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#導(dǎo)出網(wǎng)站功能實(shí)例代碼講解
這篇文章主要介紹了C#導(dǎo)出網(wǎng)站功能實(shí)例代碼,需要的朋友可以參考下2015-10-10
C#中調(diào)用命令行cmd開啟wifi熱點(diǎn)的實(shí)例代碼
最近想在win7上開啟wifi熱點(diǎn),于是就弄出下面這個(gè)小東西,里面涉及如何在控制臺(tái)上輸入命令,分享一下。首先在VS中創(chuàng)建一個(gè)window窗口,然后創(chuàng)建兩個(gè)四個(gè)button,兩個(gè)輸入框2013-04-04
淺談Async和Await如何簡(jiǎn)化異步編程(幾個(gè)實(shí)例讓你徹底明白)
本篇文章主要介紹了淺談Async和Await如何簡(jiǎn)化異步編程,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-12-12
詳解C#應(yīng)用程序如何實(shí)現(xiàn)多屏顯示
這篇文章主要為大家詳細(xì)介紹了C#如何實(shí)現(xiàn)把主屏運(yùn)行程序中多個(gè)窗體移動(dòng)到各個(gè)擴(kuò)展屏幕位置顯示,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-05-05
C#使用RegNotifyChangeKeyValue監(jiān)聽注冊(cè)表更改的方法小結(jié)
RegNotifyChangeKeyValue的最后一個(gè)參數(shù)傳遞false,表示以同步的方式監(jiān)聽,這篇文章主要介紹了C#使用RegNotifyChangeKeyValue監(jiān)聽注冊(cè)表更改的方法小結(jié),需要的朋友可以參考下2024-06-06
Unity實(shí)現(xiàn)簡(jiǎn)單虛擬搖桿
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)簡(jiǎn)單虛擬搖桿,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04
C#使用itextsharp生成PDF文件的實(shí)現(xiàn)代碼
以下是對(duì)在C#中使用itextsharp生成PDF文件的實(shí)現(xiàn)代碼進(jìn)行了詳細(xì)分析介紹,需要的朋友可以過來參考下2013-07-07

