今天遇到一个问题,就是需要把多个Word文档的内容追加到一个目标Word文档的后面,如果我有目标文档a.doc以及其他很多个文档b.doc,c.doc…等等数量很多。这个问题,如果是在服务端的话,直接使用OpenXML技术,读写文档就可以实现,这样性能较稳定,但是需要对OpenXML有一定的了解。如果在客户端机器上,可以使用Word PIA实现。

由于本人对于Word PIA较熟悉,所以采用了该方法。但是在实现的过程中,也是有很多种思路的。

  1. 将b.doc打开,将其中的内容选中,复制到剪贴板,然后打开目标文件a.doc,通过代码将光标移到文档末尾,粘贴。粘贴一次保存一下文件,然后在打开c.doc重复以上过程,知道所有文件均添加完成。
  2. 将b.doc打开,将其中的内容选中,获取Range对象,然后打开目标文件a.doc,在里面通过代码插入b的内容。

以上两种方法都涉及到打开和读取待合并的文档。完成之后还需要及时关掉已释放资源。对于一些复杂的对象,比如说具有行或者列合并的表格对象,采用第二种方式在目标文档中创建表格,然后循环遍历待合并文档中的表格,并给目标文档中的表格进行赋值会出现问题。效果都不太好。

在查找了一些资料后,发现Word自带有添加文档内容到打开文档中的功能。

 Insert Text form file

这样就简单多了,通常最简单的做法是录制宏。

Record Macro

操作步骤如下:

  1. 点击录制宏
  2. 打开目标文件a.doc
  3. 然后按住键盘 Ctrl+End 键,跳转到文档a的末尾。
  4. 点击 Insert­(插入)->Object(对象)->Text from file(文件中的文字)
  5. 选中待插入的文件b.doc,确定
  6. 停止录制宏

点击宏编辑,然后可以看到我们刚才操作的步骤与之对应的代码。然后我们将它转为.NET中调用的方式即可。在Office开发中,这是一种很有用的技巧。

Sub Macro1()
    Selection.EndKey Unit:=wdStory
    ChangeFileOpenDirectory "D:\"
    Selection.InsertFile FileName:="b.docx", Range:="", _
        ConfirmConversions:=False, Link:=False, Attachment:=False
End Sub

这里的关键方法有两个,一个是Selection.EndKey,用来跳转到文档的最后,一个是InsertFile,从文档中导入文本。将上面的VBA代码转为.NET中C#代码如下:

private void btnCombine_Click(object sender, EventArgs e)
{
    //创建WordApp对象
    Word.Application wordApp = null;
    try
    {
        wordApp = (Word.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
    }
    catch (System.Runtime.InteropServices.COMException ex)
    {
        wordApp = new Word.Application();
    }
    //源文件,待合并的文件
    object missing = Type.Missing;
    object targetfilename = @"D:\a.docx";
    Word.Document docTarget = wordApp.Documents.Open(ref targetfilename, ref missing, ref missing, ref missing, ref missing,
        ref missing, ref missing, ref missing, ref missing, ref missing,
        ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);

    //所有的要往源文件中合并的文件,注意顺序
    //在实际操作中把这部分替换为 遍历文件夹下的所有想合并的word文档的名称即可
    for (int count = 0; count <= 3; count++)
    {
        string sourcefilename = @"D:\b.docx";
        //移动光标到文档末尾
        docTarget.Application.Selection.EndKey(WdUnits.wdStory);
        //在文档末尾插入待合并内容
        docTarget.Application.Selection.InsertFile(sourcefilename, ref missing, false, false, false);
        //保存
        docTarget.Save();
    }

    docTarget.Save();

    Marshal.ReleaseComObject(wordApp);
    MessageBox.Show("Success");
}

代码中需要注意的是,创建Word.Application对象的方式,以及资源释放的方式。