2024年2月20日发(作者:)
RTF文件格式研究报告(代开版辞)[华普软件]
摘要: 本文对RTF文件格式进行分析研究,对RTF文件结构及特性进行了阐述,并分别列举了几个实用性的例子进行详细分析,最 终通过VB程序代码实现了一个RTF书写器(不具有所见即所得特性)。本文对软件开发人员及RTF文件格式感兴趣的人员具有参考价值。本文原始出处为:/?id=11。
关键字: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!演示例子,内容如下:
{rtf1ansiansicpg936deff0deflang1033deflangfe2052
{fonttbl{f0fmodernfprq6fcharset134 'cb'ce'cc'e5;}}
{*generator Msftedit 5.41.21.2500;}viewkind4uc1pardlang2052f0fs20 Hello World!par}
该文件分析如下(红色):
1、文件基本属性:
{rtf1 RTF版 本ansi字符集ansicpg936简 体中文deff0默认字体0deflang1033美 国英语deflangfe2052中国汉语
2、字体表:
{fonttbl{f0字 体0fmodernfprq6字 体间距为6fcharset134GB2312国标码 'cb'ce'cc'e5宋
体;}}
3、 生成器信息:
{*generator Msftedit 5.41.21.2500;}
4、文档属性:
viewkind4正 常视图uc1单字节pard默 认段落属性lang2052中国汉语f0字 体0fs20字 体大小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规范中都作了详细描述, 本文只列出部分常用关键字,以供参考。
对 于字体表和颜色表的说明:
对于我们在文档中使用的 每一个字体和颜色,我们都必须在文档头的字体表和颜色表中预先定义。
字体表定义的例子如下:
{fonttbl
{f0fromanfcharset0fprq2{*panose 05020304}Times New Roman;}
{f1fswissfcharset0fprq2{*panose 020b0204}Arial;}
{f10fnilfcharset2fprq2{*panose 00000000}Wingdings;}
„ „
}
我们在使用字体时,就可以直接指定字体表的一个索引,如:“f1Happy”表示字体为Arial 的 文本Happy。如果我们想加入其他字 体,如“华文中宋”,那么只需要在字体表中加入该字体说明,并在需要时引用该字体索引值即可。方法为(华文中宋的ASCII串为“'bb'aa'ce'c4'd6'd0'cb'ce”):{f222fnilfcharset134fprq2'bb'aa'ce'c4'd6'd0'cb'ce;}, 然后通过f222来引用该字体即可。
颜色表定义的例子如下:
{colortbl;red0green0blue0;red0green0blue255;red0green255blue255;red0green255blue0;red255green0blue255;red255green0blue0;red255green255blue0;red255green255blue255;red0green0blue128;red0green128blue128;red0green128blue0;red128green0blue128;red128green0blue0;red128green128blue0;red128green128blue128;red192green192blue192; „ „}
颜色表中每个颜色值采用RGB格式书写,每个颜色用分号格开,注意第一个颜色 值c0为空,表示系统默认颜色(一般为 黑色)。依次为:0、1、2、„ „。我们在使用颜色时(如字体颜色)就可以指定某 一个颜色索引值,如“cf2Sunday” 表示字体颜色为RGB(0,0,255)蓝 色的文字Sundy。“cb6ABC”表示字体 背景色为RGB(255,0,0)的文字 “ABC”。如果我们需要加入其他颜色 值,只需要在颜色表中加入颜色定义,并通过相应的索引值来引用它即可。
字 符底纹语法如下:
控制字
chbrdr
chshdngN
chcfpatN
chcbpatN
chbghoriz
chbgvert
chbgfdiag
chbgbdiag
chbgcross
chbgdcross
chbgdkhoriz
chbgdkvert
chbgdkfdiag
chbgdkbdiag
字 符边框(每 边均有边框)。
字符阴影。参数N的值文字阴影的百分比。
N是 背景图案的颜色,指定文档颜色表的一个索引。
N是填充色,指定文档颜色表的一个索引。
指定水平线文本背景图案。
指定垂直线文本背景图案。
指定正向对角线文本背景图案()。
指定反向对角线文本背景图案()。
指定十字线文本背景图案。
指定对角十字线文本背景图案。
指定粗水平线文本背景图案。
指定粗垂直线文本背景图案。
指定粗前斜线文本背景图案()。
指定粗后斜线文本背景图案(////)。
涵义
控制字
chbgdkcross
chbgdkdcross
指定粗十字线文本背景图案。
指定粗对角十字线文本背景图案。
涵义
假 设我们希望得到背景为水平线、字体为华文中宋(字体索引为222)、颜色为红色(颜色索引为6)的文本“星期天”,则只需输入:f222cf6'bb'aa'ce'c4'd6'd0'cb'ce 即可。
字 符下划线语法如下:
控制字
ul
ulcN
uld
uldash
uldashd
uldashdd
uldb
ulhwave
ulldash
ulnone
ulth
ulthd
ulthdash
ulthdashd
涵义
连 续的下划线。ul0关 闭所有下划线。
下 划线颜色。(注意:大写N表 示一个索引数字,下同)
点下划线。
短划下划线。
点划下划线。
双点划下划线。
双下划线。
加重波浪下划线。
长划下划线。
停止所有下划线。
粗下划线。
粗点下划线。
粗短划下划线。
粗点划下划线。
控制字
ulthdashdd
ulthldash
ululdbwave
ulw
ulwave
粗双点划下划线。
粗长划下划线。
双波浪下划线。
字下加下划线。
波浪下划线。
涵义
下 划线语法与前面底纹的使用相同。
其 他文本显示高级属性:
控制字
outl
scaps
shad
strike
striked1
sub
super
边 框。 outl 0关 闭之。
小体大写字母。 scaps 0关闭之。
阴影。 shad 0关闭之。
删除线。strike0关闭之。
双删除线。striked0关闭之。
按照字体信息的下标文本和缩小点的尺寸。
按照字体信息的上标文本和缩小点的尺寸。
涵义
对 齐方式语法如下:
控制字
qc
qj
居中对齐。
两端对齐。
涵义
控制字
ql
qr
qd
qkN
qt
左对齐(默认)。
右对齐。
分散对齐。
涵义
使用Kashida规则调整行百分比(0-低、10- 中、20-高)。
.用 于泰文的分散对齐。
文 本缩进语法如下:
控制字
fiN
cufiN
首 行缩进(默认为0)。
采用字符单位的百分比的首行缩进值,用以覆盖fiN的设置,虽然它们可以设为相同 值。
liN
linN
左端缩进(默认为0)。
从 左至右段落的左端缩进值;如果在从右至左段落则表示右端缩进值(默认为0)。linN定义了段前空格数。
culiN
采 用字符单位的百分比的左端缩进值,与linN一样,它用以覆盖liN和linN的 设置,虽然它们可以设为相同值。
riN
rinN
右 缩进(默认为0)。
从左至右段落的右端缩进值;如果在从右至左段落则表示左端缩进值(默认为0)。rinN定义了段前空格数。
curiN
采用字符单位的百分比的右端缩进值,与rinN一样,它用以覆盖riN和rinN的设置,虽然它们可以设为相同 值。
adjustright
当文档网格被定义时自动调整右缩进。
涵义
文 本间距语法如下:
sbN
saN
sbautoN
段 后间隔(默认为0)。
段前间隔(默认为0)。
自动段前间隔:
0 段前间距取决于sb。
1 自动段前间距(忽略sb)。
默认为0。
自动段后间隔:
0 段后间距取决于sa。
1 自动段后间距(忽略sa)
默认为0。
saautoN
lisbN
采 用字符单位的百分比的段前间隔值,用以覆盖sbN的设置,虽然它们可以设为相同值。
lisaN
采 用字符单位的百分比的段后间隔值,用以覆盖saN的设置,虽然它们可以设为相同值。
slN
行 间距。如果没有使用该控制字或者使用sl0,则行间距将根据行间字符最高值自动取值。若N为一个正值,则该值将仅仅在该值大于行间字符最高值时才使用(否则,使用字符最高值);分N是一个负值,即使在其小于行间字符最高值时,总是使用N的绝对值。
slmultN
多倍行间距。指出当前行间 距是单倍行距的倍数。该控制字只能跟在sl后,联合作用。
0 “最小”或者是“精确”的 行距
1 多倍行距,相对于“单 倍”行距。
nosnaplinegrid
取消对齐网格线。
因为篇幅限制,更详细的文本格式分析请参阅附件里的文本示例分析原文。
五、图片的表示方式
摸清RTF中 图片的表示颇费了一番周折,下面的分析希望能够加速你的学习进程。一个RTF图片数据通常直接嵌入文件中,这些图象可以是16进制(默 认的)或2进制格式。图象属于目标引用,由pict 控制字开始。如后面的例子中将描述的,pict关键字应在*shppict引用控制关键字之后。
一个图象的例子如下:
{*shppict{pict
{*picpropshplid1025{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}}}
picscalex100picscaley100piccropl0piccropr0piccropt0piccropb0picw4516pich4516picwgoal2560pichgoal2560jpegblipbliptag-728883813
{*blipuid d48e1d9b2268ef9f2741709749fb439c}
ffd8ffe000104a46494600480000ffdb0b080606080b0c0a0a0b0a0a0c100c0c0c0c0c0c100c0e0f„ „}}
{nonshppict {pict picscalex100picscaley100piccropl0piccropr0piccropt0piccropb0picw4516pich4516picwgoal2560pichgoal2560wmetafile8bliptag-728883813blipupi72
{*blipuid d48e1d9b2268ef9f2741709749fb439c}
466b0000000c02ac00ace00„ „}}
其分析如下(红色):
{*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左 端剪切值=0piccropr0右端剪切值=0piccropt0上 端剪切值=0piccropb0下端剪切值=0
picw4516图 片的像素宽度pich4516图 片的像素高度picwgoal2560图 象期望宽度pichgoal2560图
象期望高度jpegblip图 片源为一个JPEG文件bliptag图象ID标识-728883813
{*blipuid d48e1d9b2268ef9f2741709749fb439c}
图片16进 制数据:
ffd8ffe000104a46494600480000ffdb0b080606080b0c0a0a0b0a0a0c100c0c0c0c0c0c100c0e0f}16进制图片数据结束
}
兼容性wMetaFile文 件内容(可用省略):
{nonshppict只 用于兼容,不读取
{pict图 片开始picscalex100picscaley100piccropl0piccropr0piccropt0piccropb0picw4516pich4516picwgoal2560pichgoal2560wmetafile8bliptag-728883813blipupi72
{*blipuid d48e1d9b2268ef9f2741709749fb439c}
下面是MetaFile类型的16进制数据:
466b0000000c02ac00ace00
}MetaFile类型16进制图片数据结束
}
为了简化分析,我们除去所以可以省略的内容,则一副图片可以这样表示:
{*shppict{pict piccropl0piccropr0piccropt0piccropb0picw宽 度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控制字)结束。表行也可以被绝对定位。此时,表行的每个段落必 须具有相同的定位控制字。表的属性可以从前一行继承;因此,连续的表行可以通过单一的
一个简单表格例子如下:
1,1 1,2 1,3
2,1
RTF内 容如下:
2,2 2,3
trowd irow0irowband0ts15trgaph108trleft-108trbrdrt
brdrsbrdrw10 trbrdrlbrdrsbrdrw10 trbrdrbbrdrsbrdrw10 trbrdrrbrdrsbrdrw10
trbrdrhbrdrsbrdrw10 trbrdrvbrdrsbrdrw10
trftsWidth1trftsWidthB3trautofit1trpaddl108trpaddr108trpaddfl3trpaddft3trpaddfb3trpaddfr3tblrsid2113686tbllkhdrrowstbllklastrowtbllkhdrcolstbllklastcol
clvertaltclbrdrtbrdrsbrdrw10 clbrdrlbrdrsbrdrw10 clbrdrbbrdrsbrdrw10 clbrdrr
brdrsbrdrw10 cltxlrtbclftsWidth3clwWidth2840clshdrawnil
cellx2732clvertaltclbrdrtbrdrsbrdrw10 clbrdrlbrdrsbrdrw10 clbrdrbbrdrsbrdrw10
clbrdrrbrdrsbrdrw10 cltxlrtbclftsWidth3clwWidth2841clshdrawnil
cellx5573clvertaltclbrdrt
brdrsbrdrw10 clbrdrlbrdrsbrdrw10 clbrdrbbrdrsbrdrw10 clbrdrrbrdrsbrdrw10
cltxlrtbclftsWidth3clwWidth2841clshdrawnil cellx8414pardplain qj
li0ri0nowidctlparintblaspalphaaspnumfaautoadjustrightrin0lin0yts15
fs21lang1033langfe2052kerning2lochaf0hichaf0dbchaf13cgridlangnp1033langfenp2052
{insrsid2113686 hichaf0dbchaf13lochf0 1,1cell hichaf0dbchaf13lochf0 1,2cell
hichaf0dbchaf13lochf0 1,3cell }pardplain
ql li0ri0widctlparintblaspalphaaspnumfaautoadjustrightrin0lin0
fs21lang1033langfe2052kerning2lochaf0hichaf0dbchaf13cgridlangnp1033langfenp2052
{insrsid2113686 trowd irow0irowband0ts15trgaph108trleft-108trbrdrt
brdrsbrdrw10 trbrdrlbrdrsbrdrw10 trbrdrbbrdrsbrdrw10 trbrdrrbrdrsbrdrw10
trbrdrhbrdrsbrdrw10 trbrdrvbrdrsbrdrw10
trftsWidth1trftsWidthB3trautofit1trpaddl108trpaddr108trpaddfl3trpaddft3trpaddfb3trpaddfr3tblrsid2113686tbllkhdrrowstbllklastrowtbllkhdrcolstbllklastcol
clvertaltclbrdrtbrdrsbrdrw10 clbrdrlbrdrsbrdrw10 clbrdrbbrdrsbrdrw10 clbrdrr
brdrsbrdrw10 cltxlrtbclftsWidth3clwWidth2840clshdrawnil
cellx2732clvertaltclbrdrtbrdrsbrdrw10 clbrdrlbrdrsbrdrw10 clbrdrbbrdrsbrdrw10
clbrdrrbrdrsbrdrw10 cltxlrtbclftsWidth3clwWidth2841clshdrawnil
cellx5573clvertaltclbrdrt
brdrsbrdrw10 clbrdrlbrdrsbrdrw10 clbrdrbbrdrsbrdrw10 clbrdrrbrdrsbrdrw10
cltxlrtbclftsWidth3clwWidth2841clshdrawnil cellx8414row }pardplain qj
li0ri0nowidctlparintblaspalphaaspnumfaautoadjustrightrin0lin0yts15
fs21lang1033langfe2052kerning2lochaf0hichaf0dbchaf13cgridlangnp1033langfenp2052
{insrsid2113686 hichaf0dbchaf13lochf0 2,1cell hichaf0dbchaf13lochf0 2,2cell
hichaf0dbchaf13lochf0 2,3cell }pardplain
ql li0ri0widctlparintblaspalphaaspnumfaautoadjustrightrin0lin0
fs21lang1033langfe2052kerning2lochaf0hichaf0dbchaf13cgridlangnp1033langfenp2052
{insrsid2113686 trowd irow1irowband1lastrow ts15trgaph108trleft-108trbrdrt
brdrsbrdrw10 trbrdrlbrdrsbrdrw10 trbrdrbbrdrsbrdrw10 trbrdrrbrdrsbrdrw10
trbrdrhbrdrsbrdrw10 trbrdrvbrdrsbrdrw10
trftsWidth1trftsWidthB3trautofit1trpaddl108trpaddr108trpaddfl3trpaddft3trpaddfb3trpaddfr3tblrsid2113686tbllkhdrrowstbllklastrowtbllkhdrcolstbllklastcol
clvertaltclbrdrtbrdrsbrdrw10 clbrdrlbrdrsbrdrw10 clbrdrbbrdrsbrdrw10 clbrdrr
brdrsbrdrw10 cltxlrtbclftsWidth3clwWidth2840clshdrawnil
cellx2732clvertaltclbrdrtbrdrsbrdrw10 clbrdrlbrdrsbrdrw10 clbrdrbbrdrsbrdrw10
clbrdrrbrdrsbrdrw10 cltxlrtbclftsWidth3clwWidth2841clshdrawnil
cellx5573clvertaltclbrdrt
brdrsbrdrw10 clbrdrlbrdrsbrdrw10 clbrdrbbrdrsbrdrw10 clbrdrrbrdrsbrdrw10
cltxlrtbclftsWidth3clwWidth2841clshdrawnil cellx8414row }
是不是很复杂?不过没关系,我们通过对其进行分段,并加入适当注释,你就会对RTF文件中的表结构一目了然。首先需要声明的是,RTF1.7规范中规定,表行的格式如下:(
row) | (
分析代码如下(红色):
表格行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字体0fs21尺寸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表的最左边位置
行 边框设置
trbrdrtbrdrsbrdrw10
trbrdrlbrdrsbrdrw10
trbrdrbbrdrsbrdrw10
trbrdrrbrdrsbrdrw10
单元格1边框设置
clbrdrtbrdrw15brdrs
clbrdrlbrdrw15brdrs
clbrdrbbrdrw15brdrs
clbrdrrbrdrw15brdrs
cellx2732
单元格2边 框设置
clbrdrtbrdrw15brdrs
clbrdrlbrdrw15brdrs
clbrdrbbrdrw15brdrs
clbrdrrbrdrw15brdrs
cellx5573
单 元格3边框设置
clbrdrtbrdrw15brdrs
clbrdrlbrdrw15brdrs
clbrdrbbrdrw15brdrs
clbrdrrbrdrw15brdrs
cellx8414
行2数 据
intbl 段落是表的一部分
2,1 2,1cell表 单元格1结束
2,2 2,2cell表 单元格2结束
2,3 2,3cell表 单元格3结束
f1字 体1
row表 行2结束
至此,你应该对RTF表格输出有一定认识了吧。当然在表格中插入图片、嵌入表格等的实现方法同理,嵌入的图片可以等同于一段文本来处理,但是嵌套表格的实 现可能比较复杂,因为它涉及段落文本嵌套层次等高级问题,这里不再详述,有兴趣的读者可以参考《Rich Text Format (RTF) Specification v1.7》。
七、小结:RTF文 档基本结构
通过对RTF文件的分析,我们得出一个RTF文件基本结构如下:
RTF文件
文件头
RTF版本rtf
字符集
默认字体区域设置
默认字体号deff?
字体表
文件表
颜色表
样式表
编目表
编目表{ *listtable }
编目替换表{ *listoverridetable }
段落组属性{ *pgptbl }
跟踪修订
RSID表
生成器信息
文档区
文档信息区
标题
主题
作者
经理
公司
最后修改者
文档类别
关键字
注释
文档的版本号version?
Word摘要信息中的注释
内部版本号vern?
创建时间
修订时间
最后打印时间
备份时间
总编辑时间(单位:分钟)edmins?
页数nofpages?
字数nofwords?
包含空格的总字符数nofchars?
内部ID号id?
文档格式属性
节文本
节格式属性
页眉页脚设置
段落文本
文本
项目符号与编号
段落边框
段落格式属性
定位对象与边框
制表位设置
段落底纹
隐藏与否(/v /spv)?
表格
行开始trowd
行定义
单元格
单元格定义+
单元格内容+
重复行定义
行结束row
字符文本
图片
图片开始{*shppict {pict }
图片属性
图片数据
对象
绘图对象shp
脚注footnote
注释
域
八、学以致用:基于对象的RTF文件书写器设计
基于对RTF的学习运用,我通过VB实现了一个RTF输出工具类,可以实现文本、图片、表格(可以嵌入特殊文本、图片和水平、垂直合并)。基于此工具的病历示范输出也通过了基本 测试。更进一步的研究和完善将在接下来的时间进行。
详细描述如下:
RTF文档:
可以添加文本、图片、表格,支持页眉、页脚、页码、页眉对齐方式、页脚对齐方式、页码对齐方式。
基本方法:
Dim myRTF as New Creator
With myRTF
.PageHead = "页眉" ‘页眉
.PageHeadAlign = alm1_左端对齐 ‘页 眉对齐方式
.PageFooter = "时间:" & Format(Now, "YYYY年MM月DD日 HH:nn:ss") ‘页脚
.PageNumber = True ‘是否显示页码
.PageNumberAlign = alm3_居右对齐 ‘页码对齐方式
End With
文本:
可以实现粗体、斜体、前景 色(目前为固定颜色表)、字体大小、字体样式(目前为固定样式)、字符样式(目前为固定样式)、动画、水平缩放、雕刻、浮雕、字符间距、边框、阴影、删除 线、双删除线、下标、上标、下划线(17种)、 下划线颜色、隐藏文本、WEB下隐藏、字 符边框(阴文)、字符阴影(阳文)、底纹背景色、底纹前景色、底纹样式(12种)、高亮显示、高亮颜色、对齐方式、项目符号等。
基本方法:
.AddText ‘添加文本,也可用.AddText “文本内容”,或者通过i=.AddText(“AAA”)返回索引值I,然后通过(i).Bold=True来 设置属性。
. = True ‘粗体设置
.yle = ft1_标题1 ‘字体尺寸设置
.LastText = "文本" & vbCrLf ‘文 本设置,如果需要回车,直接添加vbCrLf到 文本中适当位置
.ent = alm2_居中对齐 ‘对 齐方式
„其他设置
图片:
可以插入JPEG、GIF等图片,已经对输出速度进行了优化。可以设置图 片对齐方式、文件名、大小、缩放比例、是否单独一行等。
使用方法:
.AddPicture (me) ‘文件名
.F = True ‘独立一行
.LastPicture„.其他设置(如对图像尺寸的设置)
表格:
可以设置单元格水平对齐、 垂直对齐、上下左右边框是否存在、是否包含内部斜线(左上、左下)、边框样式(支持28种边框)、边框颜色、底纹类型、底纹背景色、底纹前景色、底纹明暗百分比、单元格宽度单位、单元格首选宽 度、单元格右边界、是否是水平合并的首单元格、是否与前一单元水平合并、是否是垂直合并的首单元格、是否与前一定义垂直合并、行数、列数、文本适应单元 格、不允许文本换行、是否嵌套、数据类型(目前支持简单文本、高级文本、图片三种类型,嵌套表格暂时不支持)。
使用方法:
le
With ble
.Alignment = ral2_居中对齐
.AddRow '插入第1行
.l '第1行, 第1列(该单元格为简单文本、默认)
.Style = cbs03_双倍厚度边框
.Color = clr02_蓝色
.Width = 75
.l '第1行,第2列(该单元格为高级文本,需要赋值)
Dim rtfTxt1 As cRTFText
Set rtfTxt1 = New cRTFText
.pe = cct1_高级文本
= True
= "第(1,2)单元格内容:高级文本"
lor = clr06_大红
ze = fs09_四号
Set .LastCell = rtfTxt1
.tart = True
.Style = cbs25_双波浪线边框
.Width = 75
.Color = clr10_深青
„其他设置
对象模型:
RTFCreator
RTFTexts
RTFText
RTFPictures
RTFPicture
RTFTables
RTFTables
RTFRows
RTFRow
RTFCells
RTFCell
RTFNodes
RTFNode
八、参考文献
1、Rich Text Format (RTF) Specification v1.5,Microsoft Technical Support, 5/97 GC0165
2、Rich Text Format (RTF) Specification v1.7,Microsoft Technical Support, 8/2001– Word
2002 RTF Specification,下载地址:/downloads/?familyid=e5b8ebc2-6ad6-49f0-8c90-e4f763e3f04f&displaylang=en
3、RTF输出接口部件目前已 经投入实用,大家如果感兴趣可以留言。


发布评论