0

I need to generate .docx/.xlsx files in .NET from some kind of templates (for generating contracts, invoices, etc.)... I've found some information about custom XML parts in OpenXML format and binding data from this parts to document, so i can bind simply fields from my custom XML part...

My main question is - how i can bind some document part to collection in my XML? As example, i have this XML as custom XML part in my .docx document:

<Data>
  <Name>Superman</Name>
  <Collection>
    <CollectionItem>
      <Data1>1</Data1>
      <Data2>11</Data2>
    </CollectionItem>
    <CollectionItem>
      <Data1>2</Data1>
      <Data2>22</Data2>
    </CollectionItem>
    <CollectionItem>
      <Data1>3</Data1>
      <Data2>33</Data2>
    </CollectionItem>
    <CollectionItem>
      <Data1>4</Data1>
      <Data2>44</Data2>
    </CollectionItem>
  </Collection>
</Data>

And i can bind Name tag to text content control. Is it possible to make list or table and bind list item or table row to CollectionItem tag? As example i want to have next table to be generated from XML example above:

+-------------------|----------------------+
|  Header1          |     Header2          |
+-------------------|----------------------+
|  1                |     11               |
+-------------------|----------------------+
|  2                |     22               |
+-------------------|----------------------+
|  3                |     33               |
+-------------------|----------------------+
|  4                |     44               |
+-------------------|----------------------+

And second part of my question: is it possible to replace this custom XML part via .NET and OpenXML SDK, and if it is possible - how i can do this?

Anton
  • 575
  • 2
  • 7
  • 27

2 Answers2

0

There is support for repeating content controls in Word 2013 (Target namespace: http://schemas.microsoft.com/office/word/2012/wordml); see repeatingSection in [MS-DOCX]

For approaches which don't require Word 2013, Google "repeatingSection openxml sdk" or some such.

As a solution to this problem, I documented a standardised approach, and named it OpenDoPE. You can build your own support for this way of doing it using the OpenXML SDK, or you could IKVM docx4j. In essence, you need to create the table rows, and in each, make a content control bound to the corresponding entries in your collection.

JasonPlutext
  • 15,352
  • 4
  • 44
  • 84
0

You're off to the right track with the table and repeating CollectionItem child elements

  1. Create the basic XML structure.
    Only add a single CollectionItem to CollectionItems.

  2. Open your docx in Word (2013).
  3. Using the Developer tab, show the XML Mapping pane.
  4. Add your basic XML as a new Custom XML Part
  5. Select your XML part from the dropdown (it will show no name/namespace, unless you add the xmlns attribute to the root node of your XML.)

  6. Add a single row to the table you want mapped to the repeating elements.
  7. Place the cursor in the first column.

  8. In the XML Mapping pane find the Data1 node under CollectionItem
  9. Select Data1 in the XML Mapping Pane. (you have to select before right-click)
  10. Right-click Data1, select 'Insert Content Control', then an appropriate control type, like 'Plain Text'
  11. Repeat 8-10 for the 2nd column and Data2 in the XML Mapping Pane.

  12. Using the Table's Layout Tools Ribbon, Select the Row in which you've mapped Data1 & Data 2.
  13. Back in the XML Mapping Pane, first select, then right click on the CollectionItem node that is the parent of Data1 & Data2.
  14. Select Insert Repeating Section Content Control.

You are now data-bound to the CollectionItem nodes and their children. You will see a large [+] to the bottom right of each table row. Clicking this will insert a new row into the table AND a new CollectionItem element in the XML with 2 child elements: Data1 & Data2.

You can prevent in-document editing using the properties window of the content controls (select the control [need to click the tag twice, when in developer design mode] then hit properties on the Developer tab ribbon).

Then, use the SDK to open the document, find the Custom XML part you want to replace (again, good idea to put the namespace in so this is easier), then replace [xmlPart.FeedData()] with updated XML with as many child nodes as you wish. Your resulting document will have a table with those repeating elements as rows.

JoeBrockhaus
  • 2,745
  • 2
  • 40
  • 64