Delphi+Word解決方案參考 (轉)
+解決方案參考:namespace prefix = o ns = "urn:schemas--com::office" />
這是我做專案過程中自己做的幾個,見到大家都在問Word的問題。現在拿出來和大家共享。(希望有朋友可以進一步新增新的功能,或者做成包或者lib等,更方便大家使用。我自己是沒有時間啦,呵呵)
使用前,先根據需要建立一個空的WORD作為模板,在模板檔案中設定好各種格式和文字。另外,其中的PrnWordTable的引數是TGrh型別的,取自Ehlib2.6
其中用到的shFileCopy函式(用於複製檔案)和guiInfo函式(用於顯示訊息框)也是自己編寫的,程式碼也附後。
示範程式碼如下:
程式碼完成的功能:
1. 替換列印模板中的“#TITLE#”文字為“示範程式碼1”
2. 並且將DBGridEh1控制元件當前顯示的內容插入到文件的末尾
3. 在文件末尾插入一個空行
4. 在文件末尾插入新的一行文字
5. 將文件中的空行去掉
if PrnWordBegin('C:列印模板.DOC','C:目標檔案1.DOC') then
begin
PrnWordReplace('#TITLE#','示範程式碼1');
PrnWordTable(DBGridEh1);
PrnWordInsert('');
PrnWordInsert('這是新的一行文字');
PrnWordReplace('^p^p','^p',true);
PrnWordSave;
end;
如下:
//Word列印(宣告部分)
wDoc,p:Variant;
function PrnWordBegin(tempDoc,docName:String):boolean;
function PrnWordReplace(docText,newText:String;bSimpleReplace:boolean=false):boolean;
function PrnWordInsert(lext:String;bNewLine:boolean=true):boolean;overload;
function PrnWordInsert(var imgInsert:TImage;sBookMark:String=''):boolean;overload;
function PrnWordInsert(var chartInsert:TChart;sBookMark:String=''):boolean;overload;
function PrnWordTable(var dbG:TDBGridEh;sBookMark:String=''):boolean;
procedure PrnWordSave;
procedure PrnWordEnd;
//Word列印(實現部分)
{
功能:基於模板檔案tempDoc新建目標檔案docName並開啟檔案
}
function PrnWordBegin(tempDoc,docName:String):boolean;
begin
result:=false;
//複製模版
if tempDoc<>'' then
if not shFileCopy(tempDoc,docName) then exit;
//連線Word
try
wApp:=CreateOle('Word.Application');
except
guiInfo('請先 Microsoft Word 。');
exit;
end;
try
//開啟
if tempDoc='' then
begin
//建立新文件
wDoc:=wApp.Document.Add;
wDoc.SaveAs(docName);
end else begin
//開啟模版
wDoc:=wApp.Documents.Open(docName);
end;
except
guiInfo('開啟模版失敗,請檢查模版是否正確。');
wApp.Quit;
exit;
end;
wApp.Visible:=true;
result:=true;
end;
{
功能:使用newText替換docText內容
bSimpleReplace:true時僅做簡單的替換,false時對新文字進行換行處理
}
function PrnWordReplace(docText,newText:String;bSimpleReplace:boolean=false):boolean;
var i:Integer;
begin
if bSimpleReplace then
begin
//簡單處理,直接替換操作
try
wApp.ion.Find.ClearFormatting;
wApp.Selection.Find.Replacement.ClearFormatting;
wApp.Selection.Find.Text := docText;
wApp.Selection.Find.Replacement.Text :=newText;
wApp.Selection.Find.Forward := True;
wApp.Selection.Find.Wrap := wdFindContinue;
wApp.Selection.Find.Format := False;
wApp.Selection.Find.MatchCase := False;
wApp.Selection.Find.MatchWholeWord := true;
wApp.Selection.Find.MatchByte := True;
wApp.Selection.Find.MatchWildcards := False;
wApp.Selection.Find.MatchSoundsLike := False;
wApp.Selection.Find.MatchAllWordForms := False;
wApp.Selection.Find.Execute(Replace:=wdReplaceAll);
result:=true;
except
result:=false;
end;
exit;
end;
//自動分行
reWord.Lines.Clear;
reWord.Lines.Add(newText);
try
//定位到要替換的位置的後面
wApp.Selection.Find.ClearFormatting;
wApp.Selection.Find.Text := docText;
wApp.Selection.Find.Replacement.Text := '';
wApp.Selection.Find.Forward := True;
wApp.Selection.Find.Wrap := wdFindContinue;
wApp.Selection.Find.Format := False;
wApp.Selection.Find.MatchCase := False;
wApp.Selection.Find.MatchWholeWord := False;
wApp.Selection.Find.MatchByte := True;
wApp.Selection.Find.MatchWildcards := False;
wApp.Selection.Find.MatchSoundsLike := False;
wApp.Selection.Find.MatchAllWordForms := False;
wApp.Selection.Find.Execute;
wApp.Selection.MoveRight(wdCharacter,1);
//開始逐行插入
for i:=0 to reWord.Lines.Count-1 Do
begin
//插入當前行
wApp.Selection.InsertAfter(reWord.Lines[i]);
//除最後一行外,自動加入新行
if i wApp.Selection.InsertAfter(#13); end; //刪除替換位標 wApp.Selection.Find.ClearFormatting; wApp.Selection.Find.Replacement.ClearFormatting; wApp.Selection.Find.Text := docText; wApp.Selection.Find.Replacement.Text := ''; wApp.Selection.Find.Forward := True; wApp.Selection.Find.Wrap := wdFindContinue; wApp.Selection.Find.Format := False; wApp.Selection.Find.MatchCase := False; wApp.Selection.Find.MatchWholeWord := true; wApp.Selection.Find.MatchByte := True; wApp.Selection.Find.MatchWildcards := False; wApp.Selection.Find.MatchSoundsLike := False; wApp.Selection.Find.MatchAllWordForms := False; wApp.Selection.Find.Execute(Replace:=wdReplaceAll); result:=true; except result:=false; end; end; { 功能:列印TDBGridEh當前顯示的內容 基於TDBGridEh控制元件的格式和內容,自動在文件中的sBookMark書籤處生成Word表格 目前能夠支援單元格對齊、多行標題(兩行)、底部合計等特性 sBookMark:Word中要插入表格的書籤名稱 } function PrnWordTable(var dbG:TDBGridEh;sBookMark:String=''):boolean; var iCol,iLine,i,j,k:Integer; wTable,wRange:Variant; iRangeEnd:longint; iGridLine,iTitleLine:Integer; getTextText:String;getTextDisplay:boolean; titleList:TStringList;titleSplit,titleCol:Integer;lastTitleSplit,SubTitle:Integer;lastTitle:String; begin result:=false; try //計算表格的列數(不包括隱藏的列) iTitleLine:=1; //始終預設為1 iCol:=0; for i:=0 to dbG.Columns.Count-1 Do begin if dbG.Columns[i].Visible then begin iCol:=iCol+1; end; end; //計算表格的行數(不包括隱藏的列) if dbG.Data.DataSet.Active then iLine:=dbG.DataSource.DataSet.RecordCount else iLine:=0; iGridLine:=iLine+iTitleLine+dbG.FooterRowCount; //定位插入點 if sBookMark='' then begin //在文件末尾 iRangeEnd:=wDoc.Range.End-1; if iRangeEnd<0 then iRangeEnd:=0; wRange:=wDoc.Range(iRangeEnd,iRangeEnd); end else begin //在書籤處 wRange:=wDoc.Range.Goto(wdGoToBookmark,,,sBookMark); end; wTable:=wDoc.Tables.Add(wRange,iGridLine,iCol); wTable.Columns.AutoFit; //標題行 k:=1; for j:=1 to dbG.Columns.Count Do begin if dbG.Columns[j-1].Visible then begin if dbG.UseMultiTitle then begin titleList:=strSplit(dbG.Columns[j-1].Title.Caption,'|'); wTable.Cell(1,k).Range.InsertAfter(titleList.Strings[0]); end else wTable.Cell(1,k).Range.InsertAfter(dbG.Columns[j-1].Title.Caption); //設定單元格對齊方式 if dbG.Columns[j-1].Title.Alignment=taCenter then wTable.Cell(1,k).Range.ParagraphFormat.Alignment:=wdAlignParagraphCenter else if dbG.Columns[j-1].Title.Alignment=taRightJustify then wTable.Cell(1,k).Range.ParagraphFormat.Alignment:=wdAlignParagraphRight else if dbG.Columns[j-1].Title.Alignment=taLeftJustify then wTable.Cell(1,k).Range.ParagraphFormat.Alignment:=wdAlignParagraphJustify; k:=k+1; end; end; //填寫每一行 if iLine>0 then begin dbG.DataSource.dataset.DisableControls; dbG.DataSource.DataSet.First; for i:=1 to iLine Do begin k:=1; for j:=1 to dbG.Columns.Count Do begin if dbG.Columns[j-1].Visible then begin if dbG.Columns[j-1].FieldName<>'' then //避免由於空列而出錯 begin //如果該列有自己的格式化顯示函式,則顯示函式獲取顯示串 getTextText:=''; if Assigned(dbG.DataSource.DataSet.FieldByName(dbG.Columns[j-1].FieldName).OnGetText) then begin dbG.DataSource.DataSet.FieldByName(dbG.Columns[j-1].FieldName).OnGetText(dbG.DataSource.DataSet.FieldByName(dbG.Columns[j-1].FieldName),getTextText,getTextDisplay); wTable.Cell(i+iTitleLine,k).Range.InsertAfter(getTextText); end else begin //使用內容顯示 wTable.Cell(i+iTitleLine,k).Range.InsertAfter(dbG.DataSource.DataSet.FieldByName(dbG.Columns[j-1].FieldName).AsString); end; end; //設定單元格對齊方式 if dbG.Columns[j-1].Alignment=taCenter then wTable.Cell(i+iTitleLine,k).Range.ParagraphFormat.Alignment:=wdAlignParagraphCenter else if dbG.Columns[j-1].Alignment=taRightJustify then wTable.Cell(i+iTitleLine,k).Range.ParagraphFormat.Alignment:=wdAlignParagraphRight else if dbG.Columns[j-1].Alignment=taLeftJustify then wTable.Cell(i+iTitleLine,k).Range.ParagraphFormat.Alignment:=wdAlignParagraphJustify; k:=k+1; end; end; dbG.DataSource.DataSet.Next; end; end; //結尾行 for i:=1 to dbG.FooterRowCount Do begin k:=1; for j:=1 to dbG.Columns.Count Do begin if dbG.Columns[j-1].Visible then begin wTable.Cell(iLine+1+i,k).Range.InsertAfter(dbG.GetFooterValue(i-1,dbG.Columns[j-1])); //設定單元格對齊方式 if dbG.Columns[j-1].Footer.Alignment=taCenter then wTable.Cell(iLine+1+i,k).Range.ParagraphFormat.Alignment:=wdAlignParagraphCenter else if dbG.Columns[j-1].Footer.Alignment=taRightJustify then wTable.Cell(iLine+1+i,k).Range.ParagraphFormat.Alignment:=wdAlignParagraphRight else if dbG.Columns[j-1].Footer.Alignment=taLeftJustify then wTable.Cell(iLine+1+i,k).Range.ParagraphFormat.Alignment:=wdAlignParagraphJustify; k:=k+1; end; end; end; //處理多行標題 if dbG.UseMultiTitle then begin //先分割單元格,再逐個填入第二行 k:=1; titleCol:=1; lastTitleSplit:=1; SubTitle:=0; lastTitle:=''; for j:=1 to dbG.Columns.Count Do begin if dbG.Columns[j-1].Visible then begin titleList:=strSplit(dbG.Columns[j-1].Title.Caption,'|'); if titleList.Count>1 then begin //處理第二行以上的內容 wTable.Cell(1,k-SubTitle).Range.Cells.Split(titleList.Count,1,false); for titleSplit:=1 to titleList.Count-1 Do begin wTable.Cell(titleSplit+1,titleCol).Range.InsertAfter(titleList.Strings[titleSplit]); end; titleCol:=titleCol+1; //處理第一行合併 if (lastTitleSplit=titleList.Count) and (lastTitle=titleList.Strings[0]) then begin //內容相同時,合併單元格 wTable.Cell(1,k-SubTitle).Range.Copy; wRange:=wDoc.Range(wTable.Cell(1,k-SubTitle-1).Range.Start,wTable.Cell(1,k-SubTitle).Range.End); wRange.Cells.Merge; wRange.Paste; SubTitle:=SubTitle+1; end; end; lastTitle:=titleList.Strings[0]; lastTitleSplit:=titleList.Count; titleList.Clear;titleList.Free; k:=k+1; end; end; end; //自動調整表格 wTable.AutoFitBehavior(1);//根據內容自動調整表格wdAutoFitContent wTable.AutoFitBehavior(2);//根據視窗自動調整表格wdAutoFitWindow result:=true; except result:=false; end; try dbG.DataSource.dataset.EnableControls; except end; end; { 功能:在Word檔案中插入文字(能夠自動進行換行處理) lineText:要插入的文字 bNewLine:true時新起一行,false時在當前行插入 } function PrnWordInsert(lineText:String;bNewLine:boolean=true):boolean; var i:Integer; begin try if bNewLine then wDoc.Range.InsertAfter(#13); //自動分行 reWord.Lines.Clear; reWord.Lines.Add(lineText); //開始逐行插入 for i:=0 to reWord.Lines.Count-1 Do begin //插入當前行 wDoc.Range.InsertAfter(reWord.Lines[i]); //除最後一行外,自動加入新行 if i wDoc.Range.InsertAfter(#13); end; result:=true; except result:=false; end; end; { 功能:在Word檔案的sBookMark書籤處插入TImage控制元件包含的圖片 } function PrnWordInsert(var imgInsert:TImage;sBookMark:String=''):boolean; var wRange:Variant;iRangeEnd:Integer; begin try if sBookMark='' then begin //在文件末尾 iRangeEnd:=wDoc.Range.End-1; if iRangeEnd<0 then iRangeEnd:=0; wRange:=wDoc.Range(iRangeEnd,iRangeEnd); end else begin //在書籤處 wRange:=wDoc.Range.Goto(wdGoToBookmark,,,sBookMark); end; if imgInsert.Picture.Graphic<>nil then begin Clipboard.Assign(imgInsert.Picture); wRange.Paste; end else begin wRange.InsertAfter('照片'); end; result:=true; except result:=false; end; end; { 功能:在書籤sBookMark處插入TChart控制元件包含的圖表 } function PrnWordInsert(var chartInsert:TChart;sBookMark:String=''):boolean; var wRange:Variant;iRangeEnd:Integer; begin try if sBookMark='' then begin //在文件末尾 iRangeEnd:=wDoc.Range.End-1; if iRangeEnd<0 then iRangeEnd:=0; wRange:=wDoc.Range(iRangeEnd,iRangeEnd); end else begin //在書籤處 wRange:=wDoc.Range.Goto(wdGoToBookmark,,,sBookMark); end; chartInsert.CopyToClipboardBitmap; wRange.Paste; result:=true; except result:=false; end; end; { 功能:儲存Word檔案 } procedure PrnWordSave; begin try wDoc.Save; except end; end; { 功能:關閉Word檔案 } procedure PrnWordEnd; begin try wDoc.Save; wDoc.Close; wApp.Quit; except end; end; 附:shFileCopy原始碼 { 功能:的複製檔案 srcFile,destFile:原始檔和目標檔案 bDelDest:如果目標檔案已經存在,是否覆蓋 返回值:true成功,false失敗 } function shFileCopy(srcFile,destFile:String;bDelDest:boolean=true):boolean; begin result:=false; if not FileExists(srcFile) then begin guiInfo ('原始檔不存在,不能複製。'+#10#13+srcFile); exit; end; if srcFile=destFile then begin guiInfo ('原始檔和目標檔案相同,不能複製。'); exit; end; if FileExists(destFile) then begin if not bDelDest then begin guiInfo ('目標檔案已經存在,不能複製。'+#10#13+destFile); exit; end; FileSetAttr(destFile,FileGetAttr(destFile) and not $00000001); if not DeleteFile(PChar(destFile)) then begin guiInfo ('目標檔案已經存在,並且不能被刪除,複製失敗。'+#10#13+destFile); exit; end; end; if not CopyFileTo(srcFile,destFile) then begin guiInfo ('發生未知的錯誤,複製檔案失敗。'); exit; end; //目標檔案去掉只讀屬性 FileSetAttr(destFile,FileGetAttr(destFile) and not $00000001); result:=true; end; 附:guiInfo原始碼 { 功能:封裝了各種性質的提示框 sMsg:要提示的訊息 } procedure guiInfo(sMsg:String); begin MessageDlg(sMsg,mtInformation,[mbOK],0); end;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-962509/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 醫療行業解決方案參考行業
- SharePointFramework解決方案管理參考(二)Framework
- SharePoint Framework解決方案管理參考(一)Framework
- SharePoint Framework解決方案管理參考(二)Framework
- SQL語法參考(轉)SQL
- megalo — 網易考拉小程式解決方案
- megalo -- 網易考拉小程式解決方案
- 服務端技術方案模板參考服務端
- 查詢硬碟序列號的參考方案硬碟
- OSI參考模型詳解之玩轉傳輸層模型
- 智慧閱卷考試系統解決方案
- Git命令參考手冊(轉)Git
- 轉 《五蠹》參考譯文
- bzip2快速參考(轉)
- SCO UNIX安裝參考(轉)
- char* 轉 LPCWSTR 解決方案
- [轉]MySQL 欄位型別參考MySql型別
- [轉載] Oracle優化器參考Oracle優化
- SQL 語法參考手冊(轉)
- delphi函式參考手冊 (轉)函式
- SQL語法參考手冊(轉)SQL
- CSS 長度單位參考(轉)CSS
- “瑜珈山夜話”--- 參考資料 (轉)
- 一個考過CCNA的朋友經驗參考(轉)
- 視訊轉碼解決方案
- CA的安全解決方案(轉)
- 微軟解決方案架構 (轉)微軟架構
- b2b網站建設參考方案網站
- 廣東USB介面WiFi模組選型參考方案WiFi
- OSI參考模型和TCP/IP參考模型模型TCP
- IOC注入反轉思路-僅供參考
- marathon參考(11):ports埠設定(轉)
- to_char函式格式轉換參考函式
- SQL 語法參考手冊(SQL) (轉)SQL
- javamail參考JavaAI
- SQLAlchemy參考SQL
- 參考地址
- DOM參考手冊及事件參考手冊事件