| 加入收藏| 设为首页| 联系我们

首页 站长学习 站长之家 源码下载 建站素材 书籍教程 常用工具
 您现在的位置: 动力中国 >> 网络编程 >> C#教程 >> 文章正文  
 在C#环境下操作RTF文档
 

在C#环境下操作RTF文档

http://www.domcn.org  文章来源:互联网  点击数:

  关键字:在C#环境下操作RTF文档

        笔者正在用C#开发一个名为XWriter的文本编辑器(点击下载),其中需要提供对RTF文档的支持,以前从没有搞过RTF文档,因此临时突击研究了一下,经过几天的学习研究和实践,对C#操作RTF文档有所了解,因此才可以写出此文给予说明,希望能对其他人学习RTF文档格式有所帮助。

RTF文档格式是微软提出的一种用于描述带格式文本的文档格式,上个世纪就提出来了,一直用到现在,而且很多程序都支持这种格式,微软的Office软件家族,Windows写字板软件等等都支持,而且Windows操作系统的剪切板和OLE拖拽操作也支持RTF文档,这样就允许不同的软件通过RTF格式相互交流带格式文本。比如我用的VS.NET2003中的C#代码编辑器,在其中复制了一段代码文本,在MS Word中粘贴所得就是具有高亮度显示的文本。因此RTF格式的作用还是不小的,而且RTF格式是纯文本格式,不是二进制格式,读写都不算难。

RTF文档格式和HTML,XML之类的标记语言有点类似,原理不复杂,但内容还是比较多的,在微软的MSND中就有文章详细的介绍了RTF格式,地址是 ms-help://MS.MSDNQTR.2003FEB.2052/dnrtfspec/html/rtfspec.htm ,你用记事本打开一个RTF文档,可以发现其中也是纯文本数据,而且一般全是ANSI字符,RTF文档一般采用ASNI字符编码格式进行存储,其中是不能直接保存汉字等编码大于127的字符,要保存得使用转义字符。RTF文档中使用一对花括号{ }来定义一个组,组可以套嵌定义;用\来开始定义一个指令和转义字符;此外还能包含纯文本数据。所有的指令和转义字符都必须包含在一个组中,一个RTF文档只有一个根组,这点有点类似XML文档只能有一个根节点的规定。

我们使用Windows写字板新建一个RTF文档,只输入Hellow文本,设置文本颜色为蓝色,然后保存,然后使用记事本打开刚刚保存的RTF文件,此时就能看到一个最简单的RTF文档的内容了,其内容如下。

{

    \rtf1\ansi\ansicpg936\deff0\deflang1033\deflangfe2052

    {\fonttbl

        {\f0\fmodern\fprq6\fcharset134 \cb\ce\cc\e5;}

    }

    {\colortbl ;\red0\green0\blue255;}

    {\*\generator Msftedit 5.41.15.1507;}

    \viewkind4\uc1\pard\cf1\lang2052\f0\fs20 Hellow\cf0\par

}

此处为了便于阅读,对代码进行了缩进处理,实际上RTF文档中空白字符是会影响到显示结果的,一般实际生成RTF文档时不要添加额外的空白字符。

这段RTF代码第一行和最后一行是表示根组的花括号,然后是\开头的指令,指令名称全部由英文字母组成,若指令后面跟着若干个数字,则这些数字就是指令的参数。比如\rtf1,这个指令名称是rtf,参数值是1;而\ansi指令名称是ansi,没有参数。

指令\rtf是每个RTF文档必备的,而且总是第一个指令,因此可以看作RTF文档的文件头标记。若一个RTF文档第一个指令不是rtf指令,则可以认为这个RTF文档是不合法的。

指令\ansicpg就是说明该RTF文档的内容的编码格式,参数就是编码格式编号,例如\ansicpg936就是指明编码格式为936号字符集,对于C#程序来说,就是库函数 System.Text.Encoding.GetEncoding( 936 ) 的返回结果,也就是GB2312编码格式。RTF文档本身肯定是使用标准的ANSI格式保存的,此处指明的字符编码格式是用于处理RTF文档中的转义字符的,比如代码中由连续的转义字符 \cb\ce\cc\e5 ,程序解析RTF文档时,应当将这一串转义字符生成一个字节数组,内容为 0xcb,0xce,0xcc,0xe5,然后使用第936号编码格式对象的GetString( byte[] )函数来还原所存储的字符串,也就是宋体两个字。这点比HTML的转义字符处理要麻烦一些,HTML转义字符是一个指令定义一个字符,而RTF中的是一个指令定义一个字节,而汉字是双字节的字符编码,转化前还得设法获得完整的字节序列。

