Search
Sponsor
Winners

Win Prizes

Social Presence
Twitter Twitter LinkedIn YouTube Google

Like us on Facebook
Advertisements
Top Articles Author
Fri, 28-Nov-2014 Authors
All Time Authors
Sourav.Kayal
39750
SheoNarayan
38050
Niladri.biswas
33350

Latest members | More ...


(Statistics delayed by 5 minutes)
Ads
 Article

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

SheoNarayan
Posted by under ASP.NET category on for Beginner level | Views : 223303 red flag
If you found plagiarised (copied) or inappropriate content,
please let us know the original source along with your correct email id (to communicate) for further action.
Rating: 5 out of 5
7 vote(s)
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 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.

Page copy protected against web site content infringement by Copyscape
About the Author

SheoNarayan

Full Name: Sheo Narayan
Member Level: HonoraryPlatinum
Member Status: Microsoft_MVP,Administrator
Member Since: 7/8/2008 6:32:14 PM
Country: India
Regards, Sheo Narayan http://www.dotnetfunda.com
http://www.snarayan.com

Microsoft MVP, Author, Writer, Mentor & architecting applications since year 2001. Connect me on http://www.facebook.com/sheo.narayan | https://twitter.com/sheonarayan | http://www.linkedin.com/in/sheonarayan
Login to vote for this post.
Found interesting? Add this to:


Comments or Responses

Posted by: Raja on: 8/3/2010

Awesome tutorials, all in one like you !!!

Posted by: Basharss on: 4/19/2011 | 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 on: 7/5/2011 | 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 on: 11/22/2011 | 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 on: 1/10/2012 | 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 on: 2/27/2012 | 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

Posted by: Heinserdiaz on: 6/2/2012 | Points: 25

@Itsmanam, I have the same problem as you. Did you solve it? How?

Posted by: Amitkpatel on: 6/25/2012 | Points: 25

good one...

Posted by: Mahesh_Chs on: 7/18/2012 | Points: 25

Thank you sir ,
How can i open the pdf file in the new tab of a browser

Posted by: Bhanubysani on: 11/29/2012 | Points: 25

Hi Sheo,

I am exporting a gridview to pdf using above code in webpart,in webpart or usercontrol i am not able to write
public override void VerifyRenderingInServerForm(Control control)

{

}

so i used htmlform like this

using (StringWriter sWriter = new StringWriter(strB))
{
using (HtmlTextWriter htWriter = new HtmlTextWriter(sWriter))
{
using (HtmlForm frm = new HtmlForm())
{
GridView1.Parent.Controls.Add(frm);
frm.Attributes["runat"] = "server";
frm.Controls.Add(GridView1);
frm.RenderControl(htWriter);
// GridView1.RenderControl(htWriter);
}
}
}


After exporting to PDF some unwanted headers are adding which are not required above and below of the content.I followed different URLs.some of the codes are working good in asp.net webpages.
Because in that pages i am able to write the below method which i can't write in webpart or usercontrol.

Please find this attachment,please help me.This type of headers are adding above and below the code. I think this is top and bottom of the page.i am not sure about that.

//var theForm = document.forms['aspnetForm']; if (!theForm) { theForm = document.aspnetForm; } function
__doPostBack(eventTarget, eventArgument) { if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget; theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit(); } } ////var MSOWebPartPageFormName = 'aspnetForm'; var g_presenceEnabled = true;
var g_wsaEnabled = false; var g_wsaLCID = 1033; var g_wsaSiteTemplateId = 'STS#0'; var
g_wsaListTemplateId = 850; var _fV4UI=true;var _spPageContextInfo = {webServerRelativeUrl: "\u002f",
webLanguage: 1033, currentLanguage: 1033, webUIVersion:4,pageListId:"{12e3d35a-1bde-402c-910af18ab0398d16}",
pageItemId:1,userId:2, alertsEnabled:true, siteServerRelativeUrl: "\u002f",
allowSilverlightPrompt:'True'};////var dlc_fvsi = {"DefaultViews":[],"ViewUrls":[],"WebUrl":"\/"};////function
_spNavigateHierarchy(nodeDiv, dataSourceId, dataPath, url, listInContext, type) {
CoreInvoke('ProcessDefaultNavigateHierarchy', nodeDiv, dataSourceId, dataPath, url, listInContext, type,
document.forms.aspnetForm, "", "\u002fPages\u002fReportTool.aspx"); } ////function WebForm_OnSubmit()
{ UpdateFormDigest('\u002f', 1440000); return true; } //


Please help me getting this.

Thanks in advacne.

Bhanu

Posted by: Khushib on: 1/5/2013 | Points: 25

Hello ,this is good
but i have some query what else if i want export

Posted by: Khushib on: 1/5/2013 | Points: 25

Hello ,this is good
but i have some query what else if i want export selected portion of my page and grid view without edit and delete button
plz reply

Posted by: Abcd123 on: 10/4/2013 | Points: 25

Great code!! thank you for the input.. i was searching for a similar code...
I need some modifications on this ..Cna u help me plz.

my requirement is , the button to download is on one page which passes a parameter to another aspx page where my report format is predefined and values will be printed onto that based on the input parameter.
Now this aspx page is openend when i click on the download button

I need the same page as pdf on the button click as download without openeing the same..please urgent


Posted by: 9033387989 on: 11/13/2013 | Points: 25

i found this error while debug the code ,

"Unable to cast object of type 'iTextSharp.text.html.simpleparser.CellWrapper' to type 'iTextSharp.text.Paragraph'."

Please sir help me ..

Login to post response

Comment using Facebook(Author doesn't get notification)