NO.52 RTF实现动态Word 2.基本原理及程序类

 (说的有点儿乱,有时间做图之)

一个rtf文件差不多长这个样子

{\rtf1\***

 {\field***}         //这是一个Word中的域定义,它是一个1级块;

 \**\**\**          //这是一个NB_String(无花括号)

 {\*\atrfstart} //这是批注头,也是一个1级块

 {\rtlch\fcs1 \** \'b0\'fc}  //这是一个常见的文本定义,后方的16进制代码就是用Word打开能看到的文本

 \**\** \**

 {\rtlch\fcs1\***{\*\atrfend 274729727}{\***}{\***{}}} //这是批注尾,看以看到它内含{\*\atrfend274729727},这个就是个2级块

 {\*\datastore ****}

}

 

--名词解释:

 *块:Block,对一个Rtf{}进行递归解析,会发现它是一个由{/rtf1***}为根的树状结构。这样,对于Rtf中由{}限定的一段Rtf字符串,就称之为块。

        广义来讲,基于OO的思想,Rtf1级块NB_String的也把它算做块;这样整个rtf就是一个块。

 

 * 1级块:rtf这个块可以称之为0级块,相应的它的下一级子结点,称之为1级块,依此类推,也可以定义出2级块、3级块。1级块是本技术实现的重点分析对象。

 

 * NB_String(No Brace String):1级块可以分为含有{}的和不含{}的,不含{}1级块则是NB_String型的。

 

 * 域变量(MergeField):

 {\field{\*\fldinst {\rtlch\fcs1 \af0\afs30 \ltrch\fcs0 \fs30\kerning2\loch\af0\dbch\af35\insrsid4944230 \hich\af0\dbch\af35\loch\f0  MERGEFIELD "ACCOUNT_NAME" }}{\fldrslt {\rtlch\fcs1 \af0\afs30 \ltrch\fcs0 \fs30\lang1024\langfe1024\kerning2\loch\af0\dbch\af35\noproof\insrsid4944230 \loch\af0\dbch\af35\hich\f0 \'ab\loch\f0 \hich\f0 ACCOUNT_NAME\'bb}}}

 

 * 批注变量(MergeField):

{\*\atrfstart 271807552}
……中间是批注内容……
{\*\annotation{\*\atnref 271807552}{\*\atndate 1726397554}\ltrpar \pard\plain \ltrpar\s35\ql \li0\ri0\nowidctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs21\alang1025 \ltrch\fcs0 \fs21\lang1033\langfe2052\kerning2\loch\af0\hich\af0\dbch\af13\cgrid\langnp1033\langfenp2052 {\rtlch\fcs1 \af0 \ltrch\fcs0 \cs34\insrsid996054 \chatn }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid996054 \hich\af0\dbch\af13\loch\f0 ADDRESS_LIST}}



注:为什么使用MergeField、批注来做变量块?

这是是因为

1.“制作方便”:用Word打开一个Rtf,插入一个域和批注是很简单的事情;;

2.“易于检查”:肉眼检查手

3. 反观用特殊标记来做变量的,就做不到这两点:

    想像用Txt编辑器打开一个RTF?

    在茫茫RTF的天文里面定位要插入变量的地方?

    制作好了去检查插入的对不对?插入的特殊标记可能是非RTF编码,可能制作好的模板都打不开……

 

--动态Word模板制作及开发流程

1.制作模板

   * 域变量制作规则:在光标处,按 CTRL + F9 快捷键,然后输入“MERGEFIELD”+“变量名”(例:MERGEFIELDACCOUNT_NAME),输入完成后按 SHIFT + F9 或直接按 F9 即可。注意,MERGEFIELD关键字全大写

    * 字符规则:限定“数字”、“大写字母”、“下划线”,首字符限定“大写字母”

    * 批注变量制作规则:某些内容存在多行循环打印或需根据条件判断是否打印,则需要在模板中采用批注方式标识这部分内容,作为“批注变量”(以“_LIST”命名结尾),并在该文档中将其变量串中包含的变量与相关打印规则(如换行打印等)、模式进行说明

2.模板检验

    * 使用模板校验工具检查模板中的“批注变量”、“域变量”是否正确,这包括:

           变量是否可识别

           变量名称是否识别正确

           批注变量圏起的范围如预期所想

3.模板对应Dto制作

   * 主要是批注变量内的多个变量需要做成一个Dto

   * 如果批注内只有一个域变量,可以不做对应Dto,直接做一个List<String>塞入参数Properties即可

4.模板打印开发

   * 模板转换为一个实际文档,数据源是一个参数Properties

   * 1级变量直接塞入参数Properties中即可,名称需要与模板中一致

   * 变量取值优先取当前对应Dto中的,找不到则从Properties中查找

       如果一个变量在一个模板中要打印多次(无论在什么位置,哪怕在多级嵌套的批注中),在Properties中塞入一次即可

   * 批注要做成一个ListList名称要与模板中批注内容一致,List中的元素(Dto)可以任意命名

   * 剩下的就是根据实际逻辑塞值了


--类说明

RtfUtils.java

 *校验功能

 *格式化功能

 * Rtf合并

 * 模板输出

 * 页眉页脚替换

 * 水印内容替换

 

BlockUtils.java

 * 实际Rtf块(Block)的处理

 * 块类型,名称识别

 

BlockType.txt

 * 定义块类型

      MERGEFIELD,annotation,atrfstart,headerr,footerr,ltrrow,cell,nestrow,nestcell,pnsecl

 

ModifyWords.txt

 * Rtf Key Words的正则表达式,用于提取块的名称及类型

 

Rtf.properties

 *常用的Rtf格式定义

     SECTION_BREAK,CN_HEAD

 

BlockDto.java

       String id;对于批注,它的头和尾都有一个唯一编号

       String name;块名称

       String value;对于MERGEFIELD,实际值

       String type;块类型,取自BlockType.txt

       String oriStr;块原始Rtf

       BlockDto pre;它的上一个非NB_Stirng的Block

       BlockDto next;它的下一个非NB_Stirng的Block

 

AnnotationDto.java (extends BlockDto) * 批注类型变量

       BlockDto start;批注头

       BlockDto end; 批注尾

       List<BlockDto> contentList;块中内容

 

 

NO.51 RTF实现动态Word 1.概述

NO.52 RTF实现动态Word 2.基本原理及程序类

NO.53 RTF实现动态Word 3.development history

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值