c# - 我正在使用 OpenXML SDK 合并两个 Word 文档,但在将图像复制到标题中时得到损坏的文档

标签 c# openxml wordprocessingml

我有适用于各种不同情况的代码,包括将图像复制到文档正文中时。

将页眉和页脚从一个文档复制(添加)到另一个文档时,只要被复制的页眉/页脚不包含图像,该代码就可以工作。

当我复制其中包含图像的 header 时,生成的文件已损坏,当我尝试使用 OpenXML SDK 打开它时,它抛出异常,提示“压缩部分的数据长度不一致”。 我知道图像必须在 HeaderPart 中创建(与复制到正文中时的 MainDocumentPart 相对)。

合并图像的代码如下所示:

    private void AddSourceImagesToDestination(XElement sourceXml, OpenXmlPart sourcePart, OpenXmlPart destPart) {
      foreach(XElement drawingElement in sourceXml.Descendants(_mswDrawingElementName)) {

        XAttribute aBlipEmbedAttribute = drawingElement.Descendants(_ablipElementName).First().Attribute(_embedAttributeName);
        string relationshipId = aBlipEmbedAttribute.Value;
        ImagePart sourceImagePart = (ImagePart)sourcePart.GetPartById(relationshipId);
        ImagePart destinationImagePart = ((HeaderPart)destPart).AddImagePart(sourceImagePart.ContentType);
        string newRelationshipId = destPart.GetIdOfPart(destinationImagePart);
        aBlipEmbedAttribute.SetValue(newRelationshipId);

        destinationImagePart.FeedData(sourceImagePart.GetStream(FileMode.Open, FileAccess.Read));
      }  
  }

以上称为传递源和目标 HeaderParts,以及源 header 的 XML,此后将被复制到目标文档中。调用上述过程后,会调用 destinationHeaderPart.Header.Save()。

正如我上面所说,如果源 header 中没有图像,那么生成的文档就没有问题(即当 foreach 在源 XML 中找不到任何绘图元素时)。

不过,我想知道标题中图像的这种症状是否可能是转移注意力,而真正的问题是在其他地方。

最佳答案

正如我在对该问题的评论中所说,将图像包含到页眉和页脚中的代码很好 - 它成功了。

我如何解决我的代码(在其他地方)创建的损坏文件的问题是通过反复试验。正如其他贡献者所说,委婉地说,围绕 OpenXML 的文档不是很好。所以这个问题可能有另一种解决方案,也许我的“解决方案”只是因为其他一些副作用而起作用。

无论如何,我有一些看起来像这样的代码:

    private MemoryStream _memoryStream;
    private WordprocessingDocument _wordDocument;
      ...
    _wordDocument = WordprocessingDocument.Open(_memoryStream, true);
      ... 

    private void ReopenDocument() {
      _wordDocument.Package.Flush();
      _wordDocument.Close();
      MemoryStream newStream = new MemoryStream();
      _memoryStream.WriteTo(newStream);
      _memoryStream.Close();
      _memoryStream = newStream;
      _memoryStream.Position = 0L;
      _wordDocument = WordprocessingDocument.Open(_memoryStream, true);
    }

如果我在将 _memoryStream 写入 FileStream 之前立即调用 ReopenDocument 方法,则可以避免损坏。

关于c# - 我正在使用 OpenXML SDK 合并两个 Word 文档,但在将图像复制到标题中时得到损坏的文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9617372/

相关文章:

c# - 通过 TCP 接收数据 : MemoryStream contains more data than expected

C# 多源、不同线程、一个事件处理程序

c# - 使用反射时将新版本/修复替换为 dll

c# - 需要使用 ClosedXml 并将 excel 文件保存到本地 pc

excel - OpenOfficeXML : Copy worksheet from one work book to another

c# - OpenXML - 不从一行中读取空白单元格 C#

java - 如何从 docx4j 运行中简洁地提取文本?

C# Selenium - 有没有办法在不抛出 NoSuchElementException 的情况下检查元素是否存在

ms-word - 如何在使用 java 和 docx4j 生成 docx 文件时在单元格上使用和应用 HMerge?

c# - 将表(行)与 OpenXML SDK 2.5 一起保存