Search code examples
c#openxmlopenxml-sdk

C# WordprocessingDocument - insert an image in a cell - Image cannot be displayed


The following code is executed to add an image to a cell:

using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(byteArrayOriginalStream, true))
{
     using (Stream imageStream = new MemoryStream())
     {
         using (FileStream tempStream = new FileStream("C:\Images\xxxx Critical.jpg", FileMode.OpenOrCreate, FileAccess.ReadWrite))
         {
              tempStream.CopyTo(imageStream);
         }

         ImagePart imagePart = wordDoc.MainDocumentPart.AddImagePart(ImagePartType.Jpeg);
         imageStream.Seek(0, SeekOrigin.Begin);
         imagePart.FeedData(imageStream);
         pictureCell.RemoveAllChildren();
         AddImageToCell(pictureCell, wordDoc.MainDocumentPart.GetIdOfPart(imagePart));
    }
    wordDoc.MainDocumentPart.Document.Save();
    //copy the bytearraystream to outputfilestream
    byteArrayOriginalStream.Seek(0, SeekOrigin.Begin);
    byteArrayOriginalStream.CopyTo(outputStream);
}

This then creates a word document within a WCF Service in a destination URL passed to the service, however, the word document always shows "We're sorry. We can't open {nameoffile}.docx because we found a problem with it's contents and if press ok see red x with "This image cannot be displayed".

Is creating documents within a WCF service causing this problem, shouldn't be as not returning the message but creating the file.

jpg file only 32kb in size so wouldn't have thought that the issue.

How can I get my image to display?

The AddImageToCell code is below in case there is an issue with that

                            }
private static void AddImageToCell(TableCell cell, string relationshipId)
    {
        var element =
          new Drawing(
            new DW.Inline(
              new DW.Extent() { Cx = 990000L, Cy = 792000L },
              new DW.EffectExtent()
              {
                  LeftEdge = 0L,
                  TopEdge = 0L,
                  RightEdge = 0L,
                  BottomEdge = 0L
              },
              new DW.DocProperties()
              {
                  Id = (UInt32Value)1U,
                  Name = "Picture 1"
              },
              new DW.NonVisualGraphicFrameDrawingProperties(
                  new A.GraphicFrameLocks() { NoChangeAspect = true }),
              new A.Graphic(
                new A.GraphicData(
                  new PIC.Picture(
                    new PIC.NonVisualPictureProperties(
                      new PIC.NonVisualDrawingProperties()
                      {
                          Id = (UInt32Value)0U,
                          Name = "New Bitmap Image.jpg"
                      },
                      new PIC.NonVisualPictureDrawingProperties()),
                    new PIC.BlipFill(
                      new A.Blip(
                        new A.BlipExtensionList(
                          new A.BlipExtension()
                          {
                              Uri = "{28A0092B-C50C-407E-A947-70E740481C1C}"
                          })
                       )
                      {
                          Embed = relationshipId,
                          CompressionState =
                          A.BlipCompressionValues.Print
                      },
                      new A.Stretch(
                        new A.FillRectangle())),
                      new PIC.ShapeProperties(
                        new A.Transform2D(
                          new A.Offset() { X = 0L, Y = 0L },
                          new A.Extents() { Cx = 990000L, Cy = 792000L }),
                        new A.PresetGeometry(
                          new A.AdjustValueList()
                        )
                        { Preset = A.ShapeTypeValues.Rectangle }))
                )
                { Uri = "http://schemas.openxmlformats.org/drawingml/2006/picture" })
            )
            {
                DistanceFromTop = (UInt32Value)0U,
                DistanceFromBottom = (UInt32Value)0U,
                DistanceFromLeft = (UInt32Value)0U,
                DistanceFromRight = (UInt32Value)0U
            });

        cell.Append(new Paragraph(new Run(element)));
    }

Solution

  • I've managed to recreate a similar scenario and get an error for inserted image when using stream to open and then save the result to stream again.

    The issue was that relationship to the image part was not correctly saved in the document. After some research I've found this post, which mentions that relationships are saved upon document close. In Your code, the document stream is copied to the resulting stream before the document is closed. This seems to be the cause of the issue.

    There are several ways to fix this. You can try to:

    1. move document copying out of the using statement, where document is opened:

      using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(byteArrayOriginalStream, true))
      {
          //...
      }
      
      byteArrayOriginalStream.Seek(0, SeekOrigin.Begin);
      byteArrayOriginalStream.CopyTo(outputStream);
      

    or

    1. explicilty call the Close() method on the document instance before copying:

      using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(byteArrayOriginalStream, true))
      {
          //...
          wordDoc.MainDocumentPart.Document.Save();
          wordDoc.Close();
      
          //copy the bytearraystream to outputfilestream
          byteArrayOriginalStream.Seek(0, SeekOrigin.Begin);
          byteArrayOriginalStream.CopyTo(outputStream);
      }
      

    If this doesn't fix the issue or if You have any further questions, don't hesitate to ask :).