Generate a Word document (docx) using data from an XML file / Convert XML to a Word document based on a template
Solution 1
Figured out how to use content controls to generate documents and how to populate data from an XML into content controls. I've divided this into 2 parts:
- Part 1: Create your template document for document generation
- Part 2: Use code in C# to generate documents based on template
Part 1: Create your template document for document generation
- Create a sample XML based on which you can create the Word template for document generation. Preferably start with a less complicated version to get the hang of it.
I used the following XML for testing. For testing I didn't have repeating sections, pictures etc.
<?xml version="1.0" encoding="utf-8"?>
<mydata xmlns="http://CustomDemoXML.htm">
<field1>This is the value in field1 from the XML file</field1>
<field2>This is the value in field2 from the XML file</field2>
<field3>This is the value in field3 from the XML file</field3>
</mydata>
Note 1: This is will be just a sample XML to create your Word template. XML file(s) with real data in this same format can later be applied when generating Word document(s) from the template.
Note 2: The xmlns
attribute can contain literally anything you want and it doesn't have to be a URL starting with http.
Save your sample XML file to any location so that it can be imported to the template you are about to create.
Make sure the
Developer
tab is enabled on your copy of Word [File
->Options
->Customize Ribbon
-> UnderCustomize the Ribbon
, make sureDeveloper
is selected ->OK
]. Details: How to: Show the Developer Tab on the RibbonCreate a new Word document (or use an existing Word document) which will be your template for document generation.
On the
Developer
tab, click onXML Mapping Pane
. This will open theXML Mapping Pane
on the right side of the document.On the XML Mapping Pane, select the
Custom XML Part
drop down -> Select(Add new part)
.Select the XML file that you saved on step 1 ->
Open
.On the XML Mapping Pane, select the
Custom XML Part
drop down -> Select the item with the text that was on thexmlns
attribute of the custom XML file. If you use the sample file above, it would behttp://CustomDemoXML.htm
.Add a some static text to a Word document and add a
Plain Text Content Control
next to it (on theDeveloper
tab ->Controls
section. Repeat for all fields you need to add.
For the sample XML above, I had the following Word document:
- Click on the first
Plain Text Content Control
-> On the XML Mapping Pane, right click the field you want mapped to that content control -> ClickMap to Selected Content Control
. Repeat for all the fields you want to map.
Note: Alternatively, instead of adding the Plain Text Content Control
items from the developer tab on step #8, you could right click on the field you want to map on the XML Mapping Pane -> Click Insert Content Control
-> Click Plain Text
.
Similarly, you can also add other types of controls such as checkboxes, date pickers and even repeating sections (it supports nested repeating sections too! - since Word 2013) and map data from XML to those using just native Word functionality and without any third party tools!
- Save your template document.
Part 2: Use code in C# to generate documents based on template
This uses Microsoft's recommended OpenXML SDK to generate documents using an XML file containing real data.
Build your XML file/open an existing XML file with which to generate a document from the template created above. This needs to be in the same format as the sample XML file used to create the template.
Use the OpenXML SDK to delete any
CustomXMLPart
elements from the document. This assumes no other custom XML parts are used in the document which is the case in this example. For complex scenarios, you can delete specific XML parts if needed.Use the OpenXML SDK to add a new
CustomXMLPart
based on the XML file in step#1 above.
Here is the sample code I have to "refresh"/"reload" the sample data in the template with a data from an XML file containing real data (assuming the XML file used to generate the document is already created and saved):
using System.IO;
using DocumentFormat.OpenXml.Packaging;
namespace SampleNamespace
{
public static class SampleClass
{
public static void GenerateDocument()
{
string rootPath = @"C:\Temp";
string xmlDataFile = rootPath + @"\MyNewData.xml";
string templateDocument = rootPath + @"\MyTemplate.docx";
string outputDocument = rootPath + @"\MyGeneratedDocument.docx";
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(templateDocument, true))
{
//get the main part of the document which contains CustomXMLParts
MainDocumentPart mainPart = wordDoc.MainDocumentPart;
//delete all CustomXMLParts in the document. If needed only specific CustomXMLParts can be deleted using the CustomXmlParts IEnumerable
mainPart.DeleteParts<CustomXmlPart>(mainPart.CustomXmlParts);
//add new CustomXMLPart with data from new XML file
CustomXmlPart myXmlPart = mainPart.AddCustomXmlPart(CustomXmlPartType.CustomXml);
using (FileStream stream = new FileStream(xmlDataFile, FileMode.Open))
{
myXmlPart.FeedData(stream);
}
}
}
}
}
That's it!
Solution 2
Ok, found a detailed guide on using XSLT as a template to generate the Word document here: Using XSLT and Open XML to Create a Word 2007 Document.
Looks like even though this article is for Word 2007, it works perfectly in Word 2016.
Only issue with this method is if changes are needed to the template later on, it takes a lot of effort to update the xslt file and it's not user friendly to do so since it cannot be updated in Word itself and the actual XML of the document needs to be manipulated.
On the plus side, document generation is VERY flexible with all the power available through XSL (foreach, variables, if conditions etc.)
slayernoah
SO has helped me SO much. I want to give back when I can. And I am #SOreadytohelp http://stackoverflow.com/users/1710577/slayernoah #SOreadytohelp
Updated on July 14, 2020Comments
-
slayernoah almost 4 years
I have an XML file with the data that I need to be populated on a Word document.
I need to find a way, to define a template which can be used as a base line to populate data from an XML file and create an output document.
I believe there are two ways to do this.
- Create an XSLT file which will be the "template" and use this to generate Word documents using it in conjunction with the XML file.
- Use content controls in Word to create a template document and somehow map to an XML file.
I just don't know the details on how to implement either way. Or not sure if there is another, easier way to accomplish this task.
Could someone show an example of how this can be implemented. Just a simple example would be sufficient.
I prefer C# for any coding. I am using Word 2016 but want it to be compatible from Word 2007 to Word 2016 and everything in between if possible since users will be using these versions. Thank you!
-
Dimitris.K about 4 yearsSo, where is "outputDocument" used ? It looks like you are modifying only the source "templateDocument" in Part 2.
-
Tiklu Ganguly over 3 yearsJust a quick update. Instead of using the opendoc sdk you can also add the DocumentFormat.OpenXml nuget package in your app to run the code.