I am merging two Word documents with OpenXML SDK but get a corrupt document when copying an image into a header

StackOverflow https://stackoverflow.com//questions/9617372

  •  09-12-2019
  •  | 
  •  

Question

I have code which works in all sorts of different situations, including when copying images into the body of the document.

The code works when copying (adding) headers and footers from one document to the other, as long as the headers/footers being copied do not contain images.

When I copy a header which has an image in it, then the resulting file is corrupt, and when I try to open it with the OpenXML SDK it throws an exception saying "Compressed part has inconsistent data length". I do know that the image has to be created in the HeaderPart (as against the MainDocumentPart when copying into the body).

The code which does the merging of the image looks something like:

    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));
      }  
  }

The above is called passing the source and destination HeaderParts, and the XML of the source header which will after this be copied into the destination document. After calling the above procedure, destinationHeaderPart.Header.Save() is called.

As I said above, if there are no images in the source header, then the resulting document is fine (i.e. when the foreach doesn't find any drawing elements in the source XML).

I wonder, though, whether this symptom of the images in the header is perhaps a red herring and the real problem is somewhere else.

Was it helpful?

Solution

As I said in the comment on the question, the code to include the images into the header and footer was fine - it did the trick.

How I solved the problem of the corrupt file that my code (elsewhere) was creating was by a bit of trial and error. As other contributors have said, the documentation around OpenXML is, to put it mildly, not very good. So there might be another resolution to this problem, and maybe my "solution" just works because of some other side effects.

Anyway, I have some code which looks like this:

    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);
    }

If I call the ReopenDocument method immediately prior to writing the _memoryStream to a FileStream, then the corruption is avoided.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top