精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● Delphi>>其他>>Word&Excel>>Re:如何操控WORD?

主题:Re:如何操控WORD?
发信人: d_fang(df)
整理人: teleme(2001-02-17 12:08:36), 站内信件
【 在 min_kuan 的大作中提到:】
:如何才能将数据库的数据及RichEdit中的数据输送到WORD中进行排版?
:......
 delphi擅长做数据库类的mis开发,但对于oa就有点力不从心了。不过随着microsoft的com技术逐渐成熟,现在普通windows应用已经可以和office 97无缝结合了,尤其是在delphi 5中提供了一组servers组件,更是简化了程序开发。 

最近接触了一个用户的案例,用delphi控制word做一个合同管理程序。办公人员先根据业务需要,写好合同的文字,但在用户名称、产品名称等变化的位置填写指定的标记字符串,然后通过delphi把数据库中的实际数据替换掉word中的文字,最后让word打印出合同。 

delphi自带了一个简单的word例题,但功能太简单。通过查找vba的说明,再对照delphi的vcl,编写了如下代码,实现了基本的公文管理功能。 

启动word时用如下代码: 
begin
try 
wordapplication.connect; 
except 
messagedlg('word may not be installed', mterror, [mbok], 0); 
abort; 
end; 
wordapplication.visible := true; 
wordapplication.caption := 'delphi automation'; 
end; 

关闭word用如下代码。如果想保存doc文件,请修改savechanges变量的内容: 
var 
savechanges, originalformat, routedocument: olevariant; 
begin 
savechanges := wddonotsavechanges; 
originalformat := unassigned; 
routedocument := unassigned; 
try 
wordapplication.quit(savechanges, originalformat, routedocument); 
wordapplication.disconnect; 
except 
on e: exception do 
begin 
showmessage(e.message); 
wordapplication.disconnect; 
end; 
end; 
end; 

让word打开一个指定的文件,需要先放置opendialog,然后调用wordapplication.documents.open: 
var 
itemindex :olevariant; 
filename, confirmconversions, readonly, addtorecentfiles, 
passworddocument, passwordtemplate, revert, 
writepassworddocument, writepasswordtemplate, format: olevariant; 
begin 
if not dlgopen.execute then 
exit; 

{open document} 
filename := dlgopen.filename; 
confirmconversions := false; 
readonly := false; 
addtorecentfiles := false; 
passworddocument := ''; 
passwordtemplate := ''; 
revert := true; 
writepassworddocument := ''; 
writepasswordtemplate := ''; 
format := wdopenformatdocument; 

wordapplication.documents.open( filename, confirmconversions, 
readonly, addtorecentfiles, passworddocument, passwordtemplate, 
revert, writepassworddocument, writepasswordtemplate, format ); 

{assign worddocument component} 
itemindex := 1; 
worddocument.connectto(wordapplication.documents.item(itemindex)); 

{turn spell checking of because it takes a long time if enabled and slows down winword} 
wordapplication.options.checkspellingasyoutype := false; 
wordapplication.options.checkgrammarasyoutype := false; 
end; 

让word替换标记字符串要使用worddocument.range.find.execute,这里用delphi替换了<#name>: 
var 
findtext, matchcase, matchwholeword, matchwildcards, matchsoundslike, 
matchallwordforms, forward, wrap, format, replacewith, replace: olevariant; 
begin 
findtext := '<#name>'; 
matchcase := false; 
matchwholeword := true; 
matchwildcards := false; 
matchsoundslike := false; 
matchallwordforms := false; 
forward := true; 
wrap := wdfindcontinue; 
format := false; 
replacewith := 'delphi'; 
replace := true; 

worddocument.range.find.execute( findtext, matchcase, matchwholeword, 
matchwildcards, matchsoundslike, matchallwordforms, forward, 
wrap, format, replacewith, replace ); 

end; 

上面这4段代码完成了公文管理的基本功能,再把它和数据库结合起来,就可以开发一个与lotus notes类似的产品了。 
//**********************************************

