Exercise 2: Printing a List
In this exercise you will finish the application by using a combination of the Client Object model and the Open XML 2.0 SDK for Office to create a Word document that contains list items from a selected list. This exercise requires that the OpenXML 2.0 SDK is installed.
- Using the same Windows Form application from the previous exercise, drag a new Button control to Form1. This second button will be used to create a Word document from the items in a selected list.
- Change the Text property for the Button to Print List. Change the Name property to PrintButton
- Add a reference to the OpenXML SDK 2.0 API by selecting Project » Add Reference from the Visual Studio main menu.
- In the References dialog, set a reference to DocumentFormat.OpenXML. If this does not show up on the .Net references tab, you will have to browse to the C:\Program Files (x86)\OpenXML SDK\v2.0\lib directory.
- Add another reference to WindowsBase.dll assembly by following the same steps. Again, if this does not show up on the .Net references Tab, browse to C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0 and select to set a reference to WindowsBase.dll.
- When Form1 open in Design mode, double click the Print List button to open the code window.
- Add the following statements to the top of the code module to use the Open XML 2.0 API.
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using ClientOM = Microsoft.SharePoint.Client; using DocumentFormat.OpenXml; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Wordprocessing;
Imports ClientOM = Microsoft.SharePoint.Client Imports DocumentFormat.OpenXml Imports DocumentFormat.OpenXml.Packaging Imports DocumentFormat.OpenXml.Wordprocessing
- Add the following code to the Click event of the Print List button to retrieve the columns and list items that you will need to build the document.
private void PrintButton_Click(object sender, EventArgs e) { if (ListsListBox.SelectedIndex > -1) { //Context using (ClientOM.ClientContext ctx = new ClientOM.ClientContext(UrlTextBox.Text)) { //Get selected list string listTitle = ListsListBox.SelectedItem.ToString(); ClientOM.Web site = ctx.Web; ctx.Load(site,s => s.Lists.Where(l => l.Title == listTitle)); ctx.ExecuteQuery(); ClientOM.List list = site.Lists[0]; //Get fields for this list ctx.Load(list,l => l.Fields.Where(f => f.Hidden == false && (f.CanBeDeleted == true || f.InternalName == "Title"))); ctx.ExecuteQuery(); //Get items for the list ClientOM.ListItemCollection listItems = list.GetItems(ClientOM.CamlQuery.CreateAllItemsQuery()); ctx.Load(listItems); ctx.ExecuteQuery(); // DOCUMENT CREATION CODE GOES HERE } MessageBox.Show("Document Created!"); } }
Private Sub PrintButton_Click(ByVal sender As Object, ByVal e As EventArgs) _ Handles PrintButton.Click If ListsListBox.SelectedIndex > -1 Then 'Context Using ctx As New ClientOM.ClientContext(UrlTextBox.Text) 'Get selected list Dim listTitle As String = ListsListBox.SelectedItem.ToString() Dim site As ClientOM.Web = ctx.Web ctx.Load(site, Function(s) s.Lists.Where(Function(l) l.Title = listTitle)) ctx.ExecuteQuery() Dim list As ClientOM.List = site.Lists(0) 'Get fields for this list ctx.Load(list, Function(l)l.Fields.Where(Function(f) f.Hidden = False _ AndAlso (f.CanBeDeleted = True _ OrElse f.InternalName = "Title"))) ctx.ExecuteQuery() 'Get items for the list Dim listItems As ClientOM.ListItemCollection =list.GetItems(ClientOM.CamlQuery.CreateAllItemsQuery()) ctx.Load(listItems) ctx.ExecuteQuery() ' DOCUMENT CREATION CODE GOES HERE End Using MessageBox.Show("Document Created!") End If End Sub
The Open XML formats use a set of XML documents to represent all of the components of an Office 2007 document. These components are referred to as “parts”. Parts are designated through content type URI’s (not to be confused with SharePoint content types!). So, the process of creating a Word document involves the proper creation and packaging of the required “parts”. The OpenXML 2.0 SDK makes it easier to create these parts because it provides strongly-types objects from which you can build a document. The document you will create will contain a table with columns for each field in the list.
- Add the following code into your project to build the document.
private void PrintButton_Click(object sender, EventArgs e) { ... ctx.Load(list.Items); ctx.ExecuteQuery(); //Create the document using (WordprocessingDocument package = WordprocessingDocument.Create("c:\\" + istsListBox.SelectedItem.ToString() + ".docx", WordprocessingDocumentType.Document)) { Body body = new Body(); Table table = new Table(); //Columns TableRow colRow = new TableRow(); foreach (ClientOM.Field field in list.Fields) { TableCell colCell = new TableCell(); colCell.Append(new Paragraph(new Run(new Text(field.Title)))); colRow.Append(colCell); } table.Append(colRow); //Rows foreach (ClientOM.ListItem item in listItems) { TableRow dataRow = new TableRow(); foreach(ClientOM.Field field in list.Fields) { TableCell dataCell = new TableCell(); string dataVal = string.Empty; try { dataVal =item[field.InternalName].ToString(); } catch{ dataVal = "-"; } dataCell.Append(new Paragraph(new Run(new Text(dataVal)))); dataRow.Append(dataCell); } table.Append(dataRow); } body.Append(table); //Build document package package.AddMainDocumentPart(); package.MainDocumentPart.Document = new Document(body); package.MainDocumentPart.Document.Save(); package.Close(); } } MessageBox.Show("Document Created!"); } }
Private Sub PrintButton_Click(ByVal sender As Object, ByVal e As EventArgs) Handles PrintButton.Click ctx.Load(list.Items) ctx.ExecuteQuery() ' DOCUMENT CREATION CODE GOES HERE 'Create the document Using package As WordprocessingDocument = WordprocessingDocument.Create("c:\" + ListsListBox.SelectedItem.ToString() & ".docx", WordprocessingDocumentType.Document) Dim body As New Body() Dim table As New Table() 'Columns Dim colRow As New TableRow() For Each field As ClientOM.Field In list.Fields Dim colCell As New TableCell() colCell.Append(New Paragraph(New Run(New Text(field.Title)))) colRow.Append(colCell) Next table.Append(colRow) 'Rows For Each item As ClientOM.ListItem In listItems Dim dataRow As New TableRow() For Each field As ClientOM.Field In list.Fields Dim dataCell As New TableCell() Dim dataVal As String = String.Empty Try dataVal = item(field.InternalName).ToString() Catch dataVal = "-" End Try dataCell.Append(New Paragraph(New Run(New Text(dataVal)))) dataRow.Append(dataCell) Next table.Append(dataRow) Next body.Append(table) 'Build document package package.AddMainDocumentPart() package.MainDocumentPart.Document = New Document(body) package.MainDocumentPart.Document.Save() package.Close() End Using End Using MessageBox.Show("Document Created!") End If End Sub
- Once you have finished coding, verify that the project compiles and starts it in Visual Studio by building and running it [Ctrl] + [F5]. You should be able to enter a URL for a site and retrieve the lists for the site. Then select a list from the site and print it. A new Word document will appear in the root of the C:\ drive having a name that is the title of the selected list.(Note: as we do not have much data on this site, the documents created will likewise not have much data in them. One list that has a couple of entries on it is the Web Part Gallery, if you wish to see some data in your word document try selecting this one to Print)
In this exercise you added code to the existing Windows Forms application that prints the contents of a SharePoint list to a Word document using the OpenXML 2.0 SDK.