Introducing DotNetFunda.com on mobile http://m.dotnetfunda.com ! Be with DotNetFunda.com on the go !
Go to DotNetFunda.com
Twitter TwitterLinkedIn
YouTubeGoogle
 Online : 7466 |  Welcome, Guest!   Register  Login
Home > Articles > ASP.NET > .pdf generator in .NET - Dynamically generate .pdf in ASP.NET

.pdf generator in .NET - Dynamically generate .pdf in ASP.NET

5 vote(s)
Rating: 5 out of 5
Article posted by SheoNarayan on 8/2/2010 | Views: 29926 | Category: ASP.NET | Level: Beginner red flag


This article explains how to create a .pdf document in .NET using iTextSharp. After reading this article, you should be able to dynamically export GridView into .pdf document. You should also be able to generate .pdf with some custom text and images.

Download


 Download source code for .pdf generator in .NET - Dynamically generate .pdf in ASP.NET


Introduction

Generating .pdf document on the fly is a very frequently asked feature in any of web or windows application. In this article, I shall show how to generate .pdf document using an Open Source .dll iTextSharp.

My sample page looks like below


Prerequisite

To generate the .pdf document using this article, you will need to download the Opern source .dll from http://sourceforge.net/projects/itextsharp/ and refer in your project. To refer it in your project, right click it and select "Add Reference ....". Select the .dll from hard disk and clickk OK.


Video of this article

 You can watch the video of this article at http://www.dotnetfunda.com/tutorials/videos/x72-pdf-generator-in-net--dynamically-generate-pdf-in-aspnet-.aspx

Lets start with designing the .pdf generator page in .NET

Here, I have shown

  1. How to generate .pdf from GridView dynamically on the fly
  2. Generate .pdf and download
  3. Download the .pdf with custom text
  4. Generate .pdf with image

To show this example, I have taken 4 asp:Button controls and a asp:GridView control that will bind the data from the database. My .aspx page looks like below.

<form id="form1" runat="server">

<div id="divGridView">

<asp:gridview id="GridView1" runat="server" enableviewstate="False" width="100%" BorderWidth="1"

cellpadding="4" forecolor="#333333" gridlines="None" autogeneratecolumns="false"

datakeynames="AutoId" autogeneratedeletebutton="false" EmptyDataText="No records found" >

<HeaderStyle BackColor="#507CD1" HorizontalAlign="Left" Font-Bold="True" ForeColor="White" />

<Columns>

<asp:BoundField DataField="AutoId" HeaderText="AutoId" />

<asp:TemplateField HeaderText="Edit">

<ItemTemplate>

<a href="javascript:void(0)" onclick="ShowEditBox(<%# Eval("AutoId") %>)" title="Edit">Edit</a>

</ItemTemplate>

</asp:TemplateField>

<asp:TemplateField HeaderText="Name">

<ItemTemplate>

<span id="PName<%# Eval("AutoId") %>"><%# Eval("Name") %></span>

</ItemTemplate>

</asp:TemplateField>

<asp:BoundField HeaderText="Address" DataField="Address" />

<asp:BoundField HeaderText="City" DataField="City" />

<asp:BoundField HeaderText="Phone" DataField="Phone" />

<asp:TemplateField HeaderText="Delete">

<ItemTemplate>

<span onclick="return confirm('Are you sure?')">

<a href="javascript:DeleteRecord(<%# Eval("AutoId") %>)" title="Delete"><font color="red">Delete?</font></a>

</span>

</ItemTemplate>

</asp:TemplateField>

</Columns>

</asp:gridview>

 

<asp:Label ID="lblMessage" runat="server" EnableViewState="false" />

 

<asp:Button ID="btnGen" runat="server" Text="Generate PDF Doc" OnClick="GenerateOnlyPDF" />

 

<asp:Button ID="Button1" runat="server" Text="Download PDF" OnClick="GeneratePDFAndDownload" />

 

<asp:Button ID="Button2" runat="server" Text="Download PDF with custom text" OnClick="GeneratePDFWithText" />

 

<asp:Button ID="Button3" runat="server" Text="Generate PDF with Image" OnClick="GeneratePDFwithImage" />

</div>

</form>


Do not worry about the hyperlink control have placed under GridView, here our moto is to explain the GridView data into .pdf document.

Namespaces to be used

You will have to use at least following namespaces to work for the sample provided with this article.

using System.Configuration;

using System.Data;

using System.Data.SqlClient;

using System.Collections.Generic;

using System.IO;

using System.Xml;

using iTextSharp.text;

using iTextSharp.text.pdf;

using iTextSharp.text.html.simpleparser;

In order to show the .NET .pdf generation, I have created a common function called GeneratePDF. Its code looks like below

A common GeneratePDF method

This method takes path, fileName, download and text parameters and act acordingly.

/// <summary>

/// generate the .pdf

/// </summary>

/// <param name="path">path of the document</param>

/// <param name="fileName">name of the .pdf documen</param>

/// <param name="download">is this downloadable</param>

/// <param name="text">text to place in the .pdf</param>

private void GeneratePDF(string path, string fileName, bool download, string text)

