运用C#生成docx格式的报表
这几天在北京做一个大桥的监测系统的项目,涉及到一个功能,那就是采集数据,处理后,希望能自动生成一个报表,只需要在一个模板的基础上加几个数就可以了,但因为希望生成的是.docx格式的word2007/2010文件,所以中间还遇到不少困难,现在终于基本完成了这个功能,趁现在还记得在这里写篇博文记录下。
我的工作环境: Windows XP SP3 Microsoft Visual Studio 2010 Microsoft Office 2010 首先,我在VS2010中新建了一个控制台应用程序,然后再在解决方案资源管理器中加入两个引用:
Microsoft Office 14.0 Object Library (这是一个COM组件,应该是装完Office后就有,我用的是Office 2010,所以版本号是14.0,其具体位置在C:\WINDOWS\assembly\GAC_MSIL\Office\ 14.0.0.0__71e9bce111e9429c\Office.dll,每个人的电脑可能会有所不同) Microsoft.Office.Interop.Word (这是一个标准的C# Extension,再装完VS2010后,会带来两个名称相同的Microsoft.Office.Interop.Word,版本号分别为12.0和14.0,应该分别对应Office 2007 和Office2010,在这里我选择了版本号为14.0,其具体位置在 C#安装目录\Visual Studio Tools for Office\PIA\Office14\Microsoft.Office.Interop.Word.dll)
然后写using部分,包括:
using System; using System.Runtime.InteropServices; using Microsoft.Office.Interop.Word;
其中,System.Runtime.InteropServices提供各种各样支持 COM interop 及平台调用服务的成员,非常重要。
在正式写代码之前,我们要先做一个模板,在模板的基础上添加数字自然要比凭空生出一个word文件方便得多。假设我们做出来这么一个模板:
报表模板
然后我们将它保存为.dotx格式。比如命名为evaulation.dotx,保存在D盘根目录。 然后我们要将在这个模板添加书签,比如在如图位置中添加书签如“”。
下面我们看C#代码(我的代码风格不好,各位看官见谅……):
string Date = System.DateTime.Today.ToString().Split(' ')[0].Replace("/", "-"); string strFileName = System.Windows.Forms.Application.StartupPath + "\\**路*河大桥技术状态评定_" + Date + ".docx";
这部分是为了生成报表的文件名。
object objFileName = strFileName; bool createByMe; Microsoft.Office.Interop.Word.Application oWord; try { //如果有正在运行的word实例,则直接采用当前的word实例, //否则,直接创建新实例,在最后退出时会报模板正在使用中等问题 oWord = (Microsoft.Office.Interop.Word.Application)Marshal.GetActiveObject("Word.Application"); createByMe = false; } catch { oWord = new Microsoft.Office.Interop.Word.Application(); createByMe = true; }
这部分是尝试建立word对象。
Object Nothing = System.Reflection.Missing.Value; Object template = System.Windows.Forms.Application.StartupPath + "\\evaulation.dotx"; Document myDoc = oWord.Documents.Add(ref template, ref Nothing, ref Nothing, ref Nothing);
evaulation.dotx即为我们的模板。
object bkObj1 = "Bookmark_1"; if (oWord.ActiveDocument.Bookmarks.Exists("Bookmark_1")) { oWord.ActiveDocument.Bookmarks.get_Item(ref bkObj1).Select(); oWord.Selection.TypeText(txtImportant.Text); }
在Bookmark_1处添加textbox控件txtImportant的属性Text。
myDoc.SaveAs(ref objFileName, 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); myDoc.Close(ref Nothing, ref Nothing, ref Nothing); if (createByMe) { oWord.Quit(ref Nothing, ref Nothing, ref Nothing); }
保存和关闭文件。
最后的完整代码:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; using Microsoft.Office.Interop.Word; using System.IO; namespace WFABridgeMonitorTest1 { public partial class MakeReportForm : Form { public MakeReportForm() { InitializeComponent(); } private void cmdOutput_Click(object sender, EventArgs e) { string Date = System.DateTime.Today.ToString().Split(' ')[0].Replace("/", "-"); string strFileName = System.Windows.Forms.Application.StartupPath + "\\密关路白河大桥技术状态评定_" + Date + ".docx"; object objFileName = strFileName; bool createByMe; Microsoft.Office.Interop.Word.Application oWord; try { //如果有正在运行的word实例,则直接采用当前的word实例, //否则,直接创建新实例,在最后退出时会报模板正在使用中等问题 oWord = (Microsoft.Office.Interop.Word.Application)Marshal.GetActiveObject("Word.Application"); createByMe = false; } catch { oWord = new Microsoft.Office.Interop.Word.Application(); createByMe = true; } Object Nothing = System.Reflection.Missing.Value; Object template = System.Windows.Forms.Application.StartupPath + "\\evaulation.dotx"; Document myDoc = oWord.Documents.Add(ref template, ref Nothing, ref Nothing, ref Nothing); //do something //myDoc.Paragraphs.Last.Range.Text = "test"; object bkObj1 = "Bookmark_1"; if (oWord.ActiveDocument.Bookmarks.Exists("Bookmark_1")) { oWord.ActiveDocument.Bookmarks.get_Item(ref bkObj1).Select(); oWord.Selection.TypeText(txtImportant.Text); } object bkObj2 = "Bookmark_2"; if (oWord.ActiveDocument.Bookmarks.Exists("Bookmark_2")) { oWord.ActiveDocument.Bookmarks.get_Item(ref bkObj2).Select(); oWord.Selection.TypeText(txtWholeBridge.Text); } object bkObj3 = "Bookmark_3"; if (oWord.ActiveDocument.Bookmarks.Exists("Bookmark_3")) { oWord.ActiveDocument.Bookmarks.get_Item(ref bkObj3).Select(); oWord.Selection.TypeText(txtWholeTech.Text); } object bkObj4 = "Bookmark_4"; if (oWord.ActiveDocument.Bookmarks.Exists("Bookmark_4")) { oWord.ActiveDocument.Bookmarks.get_Item(ref bkObj4).Select(); oWord.Selection.TypeText(txtMainBeam.Text); } object bkObj5 = "Bookmark_5"; if (oWord.ActiveDocument.Bookmarks.Exists("Bookmark_5")) { oWord.ActiveDocument.Bookmarks.get_Item(ref bkObj5).Select(); oWord.Selection.TypeText(txtBearing.Text); } object bkObj6 = "Bookmark_6"; if (oWord.ActiveDocument.Bookmarks.Exists("Bookmark_6")) { oWord.ActiveDocument.Bookmarks.get_Item(ref bkObj6).Select(); oWord.Selection.TypeText(txtPier.Text); } object bkObj7 = "Bookmark_7"; if (oWord.ActiveDocument.Bookmarks.Exists("Bookmark_7")) { oWord.ActiveDocument.Bookmarks.get_Item(ref bkObj7).Select(); oWord.Selection.TypeText(txtDefect.Text); } object bkObj8 = "Bookmark_8"; if (oWord.ActiveDocument.Bookmarks.Exists("Bookmark_8")) { oWord.ActiveDocument.Bookmarks.get_Item(ref bkObj8).Select(); oWord.Selection.TypeText("3个月"); } object bkObj9 = "Bookmark_9"; if (oWord.ActiveDocument.Bookmarks.Exists("Bookmark_9")) { oWord.ActiveDocument.Bookmarks.get_Item(ref bkObj9).Select(); oWord.Selection.TypeText(txtPS.Text); } object bkObj10 = "Bookmark_10"; if (oWord.ActiveDocument.Bookmarks.Exists("Bookmark_10")) { oWord.ActiveDocument.Bookmarks.get_Item(ref bkObj10).Select(); oWord.Selection.TypeText(txtInstitution.Text); } object bkObj11 = "Bookmark_11"; if (oWord.ActiveDocument.Bookmarks.Exists("Bookmark_11")) { oWord.ActiveDocument.Bookmarks.get_Item(ref bkObj11).Select(); oWord.Selection.TypeText(Date); } object bkObj12 = "Bookmark_12"; if (oWord.ActiveDocument.Bookmarks.Exists("Bookmark_12")) { oWord.ActiveDocument.Bookmarks.get_Item(ref bkObj12).Select(); oWord.Selection.TypeText(txtPerson.Text); } myDoc.SaveAs(ref objFileName, 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); myDoc.Close(ref Nothing, ref Nothing, ref Nothing); if (createByMe) { oWord.Quit(ref Nothing, ref Nothing, ref Nothing); } } } }