Erika Ehrli - Adventures with Office Products & Technologies
MSDN & TechNet: Releasing Office, SharePoint, Exchange & Lync Centers and content for developers and IT professionals.

Data-driven document generation with Word 2007 and the Office XML File Formats: Part 1

Data-driven document generation with Word 2007 and the Office XML File Formats: Part 1

Rate This
  • Comments 48

Last week I had a chance to write some interesting code samples. I missed coding a lot, and I felt a little rusty after working in different projects. But I had a lot of fun and I want to share with you one of the samples I wrote: A simple ASP.NET 2.0 solution that retrieves data from SQL Server and generates a Word 2007 document using the Office XML File formats, WinFX, and XML Mappings in Word 2007.

One of the most common requirements for applications that work with data is "data-driven document generation." No matter what the data source is -could be an Access database, SQL database, Web service, SharePoint list, Excel spreadsheet, XML file, Word document, or multiple sources. The typical "export data and create Word documents" feature is a common need.

How to do it? Two simple steps:

  1. The Word part: Create a Word 2007 document template.
  2. The Cool app part: Create an application that pulls data from a datasource and generates new documents based on the Word 2007 document template.

Word 2007 allows you to build data-driven document generation solutions. You can create a document template with a custom XML part and use Content Controls to bind to custom XML data using XML Mapping. Next, you can create a managed application to build a new document based on the template. The managed application will open the document template, retrieve data from a SQL Server database to build a new custom XML part, replace the template’s custom XML part , and save it as a new document.

This little sample will show you how to build a document template from scratch and create a server-side application that generates documents that display data stored in a SQL Server database. How did I learn to do this, well, believe it or not, I watched the following Office Dev Con session:

CD305—Word 2007 XML Programmability: Data/View Separation and Rich Eventing for Custom XML Solutions

Presenter: Tristan Davis; 59 minutes (180 MB)
In this session, we introduce new XML capabilities, then dive into the functionality of the Office XML data store and how it can be leveraged to build solutions that will strongly tie Word documents to your business processes.

..and then asked Tristan Davis some questions related with XML Mapping.

Business Scenario: Custom Customer Letter

To demonstrate how to build and Word 2007 template and connect an item in the data store to a SQL Server database, you will first build a customer letter document template with content controls that map to an XML file. Next, you will create a server-side data-driven document generation application that will allow you to select a company name to generate a custom letter. The application will retrieve customer data from a SQL Server database and use the customer letter document template to build a new document that displays customer data based on a user selection. The document will display the following information:

  • Company Name
  • Contact Name
  • Contact Title
  • Phone

To create a Word template and define the XML Mappings for each content control.

Use the following steps to create a Microsoft Office Word 2007 template.

1. Open Word 2007.

2. Create a document.

3. Create content controls to bind to a node in the data store.

What are content controls? Content controls are predefined pieces of content. There are several types of content controls, including text blocks, drop-down menus, combo boxes, calendar controls, and pictures. You can map these content controls to an element in an XML file. Using XPath expressions, you can programmatically map content in an XML file to a content control. This enables you to write a simple and short application to manipulate and modify data in a document. 

4. Set the XML mapping on the content control.

XML mapping is a feature of Word 2007 that enables you to create a link between a document and an XML file. This creates true data/view separation between the document formatting and the custom XML data.

To load a custom XML part, you must first add a new data store to a Document object by using the Add method of the CustomXMLParts collection. This appends a new, empty data store to the document. Because it is empty, you cannot use it yet. Next, you must load a custom XML part from an XML file into the data store, by calling the Load method of the CustomXMLPart object, using a valid path to an XML file as the parameter.

5. Add four plain text content controls in the following order.

  • Content control for Company Name
  • Content control for Contact Name
  • Content control for Contact Title
  • Content control for Phone

6. Save the template document as C:\CustomerLetterTemplate.docx.

To set an XML mapping on a content control

Note In this procedure, you map the content control to a sample custom XML file. You will create a valid custom XML file, save it to your hard drive, and add a data store to the document that contains the information to which you want to map.

1. Create a text file and save it as c:\CustomerData.xml.

