问题 使用OpenXML SDK将RTF文件的内容嵌入到DOCX文件中


在我们旧的基于MSWord-97的系统中,我们使用COM与.doc文件进行交互,并嵌入OLE对象,因此嵌入的文档在父文件中可见(而不是图标)。

我们用一个使用OpenXML SDK的系统取而代之,因为它需要在我们的服务器上安装Word,这会生成.docx文件。但是我们仍然需要将RTF文件的内容嵌入到生成的DOCX中...具体来说,我们用文件的内容替换书签。

我在网上找到了一些例子,但它们都有所不同。当我在Word中创建一个简单的例子并查看XML时,有一个 批量 用于定位/显示嵌入对象的可视化表示的东西,而嵌入本身似乎并不太可怕。最简单的方法是什么?


3175
2017-07-28 15:12


起源

好吧,我暂停了这个任务,但是在3.5年后重新打开了它。我开始在SO上写一个问题,它提醒我已经存在了! - Mr. Boy
可能相关,也许它可以帮助某人: social.msdn.microsoft.com/Forums/office/en-US/... - Mr. Boy


答案:


你可以嵌入一个内容 RTF 将文档转换为OpenXML DOCX 文件 通过使用 AltChunk 锚定外部内容。该 AltChunk (w:altChunk)元素指定 OpenXML WordprocessingML文档中的一个位置,用于插入外部内容,例如 RTF 文件。 下面的代码使用 AltChunk 与...一起上课 AlternativeFormatImportPart 类 嵌入一​​个内容 RTF 文件成一个 DOCX 最后一段后面的文件:

using (WordprocessingDocument wordDocument = WordprocessingDocument.Open(@"your_docx_file.docx", true))
{
  string altChunkId = "AltChunkId5";

  MainDocumentPart mainDocPart = wordDocument.MainDocumentPart;
  AlternativeFormatImportPart chunk = mainDocPart.AddAlternativeFormatImportPart(
        AlternativeFormatImportPartType.Rtf, altChunkId);      

  // Read RTF document content.
  string rtfDocumentContent = File.ReadAllText("your_rtf_document.rtf", Encoding.ASCII);

  using (MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(rtfDocumentContent)))
  {
    chunk.FeedData(ms);
  }

  AltChunk altChunk = new AltChunk();
  altChunk.Id = altChunkId;

  // Embed AltChunk after the last paragraph.
  mainDocPart.Document.Body.InsertAfter(
    altChunk, mainDocPart.Document.Body.Elements<Paragraph>().Last());

  mainDocPart.Document.Save();
}

如果要嵌入Unicode RTF 串成一个 DOCX 然后你必须转义Unicode字符。有关示例,请参阅以下内容 stackoverflow的答案

当您遇到错误时 “该文件已损坏“然后确保你 Dispose() 要么 Close() 该 WordprocessingDocument。如果你没有关闭()文件然后关闭 w:altchunk 没有存储在 Document.xml.rels 文件。


12
2017-12-01 13:22



我用过 AltChunk 在将HTML插入docx文件之前,它就像魅力一样。绝对是要走的路 - flipchart
嗯,这似乎进展顺利,但是在保存更改后尝试在Word 2010中打开它时,我得到“文件已损坏”。我现在几乎正在使用这个例子。我应该检查什么,我应该在哪里看? - Mr. Boy
@John:你能提供一份样本文件(已损坏)吗?所以我会看一下。我使用OpenXML生产力工具包来检查这些文档。您插入的RTF文档是否完整(有效)?内存流的当前位置是零吗?请注意,FeedData方法不会寻找流的开头。 - Hans
@Hans通过在文件之前/之后解压缩.docx并执行diff,我看到输出目录有一个(有效的)RTF文件,而document.xml有一个新元素 <w:altChunk r:id="AltChunkId5" />在最后一段之后但是 没有其他的 新。似乎缺少某些东西? - Mr. Boy
@John:您能提供一份示例文档或您使用的确切代码来包含w:altChunk吗?请注意,w:altChunk元素的r:id必须是唯一的。 - Hans


这个家伙似乎已经用他自己的问题和答案解决了这个问题 如何使用OpenXml 2.0将任何文件类型嵌入到Microsoft Word中


0
2017-07-30 07:14



他的解决方案仍然需要你安装Word,这对于服务器端文档生成来说是一个糟糕的想法,也是我们首先创建新工具的全部原因。除了其他任何东西,在一些服务器配置你 不能 通过COM运行Word。 - Mr. Boy
呃,你是对的,就在底部。在WordprocessingML中提供所有这些似乎毫无意义,只是用interop来破坏它。 - Todd Main