C#讀取多條數(shù)據(jù)記錄導出到Word之圖片輸出改造
應用需求
在我的文章《C# 讀取多條數(shù)據(jù)記錄導出到 Word 標簽模板》里,講述讀取多條數(shù)據(jù)記錄結(jié)合 WORD 標簽模板輸出文件的功能,原有輸出圖片的約定是在 WORD 模板文件中借助書簽設置進行輸出,如下圖:
該書簽名稱代表了一條指令,格式為(輸出關鍵字_圖片寬度_圖片高度)。如圖中書簽名稱設置,當系統(tǒng)遇到 ds_qz 關鍵字時,輸出按后繼設置進行,圖片寬度為100、圖片高度為 50。
現(xiàn)有一模板需求如下圖:
我們需要在考官評語和考官本人簽字位置輸出手寫圖片,原有的書簽模式輸出會遇到一些問題:
(1)只能為嵌入式,位置輸出無法設置,無法進一步調(diào)整到較優(yōu)呈現(xiàn)位置。
(2)只能插入式輸出,無法實現(xiàn)嵌入式如文字浮動、環(huán)繞效果。
(3)需要在無關位置插入書簽,否則會在輸出關鍵字時被替換掉,而無法識別配置。
(4)書簽的名稱不能輸入一些特定字符,如%,減號等,給配置帶來一些麻煩。
(5)如果在文檔里真需要設置書簽,容易造成混亂。
設計
設計提供一個 ArrayList 類型參數(shù)取代書簽模式的設計,其格式為 (輸出關鍵字_圖片寬度_圖片高度_圖片 Left 相對值_圖片 Top 相對值 )。如添加 ds_qz_100_50_500_-20 字符串,當系統(tǒng)遇到 ds_qz 關鍵字時,輸出按后繼設置進行,圖片寬度為100、圖片高度為 50、圖片 Left 為500、圖片 Top 為 -20。后四個參數(shù)如果設置null則表示忽略,ds_qz_null_null_500_-20 ,則表示忽略寬度和高度設置,即表示原始大小輸出。
定位到的圖片輸出,采取浮動于文字下方的處理。
范例運行環(huán)境
操作系統(tǒng): Windows Server 2019 DataCenter
操作系統(tǒng)上安裝 Office Word 2016
數(shù)據(jù)庫:Microsoft SQL Server 2016
.net版本: .netFramework4.7.2 或以上
開發(fā)工具:VS2019 C#
配置Office DCOM
配置方法可參照我的文章《C# 讀取Word表格到DataSet》進行處理和配置。
實現(xiàn)代碼
組件庫引入
核心代碼
public string DataTableToWord(string _filename,string _repeatKey,object _dataset,ArrayList DataSetPictureConfig),該方法提供4個參數(shù),WORD模板文件名、自定義關鍵字、System.Data.DataSet,配置圖片用的 ArrayList 列表指令。
public void DataTableToWord(string _filename,string _repeatKey,object _dataset,ArrayList DataSetPictureConfig) { if (DataSetPictureConfig == null) { DataSetPictureConfig = new ArrayList(); } 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;//關閉拼寫檢查 WordDoc.ShowSpellingErrors = false;//關閉顯示拼寫錯誤提示框 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(); Word.InlineShape pic= WordApp.Selection.InlineShapes.AddPicture(@_jpgfile,false,true); foreach (string bm in DataSetPictureConfig) { string _findkey=_repKey+"_"; int _f1 =bm.IndexOf(_findkey); if(_f1==0 && bm.Length>(_findkey.Length)) { string[] _paras=bm.Substring(_findkey.Length,bm.Length-_findkey.Length).Split('_'); if(_paras.GetLength(0)>1){ if (_paras[0] != "null") { int def_width = int.Parse(_paras[0]); pic.Width = def_width; } if (_paras[1] != "null") { int def_height = int.Parse(_paras[1]); pic.Height = def_height; } } } } Word.Shape pic2 = pic.ConvertToShape(); pic2.WrapFormat.Type = Word.WdWrapType.wdWrapThrough; pic2.WrapFormat.Type = Word.WdWrapType.wdWrapBehind; pic2.Left = 0; pic2.Top = 0; foreach (string bm in DataSetPictureConfig) { string _findkey = _repKey + "_"; int _f1 = bm.IndexOf(_findkey); if (_f1 == 0 && bm.Length > (_findkey.Length)) { string[] _paras = bm.Substring(_findkey.Length, bm.Length - _findkey.Length).Split('_'); if (_paras.GetLength(0) > 3) { if (_paras[2] != "null") pic2.Left = float.Parse(_paras[2]); if (_paras[3] != "null") pic2.Top =float.Parse(_paras[3]); } } } 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); //關閉WordApp組件對象 WordApp.Quit(ref Nothing, ref Nothing, ref Nothing); }
調(diào)用示例
示例代碼如下:
DataSet rv = GetDataSet("select * from tabble"); ArrayList picconfig = new ArrayList(); //可配置每個圖片字段的大小及位置 picconfig.Add("ds_kg_sign_100_50_500_-20"); //格式為: key_width_height_left_top string ModuleFile = "d:\\bfile\\word\\面試評分表.docx"; //假設的模板文件 string _lastfile = DataTableToWord(ModuleFile,"ds_",ds,picconfig); MessageBox.Show(string.Format("已成功導出文件:{0}", _lastfile));
小結(jié)
核心代碼中需要將 Word.InlineShape 轉(zhuǎn)換為 Word.Shape 后,可以進行環(huán)繞文字的操作,如下:
Word.Shape pic2 = pic.ConvertToShape(); pic2.WrapFormat.Type = Word.WdWrapType.wdWrapThrough; pic2.WrapFormat.Type = Word.WdWrapType.wdWrapBehind; pic2.Left = 0; pic2.Top = 0;
使用 ConvertToShape() 方法轉(zhuǎn)換為 pic2 , pic2.WrapFormat.Type = Word.WdWrapType.wdWrapBehind; 可以浮動于文字下方,然后初始圖片的 Left 和 Top ,否則有可能無法正常顯示位置。
我們可以根據(jù)自己的實際情況設置環(huán)繞格式
以上就是C#讀取多條數(shù)據(jù)記錄導出到Word之圖片輸出改造的詳細內(nèi)容,更多關于C#讀取數(shù)據(jù)并導出到Word的資料請關注腳本之家其它相關文章!
相關文章
C#中使用Spire.XLS來操作Excel數(shù)據(jù)的實現(xiàn)
本文主要介紹了C#中使用Spire.XLS來操作Excel數(shù)據(jù)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-04-04WinForm下 TextBox只允許輸入數(shù)字的小例子
WinForm下 TextBox只允許輸入數(shù)字的小例子,需要的朋友可以參考一下2013-04-04