1

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)));
    }
Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
Stuart Brant
  • 155
  • 1
  • 8
  • The issue is copying file stream to memory stream is corrupting the images, but as need to upload to sharepoint not sure how can get round the problem. – Stuart Brant Feb 02 '18 at 12:13
  • Don't even think is MemoryStream specifically but CopyTo method sems to always corrupt the images. Any alternative to using CopyTo method for output file which I need to get header and footer content updated. – Stuart Brant Feb 02 '18 at 16:10
  • It seems that it's not caused by the copying itself, but performing the copy operation before the document is closed. Please take a look at my answer for more details. – Lukasz M Feb 03 '18 at 00:18
  • Lucasz done as you have said and sometimes creates a file and other times is corrupted. Used the OpenXML comparison tool to compare the two documents is nothing obvious to me that would cause corruptions. Also opening a corrupted file in WordPad shows the images I expect – Stuart Brant Mar 12 '18 at 15:34
  • In the answer below I described two solutions to ensure that the document is closed and saved before copying. Have You tried both of them? – Lukasz M Mar 12 '18 at 22:55

1 Answers1

0

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 :).

Lukasz M
  • 5,635
  • 2
  • 22
  • 29
  • Lucasz, haven't marked this as an answer as unable to get consistent results with Images after making the suggested changes. Will run it once and display an uncorrupted file. Repeat and then get a corrupted file. Running a comparison using the comparison tool shows nothing that should cause the file to be corrupted. – Stuart Brant Mar 13 '18 at 11:26
  • Have 5 tables in my report being populated – Stuart Brant Mar 13 '18 at 11:34
  • 1
    Using random number in drawing element part has sloved my issue, marking this as answer – Stuart Brant Mar 13 '18 at 12:25