2. Paste the following into the text file and save it: 

<?xml version="1.0"?>
<Customer>
  
<CompanyName>Alfreds Futterkiste</CompanyName>
  
<ContactName>Maria Anders</ContactName>
  
<ContactTitle>Sales Representative</ContactTitle>
  
<Phone>030-0074321</Phone>
</Customer>

3. Now, map each content control to bind to the <CompanyName>, <ContactName>, <ContactTitle>, and <Phone> and nodes of the previous custom XML part.

4. Open the Visual Basic editor and run the following VBA code to add a data store to your template document.

This sample code demonstrates how to attach an XML file to a document, so that it becomes an available data store item.

' Load CustomerData.xml file
   
ActiveDocument.CustomXMLParts.Add
   ActiveDocument.CustomXMLParts(
4).Load ("c:\CustomerData.xml")

To create an XML mapping, you use an XPath expression to the node in the custom XML data part to which you want to map a content control. After you add a data store to your document (and the data store points to a valid XML file), you are ready to map one of its nodes to a content control. To do this, pass a String containing a valid XPath to a ContentControl object by using the SetMapping method of the XMLMapping object (via the XMLMapping property of the ContentControl object).

5. Open the Visual Basic editor and run the following VBA code to bind content controls to items in the data store.

Dim strXPath1 As String
strXPath1 
"/Customer/CompanyName"
ActiveDocument.ContentControls(1).XMLMapping.SetMapping strXPath1

Dim strXPath2 As String
strXPath2 
"/Customer/ContactName"
ActiveDocument.ContentControls(2).XMLMapping.SetMapping strXPath2

Dim strXPath3 As String
strXPath3 
"/Customer/ContactTitle"
ActiveDocument.ContentControls(3).XMLMapping.SetMapping strXPath3

Dim strXPath4 As String
strXPath4 
"/Customer/Phone"
ActiveDocument.ContentControls(4).XMLMapping.SetMapping strXPath4

You have your template file and you are ready to start your document generation application. I love ASP.NET and I created a server-side application to show you how to generate documents on the server using the Office XML File Formats. You can build a document generation application using Win Forms, a console application, a shared Add-in or your preferred application depending of your business needs.

If you want to learn more about Word 2007 and document templates, read this article:

http://msdn2.microsoft.com/en-us/library/ms406053.aspx

This blog entry is too long already, so I will split it here and leave you with the intrigue of what part 2 will bring. Stay connected and you will soon know the happy ending for this walkthrough.

Enjoy,

-Erika

