RTF 格式 說明

摘要: 本文對RTF文件格式進行分析研究,對RTF文件結構及特性進行了闡述,並分別列舉了幾個實用性的例子進行詳細分析,
最終通過VB程序代碼實現了一個RTF書寫器(不具有所見即所得特性)。本文對軟件開發人員及RTF文件格式感興趣的人員具有參考價值。

關鍵字:RTF、Rich Text Format、Office、文件格式。

一、引言

富文本格式(RTF)規範是爲了便於在應用程序之間輕鬆轉儲格式化文本和圖形的一種編碼方法。現在,用戶可以利用特定轉換軟件,在不同系統如MS-DOS、Windows、OS/2、Macintosh和Power Macintosh的應用程序之間轉移字處理文檔。RTF規範提供一種在不同的輸出設備、操作環境和操作系統之間交換文本和圖形的一種格式。RTF使用ANSI, PC-8, Macintosh, 或IBM PC字符集控制文檔的表示法和格式化,包括屏幕顯示和打印。憑藉RTF規範,不同的操作系統和不同的軟件程序創建的文檔能夠在這些操作系統和應用程序之間傳遞。

將一個格式化的文件轉換爲RTF文件的軟件稱爲RTF書寫器。RTF書寫器用於分離現有文本中的程序控制信息,並且生成一個包含文本和與之相關的RTF組的新文件。將RTF文件轉換成格式化文件的軟件則稱爲RTF閱讀器。

二、RTF基本語法

RTF文件由未格式化本文、控制字、控制符和組組成。RTF文件沒有限制文件的行的最大長度。控制字是RTF用來標記打印控制符和管理文檔信息的一種特殊格式的命令。一個控制字最長32個字符。控制字的使用格式如下:

\字母序列<分隔符>

注意:每個控制字均以一個反斜槓\開頭。字母序列由a~z 的小寫字母組成。控制字(或者稱爲關鍵字)通常應該不包含任何大寫字母。

分隔符標記RTF控制字的結束, 可以是下列各項之一:

· 一個空格,這時空格是控制字的一部份。

· 一個數字或連字符(-), 表示跟隨的一個數值參數。該數字序列的長度由其後的一個空格或除了字母和數字的其他字符劃定。這個參數可以是正數或者負數,它的取值範圍通常是從-32767到32767。

· 任何非字母和數字的其他字符。這種情況下,此分隔字符結束控制字,而它並不屬於控制字的一部分。

控制符由一個反斜線\跟隨單個非字母字符組成。例如,\~代表一個不換行空格。控制符不需要分隔符。

組由包括在({})中的文本、控制字或控制符組成。左擴符({)表示組的開始,右擴符(})表示組的結束。每個組包括文本和文本的不同屬性。RTF文件也能同時包括字體、格式、屏幕顏色、圖形、腳註、註釋(註解)、文件頭和文件尾、摘要信息、域和書籤的組合,以及文檔、區段、段落和字符的格式屬性。如果包括字體、文件、格式、屏幕顏色、校訂標記,以及摘要信息組、文檔格式屬性,則他們一定要在文件的第一純文本字符之前,這些組形成RTF的文件頭。如果包括字體組,則它應該在格式組之前。如果組未使用,可以省略。

對於RTF文件的詳細語法及關鍵字說明請參閱《Rich Text Format (RTF) Specification v1.7》,這裏不作更詳細的說明。

