2

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

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

当我复制其中包含图像的标头时,生成的文件已损坏,并且当我尝试使用 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,源头的 XML 在此之后将被复制到目标文档中。调用上述过程后,将调用destinationHeaderPart.Header.Save()。

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

不过,我想知道标题中图像的这种症状是否可能是一个红鲱鱼,而真正的问题在其他地方。

4

1 回答 1

4

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

我如何解决我的代码(在其他地方)创建的损坏文件的问题是通过一些试验和错误来解决的。正如其他贡献者所说,围绕 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 方法,则可以避免损坏。

于 2012-04-02T07:56:26.313 回答