Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Inserting an Image into an inline shape in Word Document using Microsoft Open XML SDK

0.00/5 (No votes)
21 Jun 2017 1  
How to insert an image into an inline shape in Word Document using Microsoft Open XML SDK

Introduction

Microsoft Open XML is a new technology that Microsoft recommends using to perform CRUD operations on Office documents (Word, Excel, Powerpoint, etc.). Microsoft recommends using OpenXML over MS Interop. Microsoft also does not recommend the use of server side automation of Microsoft Office applications through server side codes such as ASP.NET, DCOM, and WIndows NT services that use Microsoft Office Interop libraries.

Although OpenXML is the direction that Microsoft wants developers to use to manipulate office documents, it is not as easy to use as compared to using the Microsoft interop libraries. This tip will demonstrate one of the hardest challenges I faced using openXML, which is inserting an image into a shape. For Microsoft interop, this task could've been done in as much as 6 lines.

Background

Starting from Microsoft Office 2007, Open XML file format has become the default file format for Microsoft Office.

To understand this tutorial, make sure you know how to use the basics of the openxml SDK, such as opening and saving documents with C#.

This article assumes you know how to insert an image into a Word document, open and close a Word document using OpenXML. See the link below:

Using the Code

Add the following OpenXML namespaces to your class:

using System;
using System.Collections.Generic;
using System.Linq;
using DocumentFormat.OpenXml;
using A = DocumentFormat.OpenXml.Drawing;
using DW = DocumentFormat.OpenXml.Drawing.Wordprocessing;
using PIC = DocumentFormat.OpenXml.Drawing.Pictures;
using DocumentFormat.OpenXml.Drawing.Wordprocessing;
using Wps = DocumentFormat.OpenXml.Office2010.Word.DrawingShape;

With the namespaces added, you can now use the required classes from OpenXML. Open the document using OpenXML. Add an imagePart that references the image object (The image you want to insert) to the MaindocumentPart object by using a file stream and get the ID of the image.

string temp;
MainDocumentPart mainPart = document.MainDocumentPart;
ImagePart imagePart = mainPart.AddImagePart(ImagePartType.Bmp);

using (FileStream stream = new FileStream(barcodepath, FileMode.Open))
{
    imagePart.FeedData(stream);
}

temp = mainPart.GetIdOfPart(imagePart);

In office OpenXML, a picture that is inserted into a Word document is considered a "Blip" Object or element. The class is derived from the DocumentFormat.OpenXml.Drawing the Blip must have an Embed value that is an imagePart ID. The Blip object then goes inside a BlipFill Object/element, and that also goes inside a graphicData Object/element and that in turn goes into a graphic object element. I'm pretty sure by now you've realized everything works like an XML tree. Sample Open XML tree below:

<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
  <a:graphicData uri=
  "http://schemas.microsoft.com/office/word/2010/wordprocessingShape">
    <wps:wsp>
      <wps:cNvSpPr>
        <a:spLocks noChangeArrowheads="1" />
      </wps:cNvSpPr>
      <wps:spPr bwMode="auto">
        <a:xfrm>
          <a:off x="0" y="0" />
          <a:ext cx="1234440" cy="1234440" />
        </a:xfrm>
        <a:prstGeom prst="roundRect">
          <a:avLst>
            <a:gd name="adj" fmla="val 16667" />
          </a:avLst>
        </a:prstGeom>
        <a:blipFill dpi="0" rotWithShape="1">
          <a:blip r:embed="Raade88ffea8d4c1b" />
          <a:stretch>
            <a:fillRect l="10000" t="10000" 

            r="10000" b="10000" />
          </a:stretch>
        </a:blipFill>
      </wps:spPr>
      <wps:bodyPr rot="0" vert="horz" 

      wrap="square" lIns="91440" tIns="45720" 

      rIns="91440" bIns="45720" anchor="t" 

      anchorCtr="0" upright="1">
        <a:noAutofit />
      </wps:bodyPr>
    </wps:wsp>
  </a:graphicData>
</a:graphic>

Now I have a reference of the image(barcode) I'm trying to add to my document. I want to insert the image into the shapes in the template document. To do this, I would have to use some LINQ to iterate through the document and get a reference to all the shapes in the document. The wps:spPr element you see in the above XML code is the XML element for the shapes in my document. The equivalent C# class is WordprocessingShape.

IEnumerable<DocumentFormat.OpenXml.Office2010.Word.DrawingShape.WordprocessingShape> shapes2 = 
document.MainDocumentPart.document.Body.Descendants
<DocumentFormat.OpenXml.Office2010.Word.DrawingShape.WordprocessingShape>();

Now that I have a collection of all the shape references in my document, I loop through the collection with a foreach, and through each iteration, I create a Blip object. Set the Blip object embed value to the picture ID reference I captured earlier form the image part. I also create a Stretch object, and FillRectangle object (these are not really necessary, I just used them for proper alignment of the barcode). And append each to its parent objects like the XML tree equivalent.

foreach (DocumentFormat.OpenXml.Office2010.Word.DrawingShape.WordprocessingShape sp in shapes2)
  {
    A.BlipFill blipFill = new A.BlipFill() { Dpi = (UInt32Value)0U, RotateWithShape = true };
    A.Blip blip1 = new A.Blip() { Embed = temp };

   A.Stretch stretch1 = new A.Stretch();
   A.FillRectangle fillRectangle1 = new A.FillRectangle() 
      { Left = 10000, Top = 10000, Right = 10000, Bottom = 10000 };
   Wps.WordprocessingShape wordprocessingShape1 = new Wps.WordprocessingShape();

   stretch1.Append(fillRectangle1);
   blipFill.Append(blip1);
   blipFill.Append(stretch1);
   Wps.ShapeProperties shapeProperties1 = sp.Descendants<Wps.ShapeProperties>().First();
   shapeProperties1.Append(blipFill);
                                     
   }

That's pretty much it. Run the code and use a Word document that has inline shapes (rectangle, oval, etc.) and try to insert an image into them.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here