Leave a Comment
  • Please add 6 and 7 and type the answer here:
  • Post
  • I have used your sample to create a similar implementation in VSTO using C#. I anayone is interested i can make this available.

  • Here is a link to view a video...how to link CC to xml data files using a ready-to-use toolkit... Source code also available...pretty neat i think

    http://channel9.msdn.com/ShowPost.aspx?PostID=254539

  • Are there plans to support a datagrid (or a table) type of content control.  I need to report on a list of data and do not see an obvious way of doing this without manually writing all the code to create a table.

  • I am a php website developer, but I have to say that these tools that MS are making available are really cool... thanks for the info, I really found it quite useful.

  • I found these directions very confusing for a first-timer using Word 2007. The steps to accomplish the task are not very direct or clear. I speak as an adjunct instructor at a community college for eight years. It took me a while to find the toolbar options that would allow me to add the text controls and to open a VBA window.

    However, once I found everything, it worked like a charm.

  • We are going the way to use more XML based content. This makes us more flexible with further ideas but

  • We are going the way to use more XML based content. This makes us more flexible with further ideas but

  • I gathered a list of common Open XML questions related to programmability: What are the Open XML File

  • Category: Word programming Level: Advance Here is a small tip on how to add data to Word content control

  • Is there a possibility to select all the cc with a specific name? ... throw select i mean make them somehow visible .. showing their titles or highlighted .. this being done programmatically.

  • Hi Erika,

    I'm (very) new to Open XML (and programming altogther)and have been playing around with it for a couple of days now. I've been trying to link an external XML file to a word document, but am having some issues in doing this.

    Basically, i'll describe exactly what i'm doing and perhaps you can point me in the right direction:

    1) Create a new word 2007 document

    2) Add 3 plain text content controls from the developer tab

    3) Save the document in docx format

    4) Launch VBA Editor

    5) Enter the following code to add a custom XML part and load an XML document:

    ActiveDocument.CustomXMLParts.Add

    ActiveDocument.CustomXMLParts(3).Load ("c:\T\Data.xml")

    NB - The XML file looks like this:

    <?xml version="1.0" ?>

    <Customer>

     <CompanyName>Timothy Winters</CompanyName>

     <Location>Springfield</Location>

     <Phone>02476144524</Phone>

    </Customer>

    6) Bind the data in the XML nodes to the (previously created) content controls:

    Dim strXPath1 As String

    strXPath1 = "/Customer/CompanyName"

    ActiveDocument.ContentControls(1).XMLMapping.SetMapping strXPath1

    Dim strXPath1 As String

    strXPath1 = "/Customer/Location"

    ActiveDocument.ContentControls(2).XMLMapping.SetMapping strXPath1

    Dim strXPath1 As String

    strXPath1 = "/Customer/Phone"

    ActiveDocument.ContentControls(3).XMLMapping.SetMapping strXPath1

    7) Click 'save' in VBA Editor.

    8) No changes in the content controls!!!!

    Where am I going wrong, Erika? :( I know it's something silly, but I can't quite put my finger on it at the moment!

    I'm unsure as to whether I enter the code in steps 5  6 into the 'Immediate' window or in the 'Code' window. Do I enter step 5 first and then save? Or do I enter both sets of code at once and then save? :s

    Some assistance at grassroots level is desperately needed... :)

    Thanks in advance, Erika!

    PS You're doing a great job!!!!

    Timothy.

  • PS In step 6 above, I entered the code incorrectly on the post. It should have read:

    Dim strXPath1 As String

    strXPath1 = "/Customer/CompanyName"

    ActiveDocument.ContentControls(1).XMLMapping.SetMapping strXPath1

    Dim strXPath2 As String

    strXPath1 = "/Customer/Location"

    ActiveDocument.ContentControls(2).XMLMapping.SetMapping strXPath2

    Dim strXPath3 As String

    strXPath1 = "/Customer/Phone"

    ActiveDocument.ContentControls(3).XMLMapping.SetMapping strXPath3

    Thanks!

  • Pardon me again... i'm having a bad day! My last post should have read:

    Dim strXPath1 As String

    strXPath1 = "/Customer/CompanyName"

    ActiveDocument.ContentControls(1).XMLMapping.SetMapping strXPath1

    Dim strXPath2 As String

    strXPath2 = "/Customer/Location"

    ActiveDocument.ContentControls(2).XMLMapping.SetMapping strXPath2

    Dim strXPath3 As String

    strXPath3 = "/Customer/Phone"

    ActiveDocument.ContentControls(3).XMLMapping.SetMapping strXPath3

    Thanks!

  • There are a couple of little checks that can be done here:

    1) how many custom XML parts have you got loaded?

    ?ActiveDocument.CustomXMLParts.count

    Word will just keep adding CustomXMLParts to a document every time you save, so you may find you have loads of bad data that does not map loaded. If this is the case check the XML in each part:

    ?ActiveDocument.CustomXMLParts(4).xml

    and where your (bad) data is loaded delete it.

    ActiveDocument.CustomXMLParts(4).delete

    2) has your XML loaded?

    activedocument.ContentControls(2).XMLMapping

    Will return True or False dependent on the sucess of the mapping; perhaps a msgbox as a result of false might help. Note: there appear to be very few error messages if mapping fails, the process appears to continue and map what can be mapped.

    3) finally you have run the VBA haven't you?

    PS I added the mapping on document_open, including a global variable recording the number of the new customXMLpart.On document_close the new customXMLpart is deleted. This is of particular use where the document is used as a template.

    Cheers

    Simon

  • Once the data is in a data content control, say a simple rich text content control, how do we insert that into another part of the document. That is, how can I resuse text entered by the user within the same document?

    Kathryn

Page 2 of 4 (48 items) 1234