{

var document = new Document();

try

{

if (download)

{

PdfWriter.GetInstance(document, Response.OutputStream);

}

else

{

PdfWriter.GetInstance(document, new FileStream(path + fileName, FileMode.Create));

}

 

// generates the grid first

StringBuilder strB = new StringBuilder();

document.Open();

if (text.Length.Equals(0)) // export the text

{

BindMyGrid();

using (StringWriter sWriter = new StringWriter(strB))

{

using (HtmlTextWriter htWriter = new HtmlTextWriter(sWriter))

{

GridView1.RenderControl(htWriter);

}

}

}

else // export the grid

{

strB.Append(text);

}

 

// now read the Grid html one by one and add into the document object

using (TextReader sReader = new StringReader(strB.ToString()))

{

List<IElement> list = HTMLWorker.ParseToList(sReader, new StyleSheet());

foreach (IElement elm in list)

{

document.Add(elm);

}

}

}

catch (Exception ee)

{

lblMessage.Text = ee.ToString();

}

finally

{

document.Close();

}

}

Above function, first creates a new instance of the Document object (found in the iTextSharp.dll) and based on whether we want the .pdf document to be downloable or not it fires PDFWriter.GetInstance method with Response.OutputStream or the name of the file with FileMode.Create. Later, if we do not pass any text into this method, then it bind the GridView and use GridView.RenderControl method to get the GridView html and append into the StringBuilder else append the text into the StringBuilder.

Next, it reads the string int the TextReader and then loop through each element find into the string using HTMLworker.ParseToList method and add them to the document.

NOTE: In the earlier version of iTextSharp HTMLParser.Parse method used to do the work that we are doing here using TextReader and looping through all the element but unfortunately in theiTextSharp 5.0.2.0 version I couldn't find this method, so I have written this work around. If anyone finds any better way parse the HTML in iTextSharp 5.0.2.0, kindly let me know by responding this article.

At last if any error occurs write into the Label control else close the Document object in the finally block. I will be using above function to generate the document for all 3 buttons shown in the 1st picture above.

An override method that is needed to export the GridView

Below method need to keep on the page where you are writing the Export functionality in case you are trying to expor the GridView into .pdf. This is to do with the GridView.RenderControl method. Nothing much to do in this, just ensure that this method is there in your code behind page when you are rendering the GridView programmatically.

/// <summary>

/// This is needed to avoid error while exporting that GridView must be placed under Form control with runat=server

/// </summary>

/// <param name="control"></param>

public override void VerifyRenderingInServerForm(Control control)

{

}

In case you are getting "RegisterForEventValidation can only be called during Render();" error, make sure that you have kept EnableEventValidation="false" in the Page directives of the .aspx page.

Lets start seeing each method for the button placed on the page (displayed in the 1st image above) one by one.

Generating .pdf document from GridView on the fly in .NET and save to the hard disk

In order to generate the document on the fly and save into the hard disck, I have created a path and fileName string variable that stores the path and .pdf document name to be used while generating the .pdf document.

/// <summary>

/// Generate .pdf

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void GenerateOnlyPDF(object sender, EventArgs e)

{

string path = Server.MapPath("~/");

string fileName = "pdfDocument" + DateTime.Now.Ticks + ".pdf";

 

GeneratePDF(path, fileName, false, "");

}

Make sure that your page has VerifyRenderingInServerForm method explained above in your code behind page.

Generate .pdf document from GridView dynamically and download

In this method, I have passed only fileName to the GeneratePDF method and rest parameters are either default or empty as I just need to generate the .pdf and download. The GeneratePDF method generates the .pdf document and last 5 lines of code for this method force it to be downlodable.

/// <summary>

/// Generate .pdf

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void GeneratePDFAndDownload(object sender, EventArgs e)

{

string fileName = "pdfDocument" + DateTime.Now.Ticks + ".pdf";

 

GeneratePDF("", fileName, true, "");

 

Response.Clear();

Response.ContentType = "application/pdf";

Response.AddHeader("content-disposition", "attachment; filename=" + fileName);

Response.Flush();

Response.End();

}

Make sure that your page has VerifyRenderingInServerForm method explained above in your code behind page.

My generated .pdf from GridView looks like below

 

Generate .pdf dynamically in .NET with custom text and download

In this method, I have passed fileName and custom text to write in .pdf. Notice that I have passed 3rd parameter of the GeneratePDF method as true (so that this .pdf file will be forced to download). In this case, the StringBuilder of the GeneratePDF method will not have the GridView html content but the custom text we are passing, so the custom text would appear in the .pdf document.

/// <summary>

/// generate .pdf with some custom text

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void GeneratePDFWithText(object sender, EventArgs e)

{

string fileName = "pdfDocument" + DateTime.Now.Ticks + ".pdf";

string text = "<b>DotNetFunda.Com</b> is a <i>great</i> <u>resource for .NET.</u>";

 

GeneratePDF("", fileName, true, text);

 

Response.Clear();

Response.ContentType = "application/pdf";

Response.AddHeader("content-disposition", "attachment; filename=" + fileName);

Response.Flush();

Response.End();

}

 

