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.
Important
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
using System.Text;
using System.IO;
using System.Xml;
using System.Security.Cryptography;
using iTextSharp.text;
using iTextSharp.text.pdf;
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();
xmlForm.LoadXml(xml);
// Add the 'my' namespace of the form to an XmlNamespaceManager object
XmlNamespaceManager xmlNameSpaceMgr =
new XmlNamespaceManager(
new NameTable());
xmlNameSpaceMgr.AddNamespace("my",
"http://schemas.microsoft.com/office/infopath/2003/myXSD/2007-10-02T08:59:49");
// Retrieve the values of the InfoPath form fields using XPath
string name = xmlForm.SelectSingleNode("/my:myFields/my:name",
xmlNameSpaceMgr).InnerText;
string date = xmlForm.SelectSingleNode("/my:myFields/my:date",
xmlNameSpaceMgr).InnerText;
string photo = xmlForm.SelectSingleNode("/my:myFields/my:photo",
xmlNameSpaceMgr).InnerText;
XmlNodeList islands = xmlForm.SelectNodes(
"/my:myFields/my:group1/my:group2/my:island",
xmlNameSpaceMgr);
// 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())
{
PdfWriter.GetInstance(document, ms);
document.Open();
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));
document.Add(paragraph);
// Add date
paragraph = new Paragraph(15F);
paragraph.Add(new Chunk("Date: ", labelFont));
paragraph.Add(new Chunk(date, defaultFont));
document.Add(paragraph);
// Add image
if (!String.IsNullOrEmpty(photo))
{
InfoPathAttachmentDecoder dec =
new InfoPathAttachmentDecoder(photo);
byte[] attachment = dec.DecodedAttachment;
iTextSharp.text.Image image =
iTextSharp.text.Image.GetInstance(attachment);
document.Add(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++)
{
table.AddCell(new Cell(
new Chunk(islands[i].InnerText, defaultFont)));
}
document.Add(table);
document.Close();
// Return the InfoPath form as an PDF document
byte[] data = ms.ToArray();
Response.Clear();
Response.ClearHeaders();
Response.ClearContent();
Response.Buffer = true;
Response.ContentType = "application/pdf";
Response.BinaryWrite(data);
Response.End();
ms.Close();
}
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
