Microsoft.Office.Interop.Word.Document 分段拆分文档

Microsoft.Office.Interop.Word.Document Section wise split document

我有一个包含多个部分的word文档,我需要根据每个部分创建多个文档。

我已经尝试了以下但无法在新文档中添加部分。

Microsoft.Office.Interop.Word.Application appWord = new Microsoft.Office.Interop.Word.Application();
Microsoft.Office.Interop.Word.Document document = appWord.Documents.Open("file.docx");
foreach (Microsoft.Office.Interop.Word.Section sec in document.Sections)
{
    Microsoft.Office.Interop.Word.Document documentNew = new Microsoft.Office.Interop.Word.Document();
    documentNew.Sections.Add(sec.Range);
    documentNew.SaveAs2("new.docx");
}

据我所知,你有一个带有“节”的 Word 文档。您想要打开该文档,遍历其中的所有“部分”,并且对于文档中找到的每个“部分”,您想要创建一个“新”Word 文档,以便新文档中的第一部分与原始文档中的当前部分。我希望我做对了。

查看您当前发布的代码……foreach 循环遍历原始文档的每个部分。然后创建一个新的 Word 文档,并在新文档中添加一个新的“部分”...

documentNew.Sections.Add(sec.Range);

由于多种原因,此行将抛出异常。但是,应该清楚“为什么”这可能行不通。在上面的代码中,我们试图向新文档“添加”一个新部分。问题是我们试图添加的“什么”…… sec.Range ……属于原始文档,并且创建了一个明确的“参考”问题,因为您将在“两个”文档中都有“一个”部分。很明显,仅此一项可能会导致问题,但是,copy-paste 可能是一个解决方案。

使用 copy-paste 至少可以解决上述双重引用问题。下面的代码使用“Word/Interop copy-paste”将原始文档中的“部分”复制到新文档中。由于我们无法真正“复制”“节”对象并将其“添加”到新文档中,另一种方法是简单地从原始文档中“复制”“节”Range,然后添加一个新的“ section”添加到新文档中,最后将Range“粘贴”到新的section中。我希望这是有道理的。

接下来,当前代码会用每个部分覆盖“new.docx”文件,因此您最终只会得到一个包含原始文档最后一节的文件。如果我们想要每个部分都有一个“新的”Word 文档,那么我们将需要某种文件名增量器来防止文件被覆盖。

最后,在使用互操作或其他 com 对象时要小心。 “close/release”您的代码创建的 com 对象很重要。具体来说,在这种情况下,appWord 对象和 document 对象。在您当前的代码中,因为我相信它会抛出异常,如果您 运行 一次又一次地多次……然后……去查看您的任务管理器……我相信您会看到许多 Word 应用程序 运行宁在后台。这称为泄漏资源,您希望避免这种情况。

通常在处理互操作时,无论是 Word 还是 Excel 等……我发现最简单的解决方案是将与 Office 对象交互的所有代码“包装”在“Try/Catch/Finally “ 陈述。所有代码都在“try”部分,一个“catch”部分,用于在出现错误时显示错误,以及最重要的“finally”部分,我们可以在其中正确关闭和释放 com 对象。这将有助于正确关闭 Word 应用程序,即使引发异常也是如此。我强烈建议您在使用互操作时使用 try/catch/finally。

下面的方法SaveSectionsToFiles(string sourceFile, string destPath) ...演示了上面描述的内容。

private void SaveSectionsToFiles(string sourceFile, string destPath) {
  string curFileName;
  int curFileNumber = 1;
  Word.Application appWord = null;
  Word.Document sourceDoc = null;
  Word.Document destDoc = null;
  Word.Section tempSection;
  try {
    appWord = new Word.Application();
    //appWord.Visible = true;
    sourceDoc = appWord.Documents.Open(sourceFile);
    foreach (Word.Section sec in sourceDoc.Sections) {
      sec.Range.Copy();  // <- Copy section range from original doc
      destDoc = new Word.Document();
      destDoc.Sections.Add();
      tempSection = destDoc.Sections[1];
      tempSection.Range.Paste();  // <- Paste range into new section of new document
      curFileName = destPath + "NewDocSec_" + curFileNumber++ + ".docx";
      destDoc.SaveAs2(curFileName);
      destDoc.Close();
    }
  }
  catch (Exception ex) {
    MessageBox.Show("Error: " + ex.Message);
  }
  finally {
    if (sourceDoc != null) {
      sourceDoc.Close();
      Marshal.ReleaseComObject(sourceDoc);
    }
    if (appWord != null) {
      appWord.Quit();
      Marshal.ReleaseComObject(appWord);
    }
  }
}

用法……

private void button1_Click(object sender, EventArgs e) {
  string sourceFile = @"D:\Test\WordTests\SectionDocument.docx";
  string destPath = @"D:\Test\WordTests\";
  SaveSectionsToFiles(sourceFile, destPath);
}