C#實現(xiàn)讀取多條數(shù)據(jù)記錄并導(dǎo)出到Word
應(yīng)用需求
將數(shù)據(jù)庫數(shù)據(jù)表中的數(shù)據(jù)輸出并打印,WORD 是一個良好的載體, 在應(yīng)用項目里,許多情況下我們會使用數(shù)據(jù)記錄結(jié)合 WORD 標簽?zāi)0暹M行配合,輸出數(shù)據(jù)進行打印的功能需求。
實現(xiàn)步驟
1、設(shè)計WORD模板,在需要輸出值的地方設(shè)置 自定義關(guān)鍵字+字段名(如%%_name),其中%%_為自定義關(guān)鍵字,name為輸出字段名。
2、根據(jù)條件查詢數(shù)據(jù)表,生成 DataSet ,如果有數(shù)據(jù)則取 Tables[0]里的數(shù)據(jù)記錄。
3、拷貝 WORD 全部內(nèi)容到剪貼板做模板數(shù)據(jù)。
4、遍歷數(shù)據(jù)表記錄,粘貼剪貼板內(nèi)容, 按照自定義關(guān)鍵+列名稱,在 WORD 中按關(guān)鍵字查找,并替換成對應(yīng)的實際數(shù)據(jù),完成輸出。
舉例我們需要提取人員的基本信息生成準考證并打印如下圖:
根據(jù)以上的結(jié)果輸出,我們需要設(shè)置如下圖標簽?zāi)0澹?/p>
如圖我們準備SQL語句如:select ProjectName,Name,Sex,IdCard,EACode,Position,Time,Address from infos where ... 并生成數(shù)據(jù)表。
其中 “ key_” 則為自定義關(guān)鍵字,后綴則對應(yīng)查詢輸出字段名。
范例運行環(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》進行處理和配置。
實現(xiàn)代碼
組件庫引入
核心代碼
public string DataTableToWord(string _filename,string _repeatKey,object _dataset),該方法提供3個參數(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)建一個名為WordApp的組件對象 Word.Application WordApp = new Word.Application(); //創(chuàng)建一個名為WordDoc的文檔對象 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)閉顯示拼寫錯誤提示框 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 表示每行記錄之間插入分頁符,最后一行時不再插入分頁符,以免造成多余一空白頁 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組件對象 WordApp.Quit(ref Nothing, ref Nothing, ref Nothing); }
小結(jié)
1、核心代碼中有對字段類型的判斷:if(dt.Columns[j].DataType==typeof(System.Byte[])),如果為System.Byte[],則表示為圖片類型字段,這是我們自行的約定,對于圖片的寬高可以根據(jù)實際需要進行設(shè)定或定義參數(shù)。
2、在根據(jù)模板內(nèi)容,每輸出一條記錄后,均會插入分頁符:
object ib = Word.WdBreakType.wdPageBreak; WordApp.Selection.InsertBreak(ref ib);
以保證打印的數(shù)據(jù)區(qū)域獨立和完整性,這要根據(jù)實際應(yīng)用來決定是否輸出。
以上就是C#實現(xiàn)讀取多條數(shù)據(jù)記錄并導(dǎo)出到Word的詳細內(nèi)容,更多關(guān)于C#讀取數(shù)據(jù)并導(dǎo)出到Word的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#關(guān)于Textbox滾動顯示最后一行,不閃爍問題
這篇文章主要介紹了C#關(guān)于Textbox滾動顯示最后一行,不閃爍問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04通過C#實現(xiàn)在Excel單元格中寫入文本、或數(shù)值
在商業(yè)、學術(shù)和日常生活中,Excel 的使用極為普遍,本文將詳細介紹如何使用免費.NET庫將數(shù)據(jù)寫入到 Excel 中,包括文本、數(shù)值、數(shù)組、和DataTable數(shù)據(jù)的輸入,需要的朋友可以參考下2024-07-07