前言:
由于对C#操作WORD不熟悉,也就留下这么一篇水文,别吐糟...=_=|||
利用Microsoft.Office.Interop.Word (2003版也就11版)——因为部分客户端还是用Office2003,所以保险起见应该引入低一点的版本
我的需求很简单,从DataTable里面循环取数据批量生成Word文档,解决方案是利用Word模板.dot插入书签并保存为程序使用的模板,
用C#打开word模板修改书签的值并批量生成Word.
遇到的问题:
我的思路是打开模板,然后循环修改书签内容,每循环一次生成一个.doc,实际上遇到的问题是当第二次给书签赋值(比如bookMark.Range.Text="2013-4-24")发现是+=的操作,也就是循环第二次书签的值是"2013-4-242013-4-24",我的理解是因为模板没有关闭,所以对书签实际上是进行了两次【插入】的操作,而非我们理解的【赋值】,一个可以实现的做法是先关闭dot再打开重新进行一次赋值,但是由于耗时超长所以我毫不犹豫抛弃这种做法,平均下来几乎一秒钟才生成一个WORD,当然Win764bit效率要低一点。——因为我后来才发现生成的软件在32bit 的xp运行效率比62bit 的WIN7高不少,而我在虚拟机运行的效率竟然比32bit 的宿主xp更快,可能虚拟机只装了office2003和framework2.0的缘故,即便如此,在xp下效率还是很低。问题回到如何不关闭模板文件的情况下,循环插入生成WORD。
解决方案:
- object[] oBookMark = new object[8];
- oBookMark[0] = "Date";//省略赋值 用来记录书签名称
- Word.Range[] rng = new Word.Range[8];
- string[] bookMarkName = new string[8];
- for (int i = 0; i < 8; i++)
- {
- rng[i] = oDoc.Bookmarks.get_Item(ref oBookMark[i]).Range;//获取书签对象赋值给我们已经定义的数组用来下面循环体的插入
- bookMarkName[i] = oDoc.Bookmarks.get_Item(ref oBookMark[i]).Name;//获取书签名称好书签对象赋值给我已经定义好的rng和oBookMark
- }
- //循环体
- for (int i = dt.Rows.Count-1; i >= 0; i--)
- {
- rng[0].Text = dt.Rows[i]["日期"].ToString();//赋值多个书签0~8
- for (int j = 0; j < 8; j++)
- {
- oDoc.Bookmarks.Add(bookMarkName[j], rng[j]);//此处直接插入即可,替代了原来的书签,位置不变...囧
- //也就是说Add操作实际上并不是随意插入书签,而是替代了原有书签,这样子每次就可以重新赋值了
- }
- //这里保存oDoc 用Save方法
- }
思路获取书签对象和书签名称赋值给我们已经定义的oBook和rng,然后做一个插入的操作,而非修改文档本身的书签值
这个方法跟刚刚搜到的文章《如何利用书签向word文档读取或写入数据[C#]》提及的“由于附值以后书签自动消除,为了以后便于修改,需要把书签再自动生成一个”
似乎是一样的实现,也懒得细想,另外我还利用Selection.InsertFile方法把生成的文档合并为一个文件(由于这个方法只能附加文件而不能从doc对象中提取页面进行附加,所以又有了大量的打开Word操作,两个Word.exe在后台进行,看着也蛋疼,果不其然的使程序更加耗时间),但是一个文件多个页面还是比多个单页的文档讨人喜欢。还是欢迎吐糟吧。。=_=||||