Microsoft Office InfoPath 2007 extended the reach of InfoPath forms by offering the ability to fill out forms through a web browser without requiring the InfoPath client application to be installed on the users' computers. Such forms are called web-based forms and are created using browser-enabled form templates that are published to a SharePoint server running InfoPath Forms Services.
The Portable Document Format (PDF) is a popular and widely used format for sharing, displaying, and printing documents. There is a free add-in available, 2007 Microsoft Office Add-in: Microsoft Save as PDF, which integrates with the InfoPath client application to allow users to export a view from a form to PDF. You can also use the InfoPath 2007 object model to programmatically export the current view of a form to PDF. However, both these options are not available for web-based forms. This article presents a technique that will enable you to convert web-based forms to PDF and allow users to display, save, and print web-based forms as PDF documents.
[ Back To Top ]
To complete the tasks outlined in this article, you must be familiar with designing and publishing InfoPath browser-compatible form templates, writing C# code in InfoPath and Visual Studio, ASP.NET development, Windows SharePoint Services 3.0 (WSS), InfoPath Forms Services, and the topics discussed in the article Hosting the InfoPath 2007 Form Editing Environment in a Custom Web Form.
In addition, you must have the following applications installed on your computer:
• Microsoft Office InfoPath 2007
• Windows SharePoint Services 3.0
• Forms Server 2007 or Microsoft Office SharePoint Server 2007 with InfoPath Forms Services
• Microsoft Visual Studio 2005
Overview of Printing Web-based Forms to PDF
[ Back To Top ]
InfoPath forms are XML files, so to print a web-based form to PDF you must retrieve the XML of the form and convert it to PDF. Retrieving the XML of a web-based form can be a challenge since such forms are hosted in a control on a web page. A web-based form can be hosted by:
1. Using the InfoPath Forms Services web page to host the form.
2. Creating a custom ASP.NET page to host the form.
In both cases, a control named XmlFormView is used to host the form on a web page. The difference between the two methods is that while you have total control over a custom web page that you create, you do not have the same amount of control over the web page that is used by InfoPath Forms Services, since its code-behind is inaccessible to you. In addition, it is not recommended to modify files that are used by InfoPath Forms Services, since they might be overwritten by future upgrades of Forms Server or Microsoft Office SharePoint Server. It is recommended that you create your own custom ASP.NET page, which uses an XmlFormView control to host your forms.
The XmlFormView control has a property named XmlForm, which gives you a reference to the main data source of the form and allows you to retrieve the XML of the form. However, the XmlForm property can only be accessed during one of the following events of the XmlFormView control:
The NotifyHost event is suitable for setting up communication between the form and the ASP.NET page that is hosting it. To trigger the NotifyHost event, you must use the NotifyHost method of the XmlForm class in an event handler of a field on the form. You can then hook up the NotifyHost event to an event handler in the ASP.NET page, retrieve the XML of the form, and convert the XML to PDF.
The technique presented in this article uses the NotifyHost method and event to enable printing web-based forms to PDF. An overview of how this technique works is shown in Figure 1 and is discussed in more detail in subsequent sections.
Figure 1: Overview of printing a web-based form to PDF
Creating and Publishing a Browser-Compatible Form Template
[ Back To Top ]
To implement the technique discussed in this article, you must either design a new browser-compatible form template or modify an existing one. The form template shown in Figure 2 is used throughout this article. It is browser-compatible and has the Main data source shown in Figure 3. The Print to PDF button control on the form template has a Clicked event handler with the code shown in Listing 1.
Figure 2: Sample InfoPath form template
Figure 3: The Main data source of the sample InfoPath form template
Listing 1: Code for the Clicked event handler of the button control
public void btnPrintToPDF_Clicked(object sender, ClickedEventArgs e)
Since the form template contains managed code, you will have to perform an administrator-approved deployment when you publish it to a SharePoint server running InfoPath Forms Services, and browser-enable it.
For more information on designing and publishing browser-compatible form templates, see the following articles:
• Introduction to browser-compatible form templates
• Publish a form template to a server running InfoPath Forms Services
• How to: Deploy Form Templates That Contain Form Code
Creating a Custom ASP.NET Page to Host a Form Template
[ Back To Top ]
Once you have published the form template to a SharePoint server running InfoPath Forms Services, you must create a custom ASP.NET page as described in the article Hosting the InfoPath 2007 Form Editing Environment in a Custom Web Form to host the form template and then follow the instructions in "Step 2: Hooking Up the NotifyHost Event to an Event Handler" in the article How to execute JScript code from an InfoPath 2007 browser-enabled form template to hook up the NotifyHost event of the XmlFormView control to an event handler in the ASP.NET page. You must then write code in this event handler to:
3. Retrieve the XML of the form and store it in a Session variable.
4. Navigate to the ASP.NET page that prints the form to PDF.
Listing 2 shows how you can retrieve the XML of the form, store the XML in a Session variable named XMLForm, and then use the Redirect method of the Response object to navigate to the ASP.NET page that prints the form to PDF. XmlFormView1 is the name of the XmlFormView control that is hosting the InfoPath form on the ASP.NET page and XmlFormView1_NotifyHost is the name of the event handler that is hooked up to the NotifyHost event of the XmlFormView control. PrintToPDF.aspx is the name of the ASP.NET page that prints the form to PDF. In this example PrintToPDF.aspx is located in a folder named CustomPage under the root of a site.
Listing 2: Retrieving and storing the XML of a form and redirecting to a page that prints the form
protected void XmlFormView1_NotifyHost(object sender,
if (XmlFormView1 != null && XmlFormView1.XmlForm != null
&& XmlFormView1.XmlForm.MainDataSource != null)
// Retrieve the XML of the form
string xml =
// Store the XML of the form in an XmlForm Session variable
if (Session["XmlForm"] != null)
Session["XmlForm"] = xml;
// Redirect to the page that prints the form to PDF
Creating an ASP.NET Page to Print a Form to PDF
[ Back To Top ]
The same way you added the ASP.NET page to host a form in the article Hosting the InfoPath 2007 Form Editing Environment in a Custom Web Form, you can add an ASP.NET page to print a form to PDF. You do not have to add any controls to the web form, but must remember to set the EnableSessionState property of the web form to True.
The ASP.NET page that prints the form to PDF must first retrieve the XML of the form that you previously saved in the Session variable, extract data from this XML, and use the data to generate a PDF file. Please note that the Session variable is used here as a way to pass data between two web pages, that is, the page that hosts the form and the page that prints the form. You can choose to do the printing directly from the page that hosts the form, in which case you do not need to use a Session variable or a separate page to print the form to PDF.
Once you have retrieved the XML of the form, you can convert it to PDF using any suitable library that can generate PDF files. The example in this article uses a library named iTextSharp to generate a PDF file using data that is extracted from the XML of a form. To use the iTextSharp library, you must add a reference to the iTextSharp DLL to your web project. The discussion of using iTextSharp to generate PDF files is beyond the scope of this article, but you are encouraged to consult the online documentation should you want to use it in your own projects. In addition, the code to convert XML to PDF has been kept simple for clarity reasons, but with additional effort or use of another PDF library, you can produce more personalized and professional looking PDF documents.
You must import the namespaces shown in Listing 3 and use the code in Listing 4 to retrieve the XML of the form from the Session variable and then convert this XML to PDF. Place this code in the code-behind of the ASP.NET page that prints the form and replace the "my" namespace with the appropriate value for your own form template.
The code shown in Listing 4 uses the InfoPathAttachmentDecoder class described in the article How to encode and decode a file attachment programmatically by using Visual C# in InfoPath to decode the Base64 encoded string of the attachment and convert it into a byte array.
Do not forget to reset the IIS service after you have built your project so that your changes will take effect on your SharePoint server.
Listing 3: Namespaces to import
Listing 4: Code in Page_Load event handler of the ASP.NET page that prints a form to PDF
// Retrieve XML of InfoPath form from Session variable
string xml = Session["XmlForm"].ToString();
// Load XML of InfoPath form into an XmlDocument object
XmlDocument xmlForm = new XmlDocument();
// Add the 'my' namespace of the form to an XmlNamespaceManager object
XmlNamespaceManager xmlNameSpaceMgr =
// Retrieve the values of the InfoPath form fields using XPath
string name = xmlForm.SelectSingleNode("/my:myFields/my:name",
string date = xmlForm.SelectSingleNode("/my:myFields/my:date",
string photo = xmlForm.SelectSingleNode("/my:myFields/my:photo",
XmlNodeList islands = xmlForm.SelectNodes(
// Using iTextSharp to construct a PDF document
// Create a document-object
Document document = new Document(PageSize.A4);
// Create a writer that listens to the document
// and directs a XML-stream to a MemoryStream
using (MemoryStream ms = new MemoryStream())
Font defaultFont = FontFactory.GetFont(
FontFactory.HELVETICA, 10, Font.NORMAL);
Font labelFont = FontFactory.GetFont(
FontFactory.HELVETICA, 10, Font.BOLD);
// Add name
Paragraph paragraph = new Paragraph(15F);
paragraph.Add(new Chunk("Name: ", labelFont));
paragraph.Add(new Chunk(name, defaultFont));
// Add date
paragraph = new Paragraph(15F);
paragraph.Add(new Chunk("Date: ", labelFont));
paragraph.Add(new Chunk(date, defaultFont));
// Add image
InfoPathAttachmentDecoder dec =
byte attachment = dec.DecodedAttachment;
iTextSharp.text.Image image =
// Add islands
iTextSharp.text.Table table = new iTextSharp.text.Table(1);
table.Alignment = 0;
table.Cellpadding = 2F;
table.Width = 50F;
table.AddCell(new Cell(new Chunk("Islands", labelFont)));
for (int i = 0; i < islands.Count; i++)
new Chunk(islands[i].InnerText, defaultFont)));
// Return the InfoPath form as an PDF document
byte data = ms.ToArray();
Response.Buffer = true;
Response.ContentType = "application/pdf";
The PDF document shown in Figure 5 is the result of the conversion of the XML of the filled-out InfoPath form shown in Figure 4.
Figure 4: The filled-out InfoPath form in Internet Explorer
Figure 5: The generated PDF document in Internet Explorer