C#實(shí)現(xiàn)讀取多條數(shù)據(jù)記錄并導(dǎo)出到Word
應(yīng)用需求
將數(shù)據(jù)庫數(shù)據(jù)表中的數(shù)據(jù)輸出并打印,WORD 是一個(gè)良好的載體, 在應(yīng)用項(xiàng)目里,許多情況下我們會(huì)使用數(shù)據(jù)記錄結(jié)合 WORD 標(biāo)簽?zāi)0暹M(jìn)行配合,輸出數(shù)據(jù)進(jìn)行打印的功能需求。
實(shí)現(xiàn)步驟
1、設(shè)計(jì)WORD模板,在需要輸出值的地方設(shè)置 自定義關(guān)鍵字+字段名(如%%_name),其中%%_為自定義關(guān)鍵字,name為輸出字段名。
2、根據(jù)條件查詢數(shù)據(jù)表,生成 DataSet ,如果有數(shù)據(jù)則取 Tables[0]里的數(shù)據(jù)記錄。
3、拷貝 WORD 全部?jī)?nèi)容到剪貼板做模板數(shù)據(jù)。
4、遍歷數(shù)據(jù)表記錄,粘貼剪貼板內(nèi)容, 按照自定義關(guān)鍵+列名稱,在 WORD 中按關(guān)鍵字查找,并替換成對(duì)應(yīng)的實(shí)際數(shù)據(jù),完成輸出。
舉例我們需要提取人員的基本信息生成準(zhǔn)考證并打印如下圖:
根據(jù)以上的結(jié)果輸出,我們需要設(shè)置如下圖標(biāo)簽?zāi)0澹?/p>
如圖我們準(zhǔn)備SQL語句如:select ProjectName,Name,Sex,IdCard,EACode,Position,Time,Address from infos where ... 并生成數(shù)據(jù)表。
其中 “ key_” 則為自定義關(guān)鍵字,后綴則對(duì)應(yīng)查詢輸出字段名。
范例運(yùn)行環(huán)境
操作系統(tǒng): Windows Server 2019 DataCenter
操作系統(tǒng)上安裝 Office Word 2016
數(shù)據(jù)庫:Microsoft SQL Server 2016
.net版本: .netFramework4.7.1 或以上
開發(fā)工具:VS2019 C#
配置Office DCOM
配置方法可參照我的文章《C# 讀取Word表格到DataSet》進(jìn)行處理和配置。
實(shí)現(xiàn)代碼
組件庫引入
核心代碼
public string DataTableToWord(string _filename,string _repeatKey,object _dataset),該方法提供3個(gè)參數(shù),WORD模板文件名、自定義關(guān)鍵字、System.Data.DataSet。
public void DataTableToWord(string _filename,string _repeatKey,object _dataset) { Object Nothing = System.Reflection.Missing.Value; object filename = _filename; //創(chuàng)建一個(gè)名為WordApp的組件對(duì)象 Word.Application WordApp = new Word.Application(); //創(chuàng)建一個(gè)名為WordDoc的文檔對(duì)象 WordApp.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone; Word.Document WordDoc = WordApp.Documents.Open(ref filename, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing, ref Nothing); WordDoc.SpellingChecked = false;//關(guān)閉拼寫檢查 WordDoc.ShowSpellingErrors = false;//關(guān)閉顯示拼寫錯(cuò)誤提示框 WordApp.Selection.WholeStory(); WordApp.Selection.Cut(); DataSet ds=(DataSet)_dataset; System.Data.DataTable dt=ds.Tables[0]; for(int i=0;i<dt.Rows.Count;i++) { WordApp.Selection.Paste(); for(int j=0;j<dt.Columns.Count;j++) { string _repKey=_repeatKey+dt.Columns[j].ColumnName.ToString(); string _repValue=string.Format("{0}",dt.Rows[i][j].ToString()); bool isPhoto=false; if(dt.Columns[j].DataType==typeof(System.Byte[])) { isPhoto=true; _repValue=""; } WordApp.Options.ReplaceSelection=true; Word.Find fnd = WordApp.Selection.Find; fnd.ClearFormatting(); Object findText = _repKey; Object matchCase = false; Object matchWholeWord = Type.Missing; Object matchWildcards = false; Object matchSoundsLike = false; Object matchAllWordForms = false; Object forward = true; Object wrap =Word.WdFindWrap.wdFindContinue; Object format = false; Object replaceWith =""; Object replace =Type.Missing;; Object matchKashida = Type.Missing; Object matchDiacritics = Type.Missing; Object matchAlefHamza = Type.Missing; Object matchControl = Type.Missing; while(fnd.Execute(ref findText, ref matchCase, ref matchWholeWord,ref matchWildcards, ref matchSoundsLike, ref matchAllWordForms, ref forward, ref wrap, ref format, ref replaceWith,ref replace, ref matchKashida, ref matchDiacritics,ref matchAlefHamza, ref matchControl)) { string r_f=WordApp.Selection.Font.Name.ToString(); WordApp.Selection.Range.Text=_repValue; if(isPhoto==true) { string _jpgfile=_path+System.Guid.NewGuid()+".jpg"; if (dt.Rows[i][j] == System.DBNull.Value) { continue; } byte[] filedata = (byte[])dt.Rows[i][j]; System.IO.MemoryStream ms = new MemoryStream(filedata); System.Drawing.Image img1 = System.Drawing.Image.FromStream(ms); img1.Save(@_jpgfile); ms.Close(); object m1=Type.Missing; object m2=Type.Missing; object m3=Type.Missing; Word.InlineShape pic= WordApp.Selection.InlineShapes.AddPicture(@_jpgfile,ref m1,ref m2,ref m3); int def_width=240; int def_height=320; foreach(Word.Bookmark bm in WordApp.ActiveDocument.Bookmarks) { string _findkey=_repKey+"_"; int _f1=bm.Name.IndexOf(_findkey); if(_f1==0 && bm.Name.Length>(_findkey.Length)) { string[] _paras=bm.Name.Substring(_findkey.Length,bm.Name.Length-_findkey.Length).Split('_'); if(_paras.GetLength(0)>1){ def_width=int.Parse(_paras[0]); def_height=int.Parse(_paras[1]); } } } pic.Width=def_width; pic.Height=def_height; // _repValue=string.Format("{0},{1},{2},{3},{4}",_p1,_p2,_p3,def_width,def_height); File.Delete(@_jpgfile); } } } object dummy = System.Reflection.Missing.Value; object what = Word.WdGoToItem.wdGoToLine; object which = Word.WdGoToDirection.wdGoToLast; object count = System.Reflection.Missing.Value; // WordApp.Selection.GoTo(ref oGoToItem, ref oGoToLast, ref Nothing, ref Nothing); WordApp.Selection.GoTo(ref what, ref which, ref count, ref dummy); //default 表示每行記錄之間插入分頁符,最后一行時(shí)不再插入分頁符,以免造成多余一空白頁 if(i!=dt.Rows.Count-1) { object ib = Word.WdBreakType.wdPageBreak; WordApp.Selection.InsertBreak(ref ib); } } } WordDoc.Save(); WordDoc.Close(ref Nothing, ref Nothing, ref Nothing); //關(guān)閉WordApp組件對(duì)象 WordApp.Quit(ref Nothing, ref Nothing, ref Nothing); }
小結(jié)
1、核心代碼中有對(duì)字段類型的判斷:if(dt.Columns[j].DataType==typeof(System.Byte[])),如果為System.Byte[],則表示為圖片類型字段,這是我們自行的約定,對(duì)于圖片的寬高可以根據(jù)實(shí)際需要進(jìn)行設(shè)定或定義參數(shù)。
2、在根據(jù)模板內(nèi)容,每輸出一條記錄后,均會(huì)插入分頁符:
object ib = Word.WdBreakType.wdPageBreak; WordApp.Selection.InsertBreak(ref ib);
以保證打印的數(shù)據(jù)區(qū)域獨(dú)立和完整性,這要根據(jù)實(shí)際應(yīng)用來決定是否輸出。
以上就是C#實(shí)現(xiàn)讀取多條數(shù)據(jù)記錄并導(dǎo)出到Word的詳細(xì)內(nèi)容,更多關(guān)于C#讀取數(shù)據(jù)并導(dǎo)出到Word的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#關(guān)于Textbox滾動(dòng)顯示最后一行,不閃爍問題
這篇文章主要介紹了C#關(guān)于Textbox滾動(dòng)顯示最后一行,不閃爍問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04通過C#實(shí)現(xiàn)在Excel單元格中寫入文本、或數(shù)值
在商業(yè)、學(xué)術(shù)和日常生活中,Excel 的使用極為普遍,本文將詳細(xì)介紹如何使用免費(fèi).NET庫將數(shù)據(jù)寫入到 Excel 中,包括文本、數(shù)值、數(shù)組、和DataTable數(shù)據(jù)的輸入,需要的朋友可以參考下2024-07-07