http://blog.csdn.net/hcx_2008/archive/2007/09/17/1788589.aspx
摘要 本文提出了Word模板的4种制作方法,并对每种方法的具体制作和使用进行了详细论述,最后比较了4种方法的优缺点和适用场合,并提出了Word模板格式的保护方法。
关键词 Word、模板、定位
Word 不但具有无与伦比的图文处理能力,同时也提供了Word层次结构的对象,使用户可以用VBA或者第三方软件开发工具实现文档自动化。COM技术的发展,使 得客户程序可以更方面容易的控制服务器程序。硬件速度的大幅提高,使原来制约COM执行速度慢的瓶颈也已不复存在。因此,越来越多的软件系统开始采用 Word作为报表输出工具,有的甚至将Word作为数据录入工具。
但是,无论将Word作为报表输出或者录入工具,都涉及到 Word中字符定位的问题。一般都是采用制作Word模板的方法来解决字符的定位。本文中所指的模板是一个体现用Word文档,和Word中定义的. dot后缀形式的模板是有区别的。模板的制作共有特殊字符标记法、书签定义法、表格法和域定义4种方法,下面分别论述其制作方法和内容识别技术、对其优缺 点进行比较并对共性的问题提供解决办法。以下程序示例都以Delphi语言为主,但对其他语言也同样适用。
1 特殊字符标记法
该 方法是在模板中用不常见的特殊字符来表示需要替换的部分,例如符号<#Variable>,<# >是特殊字符,Variable是变量名字,用来区分不同的替换内容。利用该方法制作好的Word模板,只能用来进行写操作,即将特殊字符和变量替 换成具体的内容。具体的替换示例如下:
FindText := \'<#cgmc>\’; //欲查询字符
MatchCase := False;
MatchWholeWord := True;
MatchWildcards := False;
MatchSoundsLike := False;
MatchAllWordForms := False;
Forward := True;
Wrap := wdFindContinue; //是否查询下一个
Format := False;
Replace := True;
MatchKashida:= false ;
MatchDiacritics:= false ;
MatchAlefHamza:= false ;
MatchControl:= false ;
ReplaceWith := \’特殊字符标记法\’ ; //替换字符
with WordDocument1.Range.Find do
begin
execute(FindText, MatchCase, MatchWholeWord, MatchWildcards, MatchSoundsLike, MatchAllWordForms, Forward, Wrap, Format, Replace, MatchKashida, MatchDiacritics, MatchAlefHamza, MatchControl, ReplaceWith);
end;
示例中定义的各变量都是OleVariant类型的变量。以上只是针对 一个特殊字符标记进行处理的例子。读者可将本例予查询字符中的“cgmc”换成变量,进行循环查询替换,也可以根据特殊字符<#>进行遍历查 询替换,且替换内容不仅可以是字符,也可以是图形,甚至可以是图文混排的内容。这可以通过剪贴板实现。
2 书签定义法
书签原本是作为浏览Word文档时,快速返回原先查看处的一种方法。本文正是利用书签的定位原理,对模板中的特定区域进行识别。利用该方法制作模板的步骤如下:
(1)打开已定义的模板文档,选中需要定义书签的区域。
(2)在插入主菜单中选择书签。
(3)输入书签名选择添加。
一个文档中可定义多个不同的书签。书签定义完成后,在文档正文中不显示,但可以利用Word的书签菜单手动查找或利用代码查找。Word书签的定位及其读写操作示例如下:
tmp1 := wdGoToBookmark;
tmp2 := \’cgmc\’;
WordApp.Selection.GoTo_(tmp1,EmptyParam,EmptyParam,tmp2); //书签定位
Memo1.Lines.Add(WordApp.Selection.Text);//读操作
tmp1 := wdGoToBookmark;
tmp2 := \’cgmc\’;
WordApp.Selection.GoTo_(tmp1,EmptyParam,EmptyParam,tmp2); //书签定位
WordApp.Selection.TypeText(\’书签示例);//写操作
示例中tmp1,tmp2都是OleVariant类型的变量,当然也可以利用BookMarks集合的Count属性对书签进行遍历。利用书签在文档中输出文本时,书签位置上的原有内容会被新内容替换。
3 表格法
利用该方法制作的整个模板本身是由一个或多个表格构成,具体读写内容以单元格索引为依据进行读取。插入表格的具体步骤如下:
(1)在表格主菜单中选择插入\表格。
(2)输入列数和行数,点击确定。
(3)根据模板样式合并或拆分单元格。
模板制作完成后,可根据需要将表格线进行隐藏。单元格内容的具体读写示例如下:
For i := 1 To WordDoc.Tables.Count do //第 i 个表
begin
for j := 1 To WordDoc.Tables.Item(i).Range.Cells.Count do //第 j 个Cell
begin
myCell := WordDoc.Tables.Item(i).Range.Cells.Item(j);
memo1.Lines.add(myCell.Range.Text); //读操作
end;
end;
For i := 1 To WordDoc.Tables.Count do //第 i 个表
begin
for j := 1 To WordDoc.Tables.Item(i).Range.Cells.Count do //第 j 个Cell
begin
myCell := WordDoc.Tables.Item(i).Range.Cells.Item(j);
myCell.Range.Text := ‘表格示例’; //读操作
end;
end;
示例中myCell是Word2000的Cell类型变量。利用表格法制作模板时,可根据需要设置一个或多个表格。无论规则的二维Word表格还是不规则的表格,单元格索引号都遵循从左至右从上到下逐渐增加的顺序,且每个表格的第一个单元格的索引号为1。
4 域定义法
该方法是利用Word中的域的定义来实现字符定位和内容识别。首先定义模板的大体框架,然后在需要定义域的地方插入域。插入域的具体步骤如下:
(1)在插入主菜单中选择域。
(2)选择 “文档自动化”类别。
(3)从域名中选择“DocVariable”。
(4)利用DocVariabel的命名语法定义文档中的域变量。
按Alt+F9可以显示或隐藏域定义代码。一个Word模板中可以定义多个域,多个域之间用变量名来区别。本例中的域定义在Word模板的主体部分(即除了页眉和页脚)。其读写示例分别如下:
For i := 1 to WordDoc.Fields.Count do
begin
If WordDoc.Fields.Item(i).type_ = wdFieldDocVariable then
WordDoc.Fields.Item(i).Result.Text := \’Word文档中域的使用\’; //给域付值
end;
For i := 1 to WordDoc.Fields.Count do
begin
If WordDoc.Fields.Item(i).type_ = wdFieldDocVariable then
Memo1.Lines.Add(WordDoc.Fields.Item(i).Result.Text) : //读取所有DocVariable类型的域值
end;
Word 文档中域的具体类型共有87种,详细定义可在Delphi中的Word_Tlb.Pas中查阅。在使用域变量时,必须对域类型进行判断。以上所举的例子中 都是通过域的遍历来实现指定位置文字的输出和读取,当然也可以通过域变量的名字进行域的识别。具体方法是利用域的Code属性,提取域定义字符串,然后在 域定义字符串中查找域变量。需要注意的是:给域赋值时,域中原有的文字不会被新值替换,只是在域中原有的文字后继续添加。
以上4种 方法,除特殊字符标记法只能用做Word文档生成之外,其余三种方法既能用作Word文档生成,也能用作利用模板制作的Word文档内容的读取。但是对于 利用Word文档作为系统手动录入界面来讲,书签法很容易被用户误删除,域定义法更是很难被用户肉眼识别,且即使识别出来,手动录入也很麻烦。在实际应用 中,表格法制作的模板文件一般来讲格式相对稳定,用户除非有意,否则很难误删除。因此表格法制作的模板同其他三种方法相比,更能胜任制作录入界面的工作。
模板文件归根结底是一种具有特殊格式的Word文档,因此很容易被人们修改格式。为了避免模板格式被破坏。可以为Word模板设置密码,具体使用时,手动或用程序输入密码,用程序输入密码的方法为WordDoc.UnProtect,然后打开模板文件进行操作。