指令\fonttbl定义了文档中使用的所有的字体的列表,RTF文本内容引用这个字体列表来获得显示文档使用的字体,这和HTML文档中统一定义CSS样式有点类似。fonttbl组中由若干个子组,每个子组定义一个字体,字体定义组的第一个指令为\f,带有一个参数指明字体的编号,比如\f0指明这个字体编号为0,\f1指明字体编号为1。字体定义组还定义了关于字体的其他信息,其中最重要的就是最后的字体名称了。此演示文档中,字体的名称就是\cb\ce\cc\e5;,经过编码后就是宋体;,小心后面还有个分号。注意字体编号可能是不连续的,比如可以存在这样的字体表代码{\f0 ...}{\f1 ...}{\f99 ...}{\f212 ...},因此解析RTF字体表时要考虑这点。

指令\colortbl定义了文档颜色表,RTF文档是统一引用颜色值的,文档内容的文本颜色,背景色等颜色设置都是引用颜色表的,RTF颜色表中只定义了各个颜色的RGB值,没有明确的定义编号,引用时是按照从左到右的顺序引用颜色的,而且颜色值的编号是从“1”开始计算的。此处定义了一个颜色值\red0\green0\blue255,也就是纯蓝色。

指令\*\generator是定义了文档的创建者,此处定义指令的方式比较特殊,采用了 \*\前缀,个人理解是定义了一种扩展指令,其他的RTF文档处理程序遇到这样的指令可以忽略不计。

后面的指令就是开始描述RTF文档的正文了,比如\pard开始清除当前段落设置,当前段落设置为默认格式;\f0表示设置当前字体为字体表中编号为0的字体;\fs20设置字体大小,此处的字体大小为20,单位是半个点(MSND是这样说的:Font size in half-points (the default is 24));\cf1表示当前文本颜色采用第一号颜色,即纯蓝色(RTF颜色表序号从1开始计算);还有纯文本数据 Hellow就是RTF文档的纯文本内容了。

对于英文内容,大部分是可以直接输出到RTF文档中,但对于某些特殊字符需要进行字符转义,比如\,{,}等等,前面得加上转义前缀\,因此实际上输出的是\\,\{,\},这类似C语言的转义字符处理。对于制表符,得输出\tab,对于编码大于256的字符,例如汉字,得使用文本内容编码器来编码生成二进制数据,然后使用转义前缀\来转义输出一个个字节编码。比如“宋体”,它的GB2312编码生成字节序列 0xcb,0xce,0xcc,0xe5,它输出到RTF文档的结果就是“\cb\ce\cc\e5”。

RTF文档中可以嵌入图片,可以使用代码{\pict ... },图片组中包含了图片的二进制数据的16进制编码字符串,MSDN中关于RTF图片格式的说明不多,我对一些图片数据的格式也不清楚,因此如何处理RTF图片也没多少可说的。

关于各种指令的详细说明可参考MSDN中的相关文章,文章地址ms-help://MS.MSDNQTR.2003FEB.2052/dnrtfspec/html/rtfspec_16.htm#rtfspec_21。

我们对RTF文档格式有所了解后,就可以开始编程来操作RTF文档了,无非就是按照RTF格式来拼凑字符串而已。比如我的文本编辑器有个功能,能将编辑的内容保存为RTF格式,这时候就需要根据我的文档内容来生成RTF文档。

首先是做一个RTF文档书写器,虽然生成RTF文档的操作可以看作拼凑RTF字符串,但在编程实践中不能真的这么拼凑,得仿造System.Xml.XmlWriter来做一个RTF文档书写器,我编了个名为RTFWriter的RTF文档书写器,该书写器内部实现了基础的RTF文档格式的控制,能保证输出正确的RTF文档,它还提供了比较方便的编程接口,便于其他程序模块调用。这个RTF文档书写器完整的C#代码如下

/// <summary>
/// RTF文档书写器
/// </summary>
/// <remarks>
/// 本书写器对生成RTF文档提供了基础的支持
/// 编制 袁永福 http://www.xdesigner.cn
/// </remarks>
public class RTFWriter : System.IDisposable
{

    #region 测试代码 ******************************************************

    [System.STAThread]
    static void Main()
    {
        TestWriteFile();
        TestClipboard();
    }

