C#實現讀取多條數據記錄并導出到Word
應用需求
將數據庫數據表中的數據輸出并打印,WORD 是一個良好的載體, 在應用項目里,許多情況下我們會使用數據記錄結合 WORD 標簽模板進行配合,輸出數據進行打印的功能需求。
實現步驟
1、設計WORD模板,在需要輸出值的地方設置 自定義關鍵字+字段名(如%%_name),其中%%_為自定義關鍵字,name為輸出字段名。
2、根據條件查詢數據表,生成 DataSet ,如果有數據則取 Tables[0]里的數據記錄。
3、拷貝 WORD 全部內容到剪貼板做模板數據。
4、遍歷數據表記錄,粘貼剪貼板內容, 按照自定義關鍵+列名稱,在 WORD 中按關鍵字查找,并替換成對應的實際數據,完成輸出。
舉例我們需要提取人員的基本信息生成準考證并打印如下圖:

根據以上的結果輸出,我們需要設置如下圖標簽模板:

如圖我們準備SQL語句如:select ProjectName,Name,Sex,IdCard,EACode,Position,Time,Address from infos where ... 并生成數據表。
其中 “ key_” 則為自定義關鍵字,后綴則對應查詢輸出字段名。
范例運行環(huán)境
操作系統(tǒng): Windows Server 2019 DataCenter
操作系統(tǒng)上安裝 Office Word 2016
數據庫:Microsoft SQL Server 2016
.net版本: .netFramework4.7.1 或以上
開發(fā)工具:VS2019 C#
配置Office DCOM
配置方法可參照我的文章《C# 讀取Word表格到DataSet》進行處理和配置。
實現代碼
組件庫引入

核心代碼
public string DataTableToWord(string _filename,string _repeatKey,object _dataset),該方法提供3個參數,WORD模板文件名、自定義關鍵字、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;//關閉拼寫檢查
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();
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);
//關閉WordApp組件對象
WordApp.Quit(ref Nothing, ref Nothing, ref Nothing);
}小結
1、核心代碼中有對字段類型的判斷:if(dt.Columns[j].DataType==typeof(System.Byte[])),如果為System.Byte[],則表示為圖片類型字段,這是我們自行的約定,對于圖片的寬高可以根據實際需要進行設定或定義參數。
2、在根據模板內容,每輸出一條記錄后,均會插入分頁符:
object ib = Word.WdBreakType.wdPageBreak; WordApp.Selection.InsertBreak(ref ib);
以保證打印的數據區(qū)域獨立和完整性,這要根據實際應用來決定是否輸出。
以上就是C#實現讀取多條數據記錄并導出到Word的詳細內容,更多關于C#讀取數據并導出到Word的資料請關注腳本之家其它相關文章!
相關文章
淺談Async和Await如何簡化異步編程(幾個實例讓你徹底明白)
本篇文章主要介紹了淺談Async和Await如何簡化異步編程,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-12-12
C#使用RegNotifyChangeKeyValue監(jiān)聽注冊表更改的方法小結
RegNotifyChangeKeyValue的最后一個參數傳遞false,表示以同步的方式監(jiān)聽,這篇文章主要介紹了C#使用RegNotifyChangeKeyValue監(jiān)聽注冊表更改的方法小結,需要的朋友可以參考下2024-06-06

