Using the Open XML Format SDK 2.0 to convert an InfoPath form into a DOCX file

This article shows a simple example of how to use the Open XML Format SDK 2.0 and C# code to convert and add the data from a rich text field and a repeating table to a Word 2007 document (DOCX file).

ADVERTISEMENTS

Problem

You would like to convert the data that is stored in an InfoPath form and use it to create a Word 2007 document.

Solution

You could use either XSLT to convert an InfoPath form to a Word 2007 document or classes in the System.IO.Packing namespace to convert an InfoPath form to a DOCX, but you can also use the OpenXML SDK as this article will discuss.

Discussion

This article demonstrates a simple solution, which converts an InfoPath form with a rich text box field and a repeating table into a Word 2007 document.

  1. Download the Open XML Format SDK 2.0 and install it.
  2. Create a non-empty Word 2007 document and name it Template.docx. The DOCX must have a file size greater than 0 KB. You can open it in Word and add a header to it, for example, just so it has some content.
  3. In InfoPath, create a new Blank form template.
  4. Add a Rich Text Box control, a Repeating Table control, and a Button control to the form template.
  5. Name the Rich Text Box control rtfField, and the Text Box controls within the Repeating Table control, cell1, cell2, and cell3 respectively.
  6. Double-click the Button control to open its Properties dialog box.
  7. On the Button Properties dialog box, click Edit Form Code.
  8. In the Project Explorer in Microsoft Visual Studio Tools for Application, right-click the project name and select Add Reference from the context menu that appears.
  9. On the Add Reference dialog box, click the Browse tab, navigate to the location where you installed the Open XML SDK, select the DocumentFormat.OpenXml.dll DLL, and click OK. The default location of this DLL when you install the SDK is: C:\Program Files\Open XML Format SDK\V2.0\lib\DocumentFormat.OpenXml.dll.
  10. Add the following using statements to the FormCode.cs file.

    using System.IO;
    using System.Text;
    using DocumentFormat.OpenXml.Packaging;
    using DocumentFormat.OpenXml.Wordprocessing;

  11. Add the following 2 private functions to the FormCode.cs file:

    private TableCell createCell(string content)
    {
    // Create a new table cell
    TableCell tc = new TableCell();

    // Specify the width of the table cell
    TableCellWidth tcw = new TableCellWidth();
    tcw.Width = 2400;
    tcw.Type = TableWidthUnitValues.Dxa;
    tc.Append(new TableCellProperties(tcw));

    // Specify the content of the table cell
    tc.Append(new Paragraph(new Run(new Text(content))));

    // Return the new table cell
    return tc;
    }

    private TableRow createRow(string cell1, string cell2, string cell3)
    {
    // Create a new table row
    TableRow tr = new TableRow();

    // Add the table cells to the table row
    tr.Append(createCell(cell1));
    tr.Append(createCell(cell2));
    tr.Append(createCell(cell3));

    // Return the new table row
    return tr;
    }

  12. Add the following C# code to the Clicked event handler for the button:

    // Get a reference to the main data source
    XPathNavigator root = MainDataSource.CreateNavigator();

    // Copy the template and create a new document
    string newFilePath = @"C:\NewDoc.docx";
    File.Copy(@"C:\Template.docx", newFilePath, true);

    using (WordprocessingDocument myDoc =
    WordprocessingDocument.Open(newFilePath, true))
    {
    // Add an aFChunk part to the package
    string altChunkId = "AltChunkId1";
    MainDocumentPart mainPart = myDoc.MainDocumentPart;
    AlternativeFormatImportPart chunk = mainPart
    .AddAlternativeFormatImportPart(
    AlternativeFormatImportPartType.Xhtml, altChunkId);

    // Retrieve the rich text field contents
    // and store it into the aFChunk part
    StringBuilder sb = new StringBuilder();
    sb.Append("<html>");
    sb.Append(root.SelectSingleNode(
    "//my:rtfField", NamespaceManager).InnerXml);
    sb.Append("</html>");
    string html = sb.ToString();

    using (MemoryStream ms =
    new MemoryStream(Encoding.UTF8.GetBytes(html)))
    {
    chunk.FeedData(ms);
    }

    // Add the aFChunk to the document
    AltChunk altChunk = new AltChunk();
    altChunk.Id = altChunkId;
    mainPart.Document.Body.Append(altChunk);

    // Create an empty table and specify formatting for its borders
    Table table = new Table();
    TableBorders borders = new TableBorders();

    TopBorder tb = new TopBorder();
    tb.Val = new DocumentFormat.OpenXml
    .EnumValue<BorderValues>(BorderValues.Dashed);
    tb.Size = 24;
    borders.AppendChild<TopBorder>(tb);

    BottomBorder bb = new BottomBorder();
    bb.Val = new DocumentFormat.OpenXml
    .EnumValue<BorderValues>(BorderValues.Dashed);
    bb.Size = 24;
    borders.AppendChild<BottomBorder>(bb);

    LeftBorder lb = new LeftBorder();
    lb.Val = new DocumentFormat.OpenXml
    .EnumValue<BorderValues>(BorderValues.Dashed);
    lb.Size = 24;
    borders.AppendChild<LeftBorder>(lb);

    RightBorder rb = new RightBorder();
    rb.Val = new DocumentFormat.OpenXml
    .EnumValue<BorderValues>(BorderValues.Dashed);
    rb.Size = 24;
    borders.AppendChild<RightBorder>(rb);

    InsideHorizontalBorder ihb = new InsideHorizontalBorder();
    ihb.Val = new DocumentFormat.OpenXml
    .EnumValue<BorderValues>(BorderValues.Single);
    ihb.Size = 24;
    ihb.Color = new DocumentFormat.OpenXml.StringValue("#FF0000");
    borders.AppendChild<InsideHorizontalBorder>(ihb);

    InsideVerticalBorder ivb = new InsideVerticalBorder();
    ivb.Val = new DocumentFormat.OpenXml
    .EnumValue<BorderValues>(BorderValues.Dashed);
    ivb.Size = 24;
    borders.AppendChild<InsideVerticalBorder>(ivb);

    TableProperties tblProp = new TableProperties(borders);
    table.AppendChild<TableProperties>(tblProp);

    // Loop through the repeating table and create rows in the table
    XPathNodeIterator iter = root.Select("//my:group2",
    NamespaceManager);
    while (iter.MoveNext())
    {
    string cell1 = iter.Current.SelectSingleNode(
    "my:cell1", NamespaceManager).Value;
    string cell2 = iter.Current.SelectSingleNode(
    "my:cell2", NamespaceManager).Value;
    string cell3 = iter.Current.SelectSingleNode(
    "my:cell3", NamespaceManager).Value;

    TableRow tr = createRow(cell1, cell2, cell3);
    table.Append(tr);
    }

    // Add the table to the document
    mainPart.Document.Body.Append(table);

    // Save the document
    mainPart.Document.Save();
    }

  13. Give the form Full Trust by signing it with a digital certificate.
  14. Save your work, build the project, and test the InfoPath form.