My generated .pdf document with custom text look like below


 

Generate .pdf in .NET with image

In this method, we create an instance of Document object (from iTextSharp.dll) and then create the instance of the PdfWriter with the document object and .pdf file to be written with FileMode.Create.

First, I have added ITFunda.com as the the text in the document and then to add the image inside the .pdf, we have created the iTextSharp.text.Image object by giving the path of the image (from our hard disk) and added to the document object. This method will create a .pdf document on the hard disk at root of the application.

/// <summary>

/// generate image with some text

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void GeneratePDFwithImage(object sender, EventArgs e)

{

string path = Server.MapPath("~/");

string fileName = "pdfDocument" + DateTime.Now.Ticks + ".pdf";

Document doc = new Document();

try

{

PdfWriter.GetInstance(doc, new FileStream(path + fileName, FileMode.Create));

doc.Open();

 

// Add some text

doc.Add(new Paragraph("ITFunda.Com"));

 

// Add the image now

iTextSharp.text.Image gif = iTextSharp.text.Image.GetInstance(Server.MapPath("~/itfunda.gif"));

doc.Add(gif);

}

catch (Exception ex)

{

lblMessage.Text = ex.ToString();

}

finally

{

doc.Close();

}

}

My generated .pdf document with custom text and image looks like below

A very good article on working with images with iTextSharp is written by Mikesdotnetting, you can read it at http://www.mikesdotnetting.com/Article/87/iTextSharp-Working-with-images

Conclusion

Generating .pdf in .NET has become easier now, thanks to the team behind iTextSharp.

Hope you liked this article. Thanks for reading. Keep reading and sharing your knoweldge.

If you like this article, subscribe to our RSS Feed. You can also subscribe via email to our Interview Questions, Codes and Forums section.

Page copy protected against web site content infringement by Copyscape
Found interesting? Add this to:



Please Sign In to vote for this post.

About Sheo Narayan

Experience:8 year(s)
Home page:http://www.snarayan.com
Member since:Tuesday, July 08, 2008
Level:HonoraryPlatinum
Status: [Microsoft_MVP] [Administrator]
Biography:Microsoft MVP, Author, Writer, Mentor & architecting applications since year 2001.

Connect me on Facebook | Twitter | LinkedIn | Blog

 Responses
Posted by: Raja | Posted on: 03 Aug 2010 11:55:16 PM

Awesome tutorials, all in one like you !!!

Posted by: Basharss | Posted on: 19 Apr 2011 09:49:10 AM | Points: 25


Thank you very much, but when text = "non english langauge ????" it will create empty pdf ?

Could you help me in that please.

Posted by: Amitgodse | Posted on: 05 Jul 2011 05:58:15 AM | Points: 25

Thank you sir for this vary good article..
But sir pdf which is created is having no header column in it,its showing blank. And another problem is direct download is not working if we do that then pdf gets corrupted. Sir please reply as soon as possible my project is stucked in this module.
Thanx in advance..


Posted by: Itsmanam | Posted on: 22 Nov 2011 01:23:21 AM | Points: 25

Hi

I am getting the following Error
" Unable to cast object of type 'iTextSharp.text.html.simpleparser.CellWrapper' to type 'iTextSharp.text.Paragraph'."

i have used 'itextsharp.dll(5.1.2.0)'

please suggest some soluion

Posted by: Prabhakar | Posted on: 10 Jan 2012 07:19:31 AM | Points: 25

Hello, Sheo

sir, Article is very gud . . but i recive one error . .

A page can have only one server-side Form tag.


after all code execution . . i am fill gridview by SqlDataSource . . in all Form i am put Server tag in controls and forms . .

Posted by: Sushantaguha.Net | Posted on: 27 Feb 2012 10:15:32 AM | Points: 25

But basic problem is that if I have 30 pages in a website I have to add entire controls of 30 pages or add as documents for 30 pages individually for each page.Is there any solution which can convert "entire page as it" is with a button click


sushanta guha
sushantaguha10@gmail.com

>> Write Response - Respond to this post and get points
Related Posts

ModalPopupExtender is used to open a pop-up or to open a separate ASP.NET page as a pop-up

In this article we are going to see the fileupload without postback.. We are going to do this by using ICallbackEventHandler..

Repeater doesn't have an in-built feature of paging. But we can use paging in it by using PagedDataSource class. Let me explain it in details.

Generally GridView is used to show data in tabular format. It also provide ways to modify and delete records but currently there is no way to insert record using GridView. In this article, I shall describe an easy work around to insert record using GridView.

Creating ASP.Net Menu Control using CSS

More ...
About Us | Contact Us | The Team | Advertise | Software Development | Write for us | Testimonials | Privacy Policy | Terms of Use | Link Exchange | Members | Go Top
General Notice: If you found plagiarised (copied) contents on this page, please let us know the original source along with your correct email id (to communicate) for further action.
Copyright © DotNetFunda.Com. All Rights Reserved. Copying or mimicking the site design and layout is prohibited. Logos, company names used here if any are only for reference purposes and they may be respective owner's right or trademarks. | 5/21/2012 8:23:49 AM