Generating Documents from SharePoint Lists using Open XML Content Controls
It's often the case that a department manager needs to regularly send a nicely formatted status report to her general manager or that a team leader needs to send a weekly status report to a number of interested parties. To collaborate with others in their organizations, both the manager and the team leader can maintain status information in SharePoint lists. The question for developers is how to include the information in the lists in a document such as a status report.
This blog is inactive.
New blog: EricWhite.com/blog
Blog TOCI've written an article entitled Generating Documents from SharePoint with Open XML Content Controls, published in the October issue of MSDN Magazine that details how you can put together a simple, flexible, and powerful system for generating Open XML word-processing documents using SharePoint lists as sources for data in tables of word-processing documents.
The key aspect of a successful approach is to make it so that the folks who need to generate reports can do so without involving the services of a software developer. We can adopt an approach where the user can configure the sources of data for tables in a document using content controls. The user can surround a table with a content control, and set the content control tag to the name of the SharePoint list. The user can insert content controls into cells in a nicely formatted table, and set the tags to the names of the columns of the SharePoint list. We then have enough information to retrieve the necessary data from the SharePoint list (or lists) and generate a document that contains that data. If the department manager or team leader subsequently adds a new column to their SharePoint list, they can add a new column to their table, insert a new content control, set the tag, and thereafter, their reports will contain data from the new column in the SharePoint list.
To make this clear, a typical SharePoint list looks like this:
The template Open XML word-processing document might look like the following. Notice that there is a content control surrounding the entire table, with a tag and title of "Team Members", and there is a content control in a table cell with tag and title of "TeamMemberName". If we were to put the insertion point in the Role cell, you would see that there is a content control there. There are similar content controls around and in the Current Work Items table.
The resulting generated report looks like this:
One aspect of the approach that I took is that I abstracted the operations involving the content controls into a ContentControlManager class. You can call a method, GetContentControls, which returns some XML that describes the content controls in the document. In the example that I present with the article, GetContentControls returns the following XML:
<ContentControls>
<TableName="Team Members">
<FieldName="TeamMemberName" />
<FieldName="Role" />
</Table>
<TableName="Item List">
<FieldName="ItemName" />
<FieldName="Description" />
<FieldName="EstimatedHours" />
<FieldName="AssignedTo" />
</Table>
</ContentControls>
This gives us the information that we need to use the SharePoint object model to retrieve the necessary data. After retrieving that data, we can construct a small XML tree that looks like this:
<ContentControls>
<TableName="Team Members">
<FieldName="TeamMemberName" />
<FieldName="Role" />
<Row>
<FieldName="TeamMemberName"
Value="Bob" />
<FieldName="Role"
Value="Developer" />
</Row>
<Row>
<FieldName="TeamMemberName"
Value="Susan" />
<FieldName="Role"
Value="Program Manager" />
</Row>
<Row>
<FieldName="TeamMemberName"
Value="Jack" />
<FieldName="Role"
Value="Test" />
</Row>
</Table>
<TableName="Item List">
<FieldName="ItemName" />
<FieldName="Description" />
<FieldName="EstimatedHours" />
<FieldName="AssignedTo" />
<Row>
<FieldName="ItemName"
Value="Learn SharePoint 2010" />
<FieldName="Description"
Value="This should be fun!" />
<FieldName="EstimatedHours"
Value="80" />
<FieldName="AssignedTo"
Value="All" />
</Row>
<Row>
<FieldName="ItemName"
Value="Finalize Import Module Specification" />
<FieldName="Description"
Value="Make sure to handle all document formats." />
<FieldName="EstimatedHours"
Value="35" />
<FieldName="AssignedTo"
Value="Susan" />”
</Row>
<Row>
<FieldName="ItemName"
Value="Write Test Plan" />
<FieldName="Description"
Value="Include regression testing items." />
<FieldName="EstimatedHours"
Value="20" />
<FieldName="AssignedTo"
Value="Jack" />
</Row>
</Table>
</ContentControls>
We can pass that XML to the SetContentControls method in the ContentControlManager class, which will modify the document so that the tables in the document are populated with the data from the XML. This is useful functionality in its own right, and could be used in other scenarios than generating documents from SharePoint lists.
The MSDN article contains a download that contains the ContentControlManager class, as well as the SharePoint code to populate tables with data from SharePoint lists.
Comments
Anonymous
October 20, 2009
Eric, Happened to go through your FP tutorial and then saw this post. Your work is inspirational, thank you! I was exploring this model to bring database records into Open XML without using Custom XML databindings. Are you planning to dive into nested lists or a table inside another table to show the assignments right after each team member (goes back to your Grid developer days huh?)Anonymous
October 20, 2009
The comment has been removedAnonymous
March 21, 2012
Hi Eric, I need this sample for one of my current project. But I am not able to download it. Can you look into it?Anonymous
September 09, 2014
Hi I am trying to insert the content controls in tabular format,but i am not able to achieve the controls in my word document template. Can you please elobarate it in a clear way. how to implement that controls