Thursday, September 23, 2010

Populating Data to PDF Forms for Better Prints

There are often situations, when your client wants series of Print out of form with data populated dynamically. These forms are designed Official and follows a legal format. In designing, the issue which frustrates designers a lot is uneven layout in different Browsers. Same issue occurs when we want to print from a Web Page (CSS for Print) or Document (Office Word). Luckily, for that purpose we have a perfect solution, and that is PDF (Portable Document Format). PDF Format always prints same on paper as we see on the screen (like WYSIWYG). The scope of this article is to show how to utilize “iTextSharp” Tool to insert data into the fields of a PDF File. I will try to demonstrate all the necessary controls that are used in forms.


Creating PDF Form Template


Our first step will be creating a PDF form, which we will use as a Template. You will need Adobe Lifecycle Designer. For demonstration purpose, we will use one of the form templates in the Adobe Lifecycle called Order Form. Click on New and select "Based on Template" and press next. Now just keep pressing next and leave the default settings as it is until Finish. At the finish step, I had unchecked both the Email and Print button, it’s your wish if you want to keep them or not. Last, click Finish. You will end up something like this.


Now we have a nice looking form, which have all the elements we need, save the form as PDF File. So, now that we have done with PDF Form. Let's get into coding!

Implementation


Start your Visual Studio and create a new C# Website. Drag-n-Drop the PDF file we just created into the Project root.



Now we need to add the "iTextSharp" assembly to our project in order to utilize it. Click here to download the iTextSharp DLL assembly. After download, right click on the project, and click “Add Reference…” from the menu.



And then under Browse tab specify the the path of the iTextSharp DLL file.

Now open the code behind file of the Default page i.e. Default.aspx.cs and add the following code into Page_Load method.

Response.ContentType = "application/pdf";

PdfReader pdfReader = new PdfReader(Server.MapPath("~/Template.pdf"));
PdfStamper pdfStamper = new PdfStamper(pdfReader, Response.OutputStream);

AcroFields pdfFormFields = pdfStamper.AcroFields;

pdfFormFields.SetField("PODate", DateTime.Now.Date.ToShortDateString());
pdfFormFields.SetField("OrderedByCompany", "XYZ Company, Inc.");
pdfFormFields.SetField("OrderedByAddress", "XYZ Street");
pdfFormFields.SetField("OrderedByStateProvince", "XY");
pdfFormFields.SetField("OrderedByZipCode", "111");
pdfFormFields.SetField("OrderedByPhone", "111-1111-111");
pdfFormFields.SetField("OrderedByFax", "111-1111-111");
pdfFormFields.SetField("OrderedByContactName", "Mr. XYZ");

pdfFormFields.SetField("SameAsAbove", "1");

pdfFormFields.SetField("DeliverToCompanyName", "XYZ Company, Inc.");
pdfFormFields.SetField("DeliverToAddress", "XYZ Street");
pdfFormFields.SetField("DeliverToStateProv", "XY");
pdfFormFields.SetField("DeliverToZipCode", "111");
pdfFormFields.SetField("DeliverTotPhone", "111-1111-111");
pdfFormFields.SetField("DeliverToFax", "111-1111-111");
pdfFormFields.SetField("DeliverToContactName", "Mr. XYZ");

pdfFormFields.SetField("Item", "# 85351");

pdfFormFields.SetField("Description", "HTC TOUCH DIAMOND");
pdfFormFields.SetField("Quantity", "1");
pdfFormFields.SetField("UnitPrice", "300");
pdfFormFields.SetField("Amount", "300");
pdfFormFields.SetField("Subtotal", "300");
pdfFormFields.SetField("StateTaxRate", "State Tax");
pdfFormFields.SetField("StateTax", "10");
pdfFormFields.SetField("FederalTaxRate", "Federal Tax");
pdfFormFields.SetField("FederalTax", "5");
pdfFormFields.SetField("ShippingChargeRate", "Shipping");
pdfFormFields.SetField("ShippingCharge", "20");
pdfFormFields.SetField("GrandTotal", "335");

pdfFormFields.SetField("Payment", "2");
pdfFormFields.SetField("Payable", "");
pdfFormFields.SetField("CardType", "2");

pdfFormFields.SetField("CardNumber", "XXXX-XXXX-XXXX-XXXX");
pdfFormFields.SetField("ExpirationDate", DateTime.Now.Date.AddMonths(6).ToShortDateString());
pdfFormFields.SetField("CardholderName", "Mr. XYZ");

pdfStamper.FormFlattening = true;
pdfStamper.Close();


In the very first line of the code we set response type of our default page to pdf so that browser will understand and it will call Adobe Reader to render page inside the browser.

Response.ContentType = "application/pdf";

Further we open our Order Form PDF for reading through PdfReader. PdfReader in used to input PDF and PdfStamper is used for output PDF. Next we tell PdfStamper to put all the output into the Response object. Because we will be sending PDF contents as our response back to browser.

When we created the form it consists of few fields like TextBox, Checkbox, RadioButton List. Like in ASP.NET Web Forms every control has a unique id, same in a PDF form every control has a unique ID. Using AcroFields class, we will insert our values into the fields of the PDF form. We only need to know the ID of the field.

pdfFormFields.SetField("{FIELD ID}", "{FIELD VALUE}");

At last we trigger the PdfStamper to insert the content to response by closing it. And we make all the Fields read-only by enabling the Form Flattening.

pdfStamper.FormFlattening = true;
pdfStamper.Close();

Preview



Now you can print it out and it will exactly same as we see in preview.

Download Code

You can download the code here which also include iTextSharp assembly from here.

1 comment: