destructor TAppWord.Destroy(); begin inherited Destroy(); end;
procedure TAppWord.WriteDoc(sts: Tstrings; fn: string); var sCnt: string; i: integer; begin if (fn = '') or (not Assigned(sts)) then exit; try dbword.OpenFile(fn); for i := 0 to sts.Count - 1 do begin if sts.Strings[i] = '' then begin sCnt := ' '; dbword.Replace(ReplaceText+IntToStr(i),sCnt); end else begin sCnt := sts.Strings[i]; dbword.Replace(ReplaceText+IntToStr(i),sCnt); end; end; dbword.Save; dbword.CloseDoc; except raise(Exception.Create('error')); end;
end;
function TAppWord.PickDoc(DocTitle: string; Conn: TADOConnection): string; var AQuery: TAdoQuery; sqlDoc: string; SD: TSaveDialog;
begin result := ''; if (Conn = nil) or (DocTitle = '') or (not conn.Connected) then exit; try AQuery := TAdoQuery.Create(nil); AQuery.Connection := Conn; if AQuery.Active then AQuery.Close; AQuery.SQL.Clear; sqlDoc := Format('select MB_DATA from tdly.MB_WDWJ where MB_NAME=''%s''', [DocTitle]); AQuery.SQL.Add(sqlDoc); AQuery.Open; if AQuery.RecordCount < > 1 then begin Alert('无法提取'+ DocTitle +'模板文件'); exit; end; SD := TSaveDialog.Create(nil); try SD.Filter := 'WORD文件(*.DOC) |*.DOC'; sd.DefaultExt := '*.doc'; sd.Options := [ofPathMustExist, ofOverwritePrompt]; if not SD.Execute then exit; result := Sd.FileName; Tblobfield(AQuery.FieldByName('MB_DATA')).SaveToFile(Result);// .SaveToStream(memstr); //模板字段 finally AQuery.Close; AQuery.Free; SD.Free; end; except end; end;
Delphi + Word = 数据库 + 公文处理
作者: 孙立 评价: 上站日期: 2001-09-04
内容说明:
来源: --------------------------------------------------------------------------------
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类似的产品了。
由于微软的Office系列的完善的功能;与Windows和IE的紧密集成以及强大的扩展能力,它实际上已经成为事实上的Windows下办公软件的标准,我们知道在VB中可以建立各种Office对象(Word、Excel)并控制这些对象编辑、打印、保存文档以及控制执行Office中的很多操作。象这样在VB中建立并控制Office对象是十分有用的,例如你可以将一个或者一批数据库自动输入到Word或者Excel中并保存,再通过Outlook将文档分发给其它同仁。
过去,这只有通过VB才能实现的,但是现在Delphi5也提供了这样强大的对象组。利用Delphi也可以利用Office资源了。
打开Delphi,滚动Compent Palette到Servers页,就可以看到很多熟悉的控件图标,这些就是Office组件的控件。Delphi 5中对应Office的组件包括了Word、Excel、Access、PowerPoint和Outlook可以说是十分的全面。不过要使用这些组件首先要保证你的系统中安装了Office 97或以上的 版本。
下面首先来说以下Office组件的基本使用方法Delphi中对于Office中不同的组件,首先要建立一个Application对象,例如要控制Word,首先要建立TWordApplication对象,然后再将诸如TWordDocument等Word对象通过ConnectTo方法连接到TWordApplication对象上。对于其它的Excel、Outlook等也是如此。
下面我通过具体的范例来说明对Delphi中Office对象的控制,即如何将文字输出到Word中进行简单的排版并保存和打印输出。
首先建立一个新的工程,在Form1中加入三个TButton对象、一个TMemo对象、一个TWordApplication对象、一个TWordDocument对象、一个TWordFont对象。下面是Form1的代码:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Word97, OleServer,Clipbrd;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
WordApplication1: TWordApplication;
WordDocument1: TWordDocument;
WordFont1: TWordFont;
Button2: TButton;
Button3: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.FormCreate(Sender: TObject);
begin
Button1.Caption := '插入到Word';
Button2.Caption := '打印';
Button3.Caption := '退出';
Button2.Enabled :=False;
Button3.Enabled :=False;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
Template,NewTemplate,ItemIndex:OleVariant;
procedure setfont;
begin
WordFont1.ConnectTo(WordDocument1.Sentences.Get_Last.Font);
WordFont1.Bold := 1;
WordFont1.Italic := 1;
WordFont1.shadow := 1;
WordFont1.Size := 12;
end;
begin
try
Template := EmptyParam;
NewTemplate := True;
ItemIndex := 1;
try
Wordapplication1.Connect;
except
MessageDlg('无法连接,也许没有安装Word', mtError, [mbOk], 0);
Abort;
end;
Wordapplication1.Visible := False;
WordApplication1.Caption := 'Delphi Word';
//建立一个新文档
Template := EmptyParam;
NewTemplate := False;
WordApplication1.Documents.Add(Template, NewTemplate);
//建立WordDocument连接
WordDocument1.ConnectTo(WordApplication1.Documents.Item(ItemIndex));
//因为Word进行拼写检查需要很多时间,所以首先关闭检查
WordApplication1.Options.CheckSpellingAsYouType := False;
WordApplication1.Options.CheckGrammarAsYouType := False;
//将Memo1的内容拷贝到Word中
SetFont;
WordDocument1.Range.InsertAfter('Memo1的文本: ' + #13+Memo1.Text + #13);
Button2.Enabled :=True;
Button3.Enabled :=True;
Button1.Enabled :=False;
except
on E: Exception do
begin
ShowMessage(E.Message);
WordApplication1.Disconnect;
end;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
WordDocument1.PrintOut;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
SaveChanges,OriginalFormat,RouteDocument,SavePath: OleVariant;
begin
SaveChanges := WdDoNotSaveChanges;
OriginalFormat := UnAssigned;
RouteDocument := UnAssigned;
try
SavePath:='c:\samp.doc';
WordDocument1.SaveAs(SavePath);
WordDocument1.Close;
WordDocument1.Disconnect;
WordApplication1.Quit(SaveChanges, OriginalFormat, RouteDocument);
WordApplication1.Disconnect;
close;
except
on E: Exception do
begin
Showmessage(E.Message);
WordApplication1.Disconnect;
end;
end;
end;
end.
运行程序,在Memo1中输入一些文字,点击“插入到Word”按钮,然后点击“打印”按钮就可以将由Memo1输入到Word中的文本打印出来。点击“退出”按钮就可以将文档保存到 c:\samp.doc 中然后关闭与Word的连接并退出。
由上面的范例可以看到,Delphi对于Office组件的编程同VB是有一些相似的,由于不知道什么原因,Delphi并没有提供Office组件的帮助文档。上面的程序我是一点点摸索出来的,但是如果你掌握了Office组件的编程技巧,加上Delphi强大的功能,一定会使你的程序如虎添翼的。
以上程序在Windows98、Windows2000,Delphi5.0,Office2000下运行通过
uses OleServer, ComObj
注意,模板需要写入数据的地方需要用$$$_1之类的标志标明。
unit unAppWord;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, udbword, ADODB, DB;
//ComObj, Word2000,
type
TAppword = class(TdbWord)
private
dbWord: TdbWord;
// Protected
public
constructor Create();
destructor Destroy(); override;
//依据Word文件名和内容向文件写内容
procedure WriteDoc(sts: Tstrings; fn: string);
//提取模板文件并生成word文件
function PickDoc(DocTitle: string; Conn: TADOConnection): string;
{ Public declarations }
end;
implementation
const
ReplaceText = '$$$_';
constructor TAppWord.Create();
begin
inherited Create();
end;
destructor TAppWord.Destroy();
begin
inherited Destroy();
end;
procedure TAppWord.WriteDoc(sts: Tstrings; fn: string);
var
sCnt: string;
i: integer;
begin
if (fn = '') or (not Assigned(sts)) then exit;
try
dbword.OpenFile(fn);
for i := 0 to sts.Count - 1 do
begin
if sts.Strings[i] = '' then
begin
sCnt := ' ';
dbword.Replace(ReplaceText+IntToStr(i),sCnt);
end
else
begin
sCnt := sts.Strings[i];
dbword.Replace(ReplaceText+IntToStr(i),sCnt);
end;
end;
dbword.Save;
dbword.CloseDoc;
except
raise(Exception.Create('error'));
end;
end;
function TAppWord.PickDoc(DocTitle: string; Conn: TADOConnection): string;
var
AQuery: TAdoQuery;
sqlDoc: string;
SD: TSaveDialog;
begin
result := '';
if (Conn = nil) or (DocTitle = '') or (not conn.Connected) then exit;
try
AQuery := TAdoQuery.Create(nil);
AQuery.Connection := Conn;
if AQuery.Active then AQuery.Close;
AQuery.SQL.Clear;
sqlDoc := Format('select MB_DATA from tdly.MB_WDWJ where MB_NAME=''%s''', [DocTitle]);
AQuery.SQL.Add(sqlDoc);
AQuery.Open;
if AQuery.RecordCount < > 1 then
begin
Alert('无法提取'+ DocTitle +'模板文件');
exit;
end;
SD := TSaveDialog.Create(nil);
try
SD.Filter := 'WORD文件(*.DOC) |*.DOC';
sd.DefaultExt := '*.doc';
sd.Options := [ofPathMustExist, ofOverwritePrompt];
if not SD.Execute then exit;
result := Sd.FileName;
Tblobfield(AQuery.FieldByName('MB_DATA')).SaveToFile(Result);// .SaveToStream(memstr); //模板字段
finally
AQuery.Close;
AQuery.Free;
SD.Free;
end;
except
end;
end;
end.
procedure TFrmMain.BitBtn12Click(Sender: TObject);
var
//ItemIndex:OleVariant;
FileName,ConfirmConversions,ReadOnly,AddToRecentFiles,
PasswordDocument,PasswordTemplate, Revert,
WritePasswordDocument,WritePasswordTemplate,Format:OleVariant;
begin
WordApplication1.Connect;
FileName:='c:\ZhiD.doc';
ConfirmConversions:=False;
ReadOnly:=False;
AddToRecentFiles:=False;
PasswordDocument:='';
PasswordTemplate:='';
Revert:=True;
WritePasswordDocument:='';
WritePasswordTemplate:='';
Format:=wdOpenFormatDocument;
WordApplication1.Documents.Open(FileName,ConfirmConversions,ReadOnly,AddToRecentFiles,PasswordDocument,PasswordTemplate,Revert,WritePasswordDocument,WritePasswordTemplate,Format,EmptyParam,EmptyParam,EmptyParam,EmptyParam,EmptyParam);
WordApplication1.Visible:=true;