三、Hello Word
國際慣例,一個Hello Word!演示例子,內容如下:
{\rtf1\ansi\ansicpg936\deff0\deflang1033\deflangfe2052
{\fonttbl{\f0\fmodern\fprq6\fcharset134 \'cb\'ce\'cc\'e5;}}
{\*\generator Msftedit 5.41.21.2500;}\viewkind4\uc1\pard\lang2052\f0\fs20 Hello World!\par}
該文件分析如下(紅色):
1、文件基本屬性:
{\rtf1 RTF版本\ansi字符集\ansicpg936簡體中文\deff0默認字體0\deflang1033美國英語\deflangfe2052中國漢語
2、字體表:
{\fonttbl{\f0字體0\fmodern\fprq6字體間距爲6\fcharset134GB2312國標碼 \'cb\'ce\'cc\'e5宋體;}}
3、生成器信息:
{\*\generator Msftedit 5.41.21.2500;}
4、文檔屬性:
\viewkind4正常視圖\uc1單字節\pard默認段落屬性\lang2052中國漢語\f0字體0\fs20字體大小20磅
5、正文文本:
Hello World!\par段落標記
}文件結束
注意:在RTF文件中,中文等雙字節字符采用其單字節ASCII碼序列表示,例如文本“宋體ABC”應該表示爲:\'cb\'ce\'cc\'e5ABC,這就是爲什麼RTF可讀性差的原因。如果需要通過程序獲取某個字符串的合法ASCII序列,可以採用如下的VB函數:
Public Function StrToASC(ByVal strIn As String) As String
'將中文字符串轉換爲ASC串(包括英文一起)
'先將特殊字符進行轉義:
strIn = Replace(strIn, Chr(9), "\TAB ")
strIn = Replace(strIn, Chr(13) + Chr(10), "\par ")
Dim i As Long, s As String, lsChar As String, lsPart1 As String, lsPart2 As String
Dim lsCharHex As String
For i = 1 To Len(strIn)
lsChar = Mid(strIn, i, 1)
If lsChar = "?" Then
lsCharHex = LCase(Hex(Asc(lsChar)))
If Len(lsCharHex) = 4 Then
lsCharHex = "\'" + Mid(lsCharHex, 1, 2) + "\'" + Mid(lsCharHex, 3, 2)
Else
lsCharHex = lsChar
End If
s = s + lsCharHex
Else
lsCharHex = LCase(Hex(Asc(lsChar)))
If Len(lsCharHex) = 4 Then
lsCharHex = "\'" + Mid(lsCharHex, 1, 2) + "\'" + Mid(lsCharHex, 3, 2)
Else
lsCharHex = lsChar
End If
s = s + lsCharHex
End If
Next
StrToASC = s
End Function
四、文字的更高級表示
掌握了基本文字表述方法後,你一定會試着進一步探索文本更高級的表示方法,如下劃線、顏色、粗體、斜體等等,而這些在V1.7規範中都作了詳細描述,本文只列出部分常用關鍵字,以供參考。
l 對於字體表和顏色表的說明:
對於我們在文檔中使用的每一個字體和顏色,我們都必須在文檔頭的字體表和顏色表中預先定義。
字體表定義的例子如下:
{\fonttbl
{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}
{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}
{\f10\fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;}
… …
}
我們在使用字體時,就可以直接指定字體表的一個索引,如:“\f1Happy”表示字體爲Arial 的文本Happy。如果我們想加入其他字體,如“華文中宋”,那麼只需要在字體表中加入該字體說明,並在需要時引用該字體索引值即可。方法爲(華文中宋的ASCII串爲“\'bb\'aa\'ce\'c4\'d6\'d0\'cb\'ce”):{f222\fnil\fcharset134\fprq2\'bb\'aa\'ce\'c4\'d6\'d0\'cb\'ce;},然後通過\f222來引用該字體即可。
顏色表定義的例子如下:
{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192; … …}
顏色表中每個顏色值採用RGB格式書寫,每個顏色用分號格開,注意第一個顏色值\c0爲空,表示系統默認顏色(一般爲黑色)。依次爲:\0、\1、\2、… …。我們在使用顏色時(如字體顏色)就可以指定某一個顏色索引值,如“\cf2Sunday”表示字體顏色爲RGB(0,0,255)藍色的文字Sundy。“\cb6ABC”表示字體背景色爲RGB(255,0,0)的文字“ABC”。如果我們需要加入其他顏色值,只需要在顏色表中加入顏色定義,並通過相應的索引值來引用它即可。
l 字符底紋語法如下:
控制字
涵義
\chbrdr
字符邊框(每邊均有邊框)。
\chshdngN
字符陰影。參數N的值文字陰影的百分比。
\chcfpatN
N是背景圖案的顏色,指定文檔顏色表的一個索引。
\chcbpatN
N是填充色,指定文檔顏色表的一個索引。
\chbghoriz
指定水平線文本背景圖案。
\chbgvert
指定垂直線文本背景圖案。
\chbgfdiag
指定正向對角線文本背景圖案(\\\\)。
\chbgbdiag
指定反向對角線文本背景圖案(\\\\)。
\chbgcross
指定十字線文本背景圖案。
\chbgdcross
指定對角十字線文本背景圖案。
\chbgdkhoriz
指定粗水平線文本背景圖案。
\chbgdkvert
指定粗垂直線文本背景圖案。
\chbgdkfdiag
指定粗前斜線文本背景圖案(\\\\)。
\chbgdkbdiag
指定粗後斜線文本背景圖案(////)。
\chbgdkcross
指定粗十字線文本背景圖案。
\chbgdkdcross
指定粗對角十字線文本背景圖案。
假設我們希望得到背景爲水平線、字體爲華文中宋(字體索引爲222)、顏色爲紅色(顏色索引爲6)的文本“星期天”,則只需輸入:\f222\cf6\'bb\'aa\'ce\'c4\'d6\'d0\'cb\'ce 即可。
l 字符下劃線語法如下:
控制字
涵義
\ul
連續的下劃線。\ul0關閉所有下劃線。
\ulcN
下劃線顏色。(注意:大寫N表示一個索引數字,下同)
\uld
點下劃線。
\uldash
短劃下劃線。
\uldashd
點劃下劃線。
\uldashdd
雙點劃下劃線。
\uldb
雙下劃線。
\ulhwave
加重波浪下劃線。
\ulldash
長劃下劃線。
\ulnone
停止所有下劃線。
\ulth
粗下劃線。
\ulthd
粗點下劃線。
\ulthdash
粗短劃下劃線。
\ulthdashd
粗點劃下劃線。
\ulthdashdd
粗雙點劃下劃線。
\ulthldash
粗長劃下劃線。
\ululdbwave
雙波浪下劃線。
\ulw
字下加下劃線。
\ulwave
波浪下劃線。
下劃線語法與前面底紋的使用相同。
l 其他文本顯示高級屬性:
控制字
涵義
\outl
邊框。\ outl 0關閉之。
\scaps
小體大寫字母。\ scaps 0關閉之。
\shad
陰影。\ shad 0關閉之。
\strike
刪除線。\strike0關閉之。
\striked1
雙刪除線。\striked0關閉之。
\sub
按照字體信息的下標文本和縮小點的尺寸。
\super
按照字體信息的上標文本和縮小點的尺寸。
l 對齊方式語法如下:
控制字
涵義
\qc
居中對齊。
\qj
兩端對齊。
\ql
左對齊(默認)。
\qr
右對齊。
\qd
分散對齊。
\qkN
使用Kashida規則調整行百分比(0-低、10-中、20-高)。
\qt
.用於泰文的分散對齊。
l 文本縮進語法如下:
控制字
涵義
\fiN
首行縮進(默認爲0)。
\cufiN
採用字符單位的百分比的首行縮進值,用以覆蓋\fiN的設置,雖然它們可以設爲相同值。
\liN
左端縮進(默認爲0)。
\linN
從左至右段落的左端縮進值;如果在從右至左段落則表示右端縮進值(默認爲0)。\linN定義了段前空格數。
\culiN
採用字符單位的百分比的左端縮進值,與\linN一樣,它用以覆蓋\liN和\linN的設置,雖然它們可以設爲相同值。
\riN
右縮進(默認爲0)。
\rinN
從左至右段落的右端縮進值;如果在從右至左段落則表示左端縮進值(默認爲0)。\rinN定義了段前空格數。
\curiN
採用字符單位的百分比的右端縮進值,與\rinN一樣,它用以覆蓋\riN和\rinN的設置,雖然它們可以設爲相同值。
\adjustright
當文檔網格被定義時自動調整右縮進。
l 文本間距語法如下:
\sbN
段後間隔(默認爲0)。
\saN
段前間隔(默認爲0)。
\sbautoN
自動段前間隔:
0 段前間距取決於\sb。
1 自動段前間距(忽略\sb)。
默認爲0。
\saautoN
自動段後間隔:
0 段後間距取決於\sa。
1 自動段後間距(忽略\sa)
默認爲0。
\lisbN
採用字符單位的百分比的段前間隔值,用以覆蓋\sbN的設置,雖然它們可以設爲相同值。
\lisaN
採用字符單位的百分比的段後間隔值,用以覆蓋\saN的設置,雖然它們可以設爲相同值。
\slN
行間距。如果沒有使用該控制字或者使用\sl0,則行間距將根據行間字符最高值自動取值。若N爲一個正值,則該值將僅僅在該值大於行間字符最高值時才使用(否則,使用字符最高值);分N是一個負值,即使在其小於行間字符最高值時,總是使用N的絕對值。
\slmultN
多倍行間距。指出當前行間距是單倍行距的倍數。該控制字只能跟在\sl後,聯合作用。
0 “最小”或者是“精確”的行距
1 多倍行距,相對於“單倍”行距。
\nosnaplinegrid
取消對齊網格線。
因爲篇幅限制,更詳細的文本格式分析請參閱附件裏的文本示例分析原文。
五、圖片的表示方式
摸清RTF中圖片的表示頗費了一番周折,下面的分析希望能夠加速你的學習進程。一個RTF圖片數據通常直接嵌入文件中,這些圖象可以是16進制(默認的)或2進制格式。圖象屬於目標引用,由\pict 控制字開始。如後面的例子中將描述的,\pict關鍵字應在\*\shppict引用控制關鍵字之後。
一個圖象的例子如下:
{\*\shppict{\pict
{\*\picprop\shplid1025{\sp{\sn shapeType}{\sv 75}}{\sp{\sn fFlipH}{\sv 0}}{\sp{\sn fFlipV}{\sv 0}}{\sp{\sn pibFlags}{\sv 2}}{\sp{\sn fLine}{\sv 0}}{\sp{\sn fLayoutInCell}{\sv 1}}}
\picscalex100\picscaley100\piccropl0\piccropr0\piccropt0\piccropb0\picw4516\pich4516\picwgoal2560\pichgoal2560\jpegblip\bliptag-728883813
{\*\blipuid d48e1d9b2268ef9f2741709749fb439c}
ffd8ffe000104a46494600010101004800480000ffdb0043000604040405040605050609060506090b080606080b0c0a0a0b0a0a0c100c0c0c0c0c0c100c0e0f… …}}
{\nonshppict {\pict \picscalex100\picscaley100\piccropl0\piccropr0\piccropt0\piccropb0\picw4516\pich4516\picwgoal2560\pichgoal2560\wmetafile8\bliptag-728883813\blipupi72
{\*\blipuid d48e1d9b2268ef9f2741709749fb439c}
0100090000034660000000002160000000000400000003010800050000000b0200000000050000000c02ac00ac00030000001e00040000000701040021600000… …}}
其分析如下(紅色):
{\*\shppict圖片(引用)
{\pict圖片開始
繪圖對象屬性(這個組可以省略):
{\*\picprop表示這裏是應用於一個內嵌圖象的形狀屬性\shplid1025標識每個圖形的唯一數值
{\sp繪圖對象屬性定義
{\sn shapeType}{\sv 75}} 圖片類型爲相框
{\sp{\sn fFlipH}{\sv 0}} 水平翻轉:False
{\sp{\sn fFlipV}{\sv 0}} 垂直翻轉:False
{\sp{\sn pibFlags}{\sv 2}} 鏈接圖片標誌
{\sp{\sn fLine}{\sv 0}}具有線條:False
{\sp{\sn fLayoutInCell}{\sv 1}}允許圖形錨點定位在單元格內部:True
}繪圖對象屬性定義結束
圖片屬性:
\picscalex100水平縮放比例\picscaley100垂直縮放比例
\piccropl0左端剪切值=0\piccropr0右端剪切值=0\piccropt0上端剪切值=0\piccropb0下端剪切值=0
\picw4516圖片的像素寬度\pich4516圖片的像素高度\picwgoal2560圖象期望寬度\pichgoal2560圖象期望高度\jpegblip圖片源爲一個JPEG文件\bliptag圖象ID標識-728883813
{\*\blipuid d48e1d9b2268ef9f2741709749fb439c}
圖片16進制數據:
ffd8ffe000104a46494600010101004800480000ffdb0043000604040405040605050609060506090b080606080b0c0a0a0b0a0a0c100c0c0c0c0c0c100c0e0f}16進製圖片數據結束
}
兼容性wMetaFile文件內容(可用省略):
{\nonshppict只用於兼容,不讀取
{\pict圖片開始\picscalex100\picscaley100\piccropl0\piccropr0\piccropt0\piccropb0\picw4516\pich4516\picwgoal2560\pichgoal2560\wmetafile8\bliptag-728883813\blipupi72
{\*\blipuid d48e1d9b2268ef9f2741709749fb439c}
下面是MetaFile類型的16進制數據:
0100090000034660000000002160000000000400000003010800050000000b0200000000050000000c02ac00ac00030000001e00040000000701040021600000
}MetaFile類型16進製圖片數據結束
}
爲了簡化分析,我們除去所以可以省略的內容,則一副圖片可以這樣表示:
{\*\shppict{\pict piccropl0\piccropr0\piccropt0\piccropb0\picw寬度\pich高度\picwgoal顯示寬度\pichgoal顯示高度\jpegblipJPEG類型\bliptag-728883813ID值(爲一個負的長整形值)
下面是該圖片的實際16進制數據:
ffd8ffe0001… …}}
如果需要通過程序獲取指定圖片合法的16進制字符串,可以採用如下的VB函數:
Public Function PicToASC(ByVal strFileName As String) As String
'獲取圖片16進制數據
Dim bData() As Byte
Dim i As Long
Dim lNum As Long
Dim strData As String, strTMP As String
lNum = FreeFile
Open strFileName For Binary As #lNum
ReDim bData(LOF(lNum) - 1)
Get #lNum, , bData
Close #lNum
strData = Space((UBound(bData) + 1) * 2)
For i = 0 To UBound(bData)
strTMP = Hex$(bData(i))
If Len(strTMP) = 1 Then
strTMP = "0" + strTMP
End If
Mid(strData, i * 2 + 1) = strTMP
Next
PicToASC = strData
End Function
六、表格基本表示方法
上面對文本和圖片都進行了分析,相信你已經對RTF文件格式有了一定體會,接下來說明RTF文件中表的表示方法。表的定義稍顯複雜,不過還是有規律可循的。不存在RTF表組,實際上表由段落屬性來描述。一個表表現爲多個錶行的順序排列。一個錶行是一個由不同單元格組成的段落序列。簡言之,表格由行組成,行由單元格組成。不管有多複雜的表格,它都是通過一行接一行的描述來實現的,包括表格的嵌套。錶行從控制字\trowd開始,\row結束。包含在一個錶行中的每個段落必須指定\intbl控制字或者從前一段落繼承。一個單元內可能有多個段落;單元由單元格標誌(\cell控制字)結束,行由行標誌(\row控制字)結束。錶行也可以被絕對定位。此時,錶行的每個段落必須具有相同的定位控制字。表的屬性可以從前一行繼承;因此,連續的錶行可以通過單一的<tbldef>來定義。
一個簡單表格例子如下:
1,1
1,2
1,3
2,1
2,2
2,3
RTF內容如下:
\trowd \irow0\irowband0\ts15\trgaph108\trleft-108\trbrdrt
\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10
\trftsWidth1\trftsWidthB3\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblrsid2113686\tbllkhdrrows\tbllklastrow\tbllkhdrcols\tbllklastcol \clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr
\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2840\clshdrawnil \cellx2732\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2841\clshdrawnil \cellx5573\clvertalt\clbrdrt
\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2841\clshdrawnil \cellx8414\pard\plain \qj \li0\ri0\nowidctlpar\intbl\aspalpha\aspnum\faauto\adjustright\rin0\lin0\yts15
\fs21\lang1033\langfe2052\kerning2\loch\af0\hich\af0\dbch\af13\cgrid\langnp1033\langfenp2052 {\insrsid2113686 \hich\af0\dbch\af13\loch\f0 1,1\cell \hich\af0\dbch\af13\loch\f0 1,2\cell \hich\af0\dbch\af13\loch\f0 1,3\cell }\pard\plain
\ql \li0\ri0\widctlpar\intbl\aspalpha\aspnum\faauto\adjustright\rin0\lin0 \fs21\lang1033\langfe2052\kerning2\loch\af0\hich\af0\dbch\af13\cgrid\langnp1033\langfenp2052 {\insrsid2113686 \trowd \irow0\irowband0\ts15\trgaph108\trleft-108\trbrdrt
\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10
\trftsWidth1\trftsWidthB3\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblrsid2113686\tbllkhdrrows\tbllklastrow\tbllkhdrcols\tbllklastcol \clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr
\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2840\clshdrawnil \cellx2732\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2841\clshdrawnil \cellx5573\clvertalt\clbrdrt
\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2841\clshdrawnil \cellx8414\row }\pard\plain \qj \li0\ri0\nowidctlpar\intbl\aspalpha\aspnum\faauto\adjustright\rin0\lin0\yts15
\fs21\lang1033\langfe2052\kerning2\loch\af0\hich\af0\dbch\af13\cgrid\langnp1033\langfenp2052 {\insrsid2113686 \hich\af0\dbch\af13\loch\f0 2,1\cell \hich\af0\dbch\af13\loch\f0 2,2\cell \hich\af0\dbch\af13\loch\f0 2,3\cell }\pard\plain
\ql \li0\ri0\widctlpar\intbl\aspalpha\aspnum\faauto\adjustright\rin0\lin0 \fs21\lang1033\langfe2052\kerning2\loch\af0\hich\af0\dbch\af13\cgrid\langnp1033\langfenp2052 {\insrsid2113686 \trowd \irow1\irowband1\lastrow \ts15\trgaph108\trleft-108\trbrdrt
\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrh\brdrs\brdrw10 \trbrdrv\brdrs\brdrw10
\trftsWidth1\trftsWidthB3\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblrsid2113686\tbllkhdrrows\tbllklastrow\tbllkhdrcols\tbllklastcol \clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr
\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2840\clshdrawnil \cellx2732\clvertalt\clbrdrt\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2841\clshdrawnil \cellx5573\clvertalt\clbrdrt
\brdrs\brdrw10 \clbrdrl\brdrs\brdrw10 \clbrdrb\brdrs\brdrw10 \clbrdrr\brdrs\brdrw10 \cltxlrtb\clftsWidth3\clwWidth2841\clshdrawnil \cellx8414\row }
是不是很複雜?不過沒關係,我們通過對其進行分段,並加入適當註釋,你就會對RTF文件中的表結構一目瞭然。首先需要聲明的是,RTF1.7規範中規定,錶行的格式如下:(<tbldef> <cell>+ <tbldef> \row) | (<tbldef> <cell>+ \row) | (<cell>+ <tbldef> \row),目前Word2003採用的方式就是第一種,即“定義+內容+重複定義”,如此一來就會有很大的數據冗餘,這就是爲什麼Word2003的一個簡單文檔都會很大的原因,不過爲了兼容性考慮,這樣處理也是必要的。其定義也由“行定義+單元格定義”組成,其中單元格定義可用重複。
分析代碼如下(紅色):
表格行1
\trowd錶行1開始
表格屬性
\trgaph108表中單元格半間距\trleft-108表的最左邊位置
行邊框設置
\trbrdrt行的上邊框\brdrs單倍厚度\brdrw10線寬
\trbrdrl行的左邊框\brdrs單倍厚度\brdrw10線寬
\trbrdrb行的下邊框\brdrs單倍厚度\brdrw10線寬
\trbrdrr行的右邊框\brdrs單倍厚度\brdrw10線寬
單元格1邊框設置
\clbrdrt單元格上邊框\brdrw15線寬\brdrs單倍厚度
\clbrdrl單元格左邊框\brdrw15線寬\brdrs單倍厚度
\clbrdrb單元格下邊框\brdrw15線寬\brdrs單倍厚度
\clbrdrr單元格右邊框\brdrw15線寬\brdrs單倍厚度
\cellx2732單元格右邊界
單元格2邊框設置
\clbrdrt單元格上邊框\brdrw15線寬\brdrs單倍厚度
\clbrdrl單元格左邊框\brdrw15線寬\brdrs單倍厚度
\clbrdrb單元格下邊框\brdrw15線寬\brdrs單倍厚度
\clbrdrr單元格右邊框\brdrw15線寬\brdrs單倍厚度
\cellx5573單元格右邊界
單元格3邊框設置
\clbrdrt單元格上邊框\brdrw15線寬\brdrs單倍厚度
\clbrdrl單元格左邊框\brdrw15線寬\brdrs單倍厚度
\clbrdrb單元格下邊框\brdrw15線寬\brdrs單倍厚度
\clbrdrr單元格右邊框\brdrw15線寬\brdrs單倍厚度
\cellx8414單元格右邊界
行1數據
\pard重置段落屬性\intbl段落是表的一部分\kerning2緊縮字符尺寸\f0字體0\fs21尺寸21
1,1 1,1 \cell表單元格1結束
1,2 1,2 \cell表單元格2結束
1,3 1,3 \cell表單元格3結束
\f1字體1
\row錶行1結束
\f0字體0
表格行2
\trowd錶行2開始
\trgaph108表中單元格半間距\trleft-108表的最左邊位置
行邊框設置
\trbrdrt\brdrs\brdrw10
\trbrdrl\brdrs\brdrw10
\trbrdrb\brdrs\brdrw10
\trbrdrr\brdrs\brdrw10
單元格1邊框設置
\clbrdrt\brdrw15\brdrs
\clbrdrl\brdrw15\brdrs
\clbrdrb\brdrw15\brdrs
\clbrdrr\brdrw15\brdrs
\cellx2732
單元格2邊框設置
\clbrdrt\brdrw15\brdrs
\clbrdrl\brdrw15\brdrs
\clbrdrb\brdrw15\brdrs
\clbrdrr\brdrw15\brdrs
\cellx5573
單元格3邊框設置
\clbrdrt\brdrw15\brdrs
\clbrdrl\brdrw15\brdrs
\clbrdrb\brdrw15\brdrs
\clbrdrr\brdrw15\brdrs
\cellx8414
行2數據
\intbl 段落是表的一部分
2,1 2,1\cell表單元格1結束
2,2 2,2\cell表單元格2結束
2,3 2,3\cell表單元格3結束
\f1字體1
\row錶行2結束
至此,你應該對RTF表格輸出有一定認識了吧。當然在表格中插入圖片、嵌入表格等的實現方法同理,嵌入的圖片可以等同於一段文本來處理,但是嵌套表格的實現可能比較複雜,因爲它涉及段落文本嵌套層次等高級問題,這裏不再詳述,有興趣的讀者可以參考《Rich Text Format (RTF) Specification v1.7》。
七、小結:RTF文檔基本結構
通過對RTF文件的分析,我們得出一個RTF文件基本結構如下:
RTF文件<File>
文件頭<header>
RTF版本\rtf
字符集<charset>
默認字體區域設置<deffont>
默認字體號\deff?
字體表<fonttbl>
文件表<filetbl>?
顏色表<colortbl>?
樣式表<stylesheet>?
編目表<listtables>?
編目表{ \*\listtable }
編目替換表{ \*\listoverridetable }
段落組屬性{ \*\pgptbl }
跟蹤修訂<revtbl>?
RSID表<rsidtable>?
生成器信息<generator>?
文檔區<document>
文檔信息區<info>?
標題<title>?
主題<subject>?
作者<author>?
經理<manager>?
公司<company>?
最後修改者<operator>?
文檔類別<category>?
關鍵字<keywords>?
註釋<comment>?
文檔的版本號\version?
Word摘要信息中的註釋<doccomm>?
內部版本號\vern?
創建時間<creatim>?
修訂時間<revtim>?
最後打印時間<printim>?
備份時間<buptim>?
總編輯時間(單位:分鐘)\edmins?
頁數\nofpages?
字數\nofwords?
包含空格的總字符數\nofchars?
內部ID號\id?
文檔格式屬性<docfmt>*
節文本<section>+
節格式屬性<secfmt>*
頁眉頁腳設置<hdrftr>?
段落文本<para>+
文本<textpar>|
項目符號與編號<pn>?
段落邊框<brdrdef>?
段落格式屬性<parfmt>*
定位對象與邊框<apoctl>*
製表位設置<tabdef>?
段落底紋<shading>?
隱藏與否(/v /spv)?
表格<row>
行開始\trowd
行定義<tbldef>
單元格<cell>+
單元格定義+
單元格內容+
重複行定義<tbldef>
行結束\row
字符文本<char>+
圖片<pict>
圖片開始{\*\shppict {\pict }
圖片屬性
圖片數據
對象<obj>
繪圖對象\shp
腳註\footnote
註釋<annot>
域<field>
八、學以致用:基於對象的RTF文件書寫器設計
基於對RTF的學習運用,我通過VB實現了一個RTF輸出工具類,可以實現文本、圖片、表格(可以嵌入特殊文本、圖片和水平、垂直合併)。基於此工具的病歷示範輸出也通過了基本測試。更進一步的研究和完善將在接下來的時間進行。
詳細描述如下:
l RTF文檔:
可以添加文本、圖片、表格,支持頁眉、頁腳、頁碼、頁眉對齊方式、頁腳對齊方式、頁碼對齊方式。
基本方法:
Dim myRTF as New RTFCreator.clsRTFCreator
With myRTF
.PageHead = "頁眉" ‘頁眉
.PageHeadAlign = alm1_左端對齊 ‘頁眉對齊方式
.PageFooter = "時間:" & Format(Now, "YYYY年MM月DD日 HH:nn:ss") ‘頁腳
.PageNumber = True ‘是否顯示頁碼
.PageNumberAlign = alm3_居右對齊 ‘頁碼對齊方式
End With
l 文本:
可以實現粗體、斜體、前景色(目前爲固定顏色表)、字體大小、字體樣式(目前爲固定樣式)、字符樣式(目前爲固定樣式)、動畫、水平縮放、雕刻、浮雕、字符間距、邊框、陰影、刪除線、雙刪除線、下標、上標、下劃線(17種)、下劃線顏色、隱藏文本、WEB下隱藏、字符邊框(陰文)、字符陰影(陽文)、底紋背景色、底紋前景色、底紋樣式(12種)、高亮顯示、高亮顏色、對齊方式、項目符號等。
基本方法:
.AddText ‘添加文本,也可用.AddText “文本內容”,或者通過i=.AddText(“AAA”)返回索引值I,然後通過myRTF.Texts(i).Bold=True來設置屬性。
.LastText.Bold = True ‘粗體設置
.LastText.FontStyle = ft1_標題1 ‘字體尺寸設置
.LastText = "文本" & vbCrLf ‘文本設置,如果需要回車,直接添加vbCrLf到文本中適當位置
.LastText.Alignment = alm2_居中對齊 ‘對齊方式
…其他設置
l 圖片:
可以插入JPEG、GIF等圖片,已經對輸出速度進行了優化。可以設置圖片對齊方式、文件名、大小、縮放比例、是否單獨一行等。
使用方法:
.AddPicture (CommonDialog2.FileName) ‘文件名
.LastPicture.AddCRLF = True ‘獨立一行
.LastPicture….其他設置(如對圖像尺寸的設置)
l 表格:
可以設置單元格水平對齊、垂直對齊、上下左右邊框是否存在、是否包含內部斜線(左上、左下)、邊框樣式(支持28種邊框)、邊框顏色、底紋類型、底紋背景色、底紋前景色、底紋明暗百分比、單元格寬度單位、單元格首選寬度、單元格右邊界、是否是水平合併的首單元格、是否與前一單元水平合併、是否是垂直合併的首單元格、是否與前一定義垂直合併、行數、列數、文本適應單元格、不允許文本換行、是否嵌套、數據類型(目前支持簡單文本、高級文本、圖片三種類型,嵌套表格暫時不支持)。
使用方法:
myRTF.Addtable
With myRTF.LastTable
.Alignment = ral2_居中對齊
.AddRow '插入第1行
.LastRow.AddCell '第1行,第1列(該單元格爲簡單文本、默認)
.LastRow.BorderStyle = cbs03_雙倍厚度邊框
.LastRow.BorderColor = clr02_藍色
.LastRow.BorderWidth = 75
.LastRow.AddCell '第1行,第2列(該單元格爲高級文本,需要賦值)
Dim rtfTxt1 As cRTFText
Set rtfTxt1 = New cRTFText
.LastCell.DataType = cct1_高級文本
rtfTxt1.Bold = True
rtfTxt1.Text = "第(1,2)單元格內容:高級文本"
rtfTxt1.ForeColor = clr06_大紅
rtfTxt1.FontSize = fs09_四號
Set .LastCell = rtfTxt1
.LastCell.MergeStart = True
.LastCell.BorderStyle = cbs25_雙波浪線邊框
.LastCell.BorderWidth = 75
.LastCell.BorderColor = clr10_深青
…其他設置
l 對象模型:
RTFCreator
RTFTexts
RTFText
RTFPictures
RTFPicture
RTFTables
RTFTables
RTFRows
RTFRow
RTFCells
RTFCell
RTFNodes
RTFNode

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章