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 3 and 3 and type the answer here:
  • Post
  • Thanks very much for this Erika, I sincerely hope part two will deal with 'collections' as in adding a table with repeating data.  I am currently dealing with that using XSLT which is very cumbersome especially when you need to update and deploy.

    I love your posts!
  • I love this idea. One question, now that you have created the Word 2007 file on the server, what tools could you use to convert the document into a Word 2003 or XP file for download by users who haven't got Office 2007?
  • You can build a server-side application using Visual Studio to generate data-rich documents using the Office XML File Formats and  the .NET Framework 3.0 (aka Microsoft WinFX ). Here's how...
  • Edje:

    Thanks for the very nice comment :). Part 2 doesn't deal with WordML generation, it deals more with replacing a Word Content Control (placeholder) with custom xml data. To iterate a collection to add a custom table, you need to create the WordML file (document.xml part). You can use a XMLDocument or XMLTextWriter object to create a table element. I will keep in mind your request for a future blog entry :).

    Brett:
    The only tool I know of is the "Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint 2007 File Formats (Beta 2)."   You can use this tool with your current version of Office (2003 and XP only) to be able to read and write the Office XML formats. You can download the tool here:
    http://www.microsoft.com/office/preview/beta/converter.mspx
  • I've been planning to start pulling together some real world examples around the ways in which people...
  • Hi Erika!

    Great article, it helped me a lot.

    But now, i got a slight different problem:

    In my AddIn, it must be possible to add an entry to the CustomXmlPart, according to a given schema. Initially, the XML of the CustomXmlPart looks like "<MetaData></MetaData>", and by clicking some button it should become "<MetaData><Name>MySelf</Name></MetaData>". But, as the given schema I mentioned is very rich and flexible, I cannot pre-define all the fields.

    Now, I try the following:

    part = Globals.ThisAddIn.Application.ActiveDocument.CustomXMLParts.Add ("<MetaData></MetaData>", System.Reflection.Missing.Value);

    ---> The SchemaCollection of the newly created CustomXmlPart is empty.

    part.SchemaCollection.Add ("NameSpaceUri", "SchemaAlias", "(path to xsd file)", false);

    When doing the SchemaCollection.Ad, I get the following exception:

    "System.Runtime.InteropServices.COMException (0xE0041802): This schema cannot be reloaded, as the schema collection is currently in use."

    What is going wrong here? Any idea?

    Thanks

    Michael

  • Hey Michael,

    Thanks for writing.

    The CustomXMLParts.Add method allows you to add a new valid Custom XML part, what you are adding is invalid. Try doing the following:

    ActiveDocument.CustomXMLParts.Add

    ActiveDocument.CustomXMLParts(4).LoadXML ("<?xml version='1.0'?><MetaData><Name>MySelf</Name></MetaData>")

    Where 4 is the index number of the CustomXMLPart. You can add more as needed.

    If you are trying to override an existing CustomXMLPart with new nodes,the best way is using the AddNode method.

    The model is similar to DOM.

    I hope this helps,

    -Erika

  • Article submitted by: Stéphane Rodriguez This article is a tutorial for working with parts as defined...

  • Article submitted by: Stéphane Rodriguez This article is a tutorial for working with parts as defined...

  • Hi Erika,

    Nice article, though I'm afraid I am still clueless as to how to map a content control to an XML Element.

    Is there a way to do this through Word 2007? Can you guide me through the menus if possible?

    Thanks in advance.

    Akshay Dhavle

  • Akshay,

    Totally agree with you, I really dont understand why documentations are usually missing important points... IMHO its really a bit lousy.... Not everyone have the bandwidth to see the demo play...

  • Hello,

    is the mapping of Content Controls to XML only possible programatically?

    Would be glad if you can give me an answer

    (annette.ilgen(at)cataligent.com )

  • Ashkay, goodwill and Annette:

    There’s no UI to map controls to XML with one exception – SharePoint and Built-in properties are listed in the Quick Parts | Linked Properties fly out menu.

    You can map Content Controls to Custom XML parts.

    1. Using XMLMapping object (programmatically).

    2. Manually updating files inside of a document package. Here’s a great sample: http://openxmldeveloper.org/archive/2006/06/04/Mapping_Content_Controls_to_Custom_XML_Parts_using_Notepad.aspx

    3.Using the System.IO.Packaging class to programmatically manipulate the package and create the item.xml parts and the relationships.

    I promise to blog about this soon to clarify a bit more.

  • Hi Erika,

    Can you help me? I created a task pane using visual studio tools for office. This task pane have a list list of customers from a database and displays them in a grid.

    How can I mapping this information into a plain text content control?

    Thanks

    Jason

Page 1 of 4 (48 items) 1234