    /// <summary>
    /// 测试生成RTF文件
    /// 执行这个函数后可以使用 MS Word 打开文件 c:\a.rtf 
    /// </summary>
    internal static void TestWriteFile( )
    {
        RTFWriter w = new RTFWriter( c:\\a.rtf ) ;
        TestBuildRTF( w );
        w.Close();
        System.Windows.Forms.MessageBox.Show(好了,你可以打开文件 c:\\a.rtf 了.);
    }

    /// <summary>
    /// 测试生成RTF文档并设置到系统剪切板中
    /// 执行这个函数后就可以在 MS Word中使用粘贴操作来显示程序生成的文档了
    /// </summary>
    internal static void TestClipboard()
    {
        System.IO.StringWriter myStr = new System.IO.StringWriter();
        RTFWriter w = new RTFWriter( myStr );
        TestBuildRTF( w );
        w.Close();
        System.Windows.Forms.DataObject data = new System.Windows.Forms.DataObject();
        data.SetData( System.Windows.Forms.DataFormats.Rtf , myStr.ToString());
        System.Windows.Forms.Clipboard.SetDataObject( data , true );
        System.Windows.Forms.MessageBox.Show(好了,你可以在MS Word 中粘贴文本了.);
    }

    /// <summary>
    /// 测试生成RTF文档
    /// </summary>
    /// <param name=w>RTF文档书写器</param>
    private static void TestBuildRTF( RTFWriter w )
    {
        w.Encoding = System.Text.Encoding.GetEncoding( 936 );
        // 输出文件头
        w.WriteStartGroup();
        w.WriteKeyword(rtf1);
        w.WriteKeyword(ansi);
        w.WriteKeyword(ansicpg + w.Encoding.CodePage );
        // 输出字体表
        w.WriteStartGroup();
        w.WriteKeyword(fonttbl);
        w.WriteStartGroup();
        w.WriteKeyword(f0);
        w.WriteText(隶书;);
        w.WriteEndGroup();
        w.WriteStartGroup();
        w.WriteKeyword(f1);
        w.WriteText(宋体;);
        w.WriteEndGroup();
        w.WriteEndGroup();
        // 输出颜色表
        w.WriteStartGroup();
        w.WriteKeyword(colortbl);
        w.WriteText(;);
        w.WriteKeyword(red0);
        w.WriteKeyword(green0);
        w.WriteKeyword(blue255);
        w.WriteText(;);
        w.WriteEndGroup();
        // 输出正文
        w.WriteKeyword(qc);    // 设置居中对齐
        w.WriteKeyword(f0);    // 设置字体
        w.WriteKeyword(fs30);    // 字体大小
        w.WriteText(这是第一段

[1] [2] [3] [4] 下一页


在C#环境下操作RTF文档
  • 上一篇文章:

  • 下一篇文章:
  •  热门文章
    普通文章 电子邮件改头换面 四公司畅谈未
    普通文章 PC病毒史上最声名狼藉的八大病
    普通文章 Rails系统中的AJAX开发技术简析
    普通文章 基于ASP.NET AJAX框架实现表单
    普通文章 开发ASP.NET AJAX客户端定制行
    普通文章 用JFreeChart对JSP报表进行增强
    普通文章 SQL Server 2005上的CLR和ADO.
    普通文章 SQL Server 2005的XML支持机制
    普通文章 Firefox中标签式浏览技巧大全
    普通文章 Tomcat中的Session和Cookie大揭
     
     推荐文章
    推荐文章 把Google地图嵌入网页 就是这么
    推荐文章 迅雷搜索候选资源出错的解决
    推荐文章 轻松去除迅雷里的各种广告和资
    推荐文章 突破限制 免费领养到QQ空间五级
    推荐文章 Rational统一过程RUP贴近中小软
    推荐文章 构建自己的轻量级XML DOM分析程
    推荐文章 WPS Office 2007技巧:妙用配置
    推荐文章 Excel 2007:求余数函数实用进阶
    推荐文章 浅谈ASP.NET的Postback
    推荐文章 软件开发中项目需求管理简述
     
     相关文章
    没有相关文章
    设为首页 | 加入收藏 | 广告合作 | 联系站长 | 版权申明 |
    动力中国为网友提供免费学习资料,可用资源,如果您认为我们的相关内容侵害到了您的权利请联系管理员
    Copyright © 2006-2008 domcn.org All Rights Reserved.