You should now have a fully functional InfoPath form so that when you type formatted text into the rich text field, add a few rows to the repeating table, and then click the button, all of this data is converted and a DOCX file containing the data is created.

Note: The Open XML Format SDK 2.0 documentation contains several example code snippets on how to construct documents.

 
 Subscribe for updates via RSS or Email

Copyright: This article may not be used on web sites (whether personal or otherwise), copied, disseminated, altered, printed, published, broadcasted, or reproduced in any way without an expressed written consent of S.Y.M. Wong-A-Ton. The techniques demonstrated in this article may be used within any Microsoft InfoPath project. This article is provided without any warranties. Copyright for this article is non-transferrable and remains with the author, S.Y.M. Wong-A-Ton.

InfoPath 2013 Cookbook: 121 Codeless Recipes for Beginners
InfoPath 2013 Cookbook 2: 121 Codeless Recipes for SharePoint 2013
InfoPath 2010 Cookbook: 101 Codeless Recipes for Beginners
InfoPath 2010 Cookbook 2: 101 Codeless Recipes for SharePoint 2010
InfoPath 2010 Cookbook 3: 101 Code Recipes for C# Developers
InfoPath 2010 Cookbook 5: Integrating InfoPath with Excel and Excel Services


Related InfoPath Articles:

ADVERTISEMENTS

InfoPath 2013 Cookbook: 121 Codeless Recipes for Beginners

InfoPath 2013 Cookbook 2: 121 Codeless Recipes for SharePoint 2013

InfoPath 2010 Cookbook: 101 Codeless Recipes for Beginners

InfoPath 2010 Cookbook 2: 101 Codeless Recipes for SharePoint 2010

InfoPath 2010 Cookbook 3: 101 Code Recipes for C# Developers

InfoPath 2010 Cookbook 4: 101 Code Recipes for VB Developers

InfoPath 2010 Cookbook 5: Integrating InfoPath with Excel and Excel Services