Question

Below I have code that inserts an image at the end of a document in word using OpenXML. What I need to do is try and find and item called [Image Holder] within the document and replace that with the image I'm passing over.

Here is the current code that adds it to the end of a document

        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 = "NGSignature"
                     },
                     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 = "NGSignature.jpg"
                                     },
                                     new PIC.NonVisualPictureDrawingProperties()),
                                 new PIC.BlipFill(
                                     new A.Blip(
                                         new A.BlipExtensionList(
                                             new A.BlipExtension()
                                             {
                                                 Uri =
                                                   "{28A0092B-C50C-407E-A947-70E740481C1C}"
                                             })
                                     )
                                     {
                                         Embed = relationship_id,
                                         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,
                     EditId = "50D07946"
                 });

        word_doc.MainDocumentPart.Document.Body.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(element)));

UPDATE Ok i opened the file in the OpenXML tool and found the following lines that contain the data I need to replace inside the XML file.

<w:r>
    <w:rPr>
      <w:sz w:val="20" />
    </w:rPr>
    <w:instrText xml:space="preserve"> REF NG_MACRO "HOLDER" "3fd95b6f-4c63-42fb-ba2e-dc6d57975c57" </w:instrText>
  </w:r>

and

  <w:r>
    <w:rPr>
      <w:sz w:val="20" />
    </w:rPr>
    <w:t xml:space="preserve">{HOLDER}</w:t>
  </w:r>

The second part is what I see when I open the document. The first part i'm not sure but the application that creates it puts it in.

To do this correctly i'm guessing the 1 part needs removed and then the image section to replace the 2nd part.

Was it helpful?

Solution

To replace a text holder with an given image use the following steps:

  1. Search for the text place holder.
  2. Determine the parent of the text place holder
  3. Insert the image (Drawing element) after the text place holder.
  4. Remove the text palce holder.

The code below implements the steps described above:

// Search for text holder
Text textPlaceHolder = word_doc.MainDocumentPart.Document.Body.Descendants<Text>()
    .Where((x) => x.Text == "$image_tag$").First();

if (textPlaceHolder == null)
{
  Console.WriteLine("Text holder not found!");      
}
else
{
  var parent = textPlaceHolder.Parent;

  if(!(parent is Run))  // Parent should be a run element.
  {
    Console.Out.WriteLine("Parent is not run");
  }
  else
  {
    // Insert image (the image created with your function) after text place holder.        
    textPlaceHolder.Parent.InsertAfter<Drawing>(element, textPlaceHolder);
    // Remove text place holder.
    textPlaceHolder.Remove();
  }
}

You could also use content place holders (SdtElement) instead of simple text place holders.

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