笔者在实际应用中发现,报表的内容一般很少变动,但其字体格式及版式是经常变动的,而且有时用户为了某种需要,不想修改数据库的真实内容而又要改变报表内容。如果用ReportSmith可以解决前者问题,但对于后者则无能为力了,且其界面是英文的,不合用户习惯。如果用3.0中的TQReport的报表部件,则两者都不能实时解决,必须修改原代码后重新编译才能使用。而使用Word及Excel则完全可以克服以上不足。具体实现如下(以Word实现为例): 

  首先用Word编辑报表格式,并排好版,把将要输出的数据项用表单域代替,并取名。这里我们暂时假设有表单域Item1及Item2(均为文本型),将这个文档存为模板文件Example.dot,然后按如下步骤进行: 

  1)运行Delphi3,在Form1里加入一个System部件集里的TDdeClientCov部件,取名为DdeExample,将其ConnectMode设为ddeManual(手动方式);将DdeService设为‘(WinWord)’;将ServiceApplication设为‘WinWord’。 

  2)编写一个自定义过程,以激活Word,如下: 
  procedure Tform1.WordActive(Cmds: TStrings); 
  var 
     WordPath: String; 
  begin 
     if(not DdeExample.OpenLink) then {判断是否巳动态链接} 
     begin 
       if(FindWindow('OpusApp', nil)=0) then 
       begin 
          WordPath := 'C:\msoffice\winword'; 
          if(WordPath='') then 
             ShowMessage('中文Word未安装或未设置路径,请安装设置Word中文 版。') 
          else begin 
             DdeExample.ServiceApplication := WordPath+'\Winword.exe'; 
             if(DdeExample.OpenLink) then {如果巳动态链接执行宏命令}              
                  DdeExample.ExecuteMacroLines(Cmds,False) 
              else  
                  ShowMessage('无法启动Word中文版!'); 
               DdeExample.ServiceApplication := 'WinWord.exe'; 
           end; 
      end 
      else begin{如果巳动态链接执行宏命令} 
         DdeExample.ExecuteMacroLines(Cmds,False); 
      end; 
    end 
    else 
      DdeExample.ExecuteMacroLines(Cmds,false); 
  end; 

  在private声明区里加入如下:  
  procedure ActiveWord(Cmds: TStrings); 

  3)在Form1中加入一个按钮Button1,在其onclick事件里写如下代码: 
  procedure TForm1.Button1Click(Sender: TObject); 
  var 
     Cmds:TStringList;{创建Cmds} 
     TempItem1,TempItem2:String; 
  begin 
     cmds:=TStringList.Create; 
     cmds.Clear; 
     TempItem1:='数据项一'; 
     TempItem2:='数据项二'; 
     with Cmds do 
     begin 
        Clear; 
        Add('[FileNew.Template ="Example.Dot″]');{打开模板文件Example.Dot} 
        Add('[AppMaximize]');{文档最大化} 
        Add('[SetFormResult"Item1″,″'+TempItem1+'″]');{将数据TempItem1传给表单域Item1} 
        Add('[SetFormResult"Item2″,″'+TempItem2+'″]);{将数据TempItem2传给表单域Item2} 
     end; 
     WordActive(DdeExample,Cmds);{调用自定义过程} 
     Cmds.Free;{释放Cmds} 
  end; 

  运行这个程序,单击Button1,大家可以发现Word被启动了,屏幕上出现了:数据项一;数据项二两个数据项。最后,大家可以任意修改本报表的格式及数据,因为这时这个报表与具体的应用程序巳没有关系了。 

  本例中用的是中文Word6或中文Word7。由于Word97的宏命令巳变为Visual Basic语句,如大家想用Word97实现,请将其宏命令改变为相应的代码。  

  这是个简单的示例,大家可以利用Word的宏录制功能,录取更多的宏(如自动生成表格、填充文字、变动字体等宏命令),并与数据库的各种表联系起来,依次加入Cmds中即可实现您所要求的更复杂的功能。 

 




----
欢迎参观方文设计室
http://funstudio.coolwww.net

[关闭][返回]