Monday, July 30, 2012

Export to PDF file in ASP.Net – Gridview to PDF, ASPX Page Content to PDF


Export to PDF file in ASP.Net – Gridview to PDF, ASPX Page Content to PDF

Creating data driven application is one of the most commonly done task in our day today application development. In these applications, reporting and generating reports in various formats is one of the repeated requirements we will get. Read the article Export to Excel in ASP.Net 2.0 – Gridview to Excel, DataTable to Excel which discusses some handful of techniques to export the data to excel file. Apart from excel reports, generating PDF report is one of the most common reporting requirement we will get in data driven application. Exporting data to PDF format is not a straight forward task like we do for excel file generation. To do this, we have to employ some 3rd party component or develop a component ourselves by understanding the PDF file standards.
Since, developing a component ourselves is complicated and time consuming task we can try using any free 3rd party component available in the market. In this article, we will try using one of most widely used PDF generation component called iTextSharp or iText PDF component.

According to iText PDF official site,
iText is a library that allows you to generate PDF files on the fly.
iText is an ideal library for developers looking to enhance web- and other applications with dynamic PDF document generation and/or manipulation.

In this article, we will see about,
1.      Simple PDF generation from an in-memory string or HTML string
2.      Export Page Content to PDF
3.      Export GridView control to PDF

Steps
1.      Go to Start> All Programs> Open Visual Studio 2008. Create a new test Asp.Net project. Select your familiar language, i have used C# to demonstrate in this article.
2.      Download the iText PDF component from the official site (or from here) and add it to your project through add reference dialog box.

Simple PDF generation from an in-memory String or HTML String
Sometimes, we may need to generate PDF file on the fly from a string value obtained from database, etc.
The below code will help you to do that,
protected void btnCreate_Click(object sender, EventArgs e)
    {
        string str ="I Love ASP.Net!";
        Document document = new Document();
        PdfWriter.GetInstance(document, new FileStream(@"C:\Temp\test.pdf", FileMode.Create));
        document.Open();
        Paragraph P = new Paragraph(str, FontFactory.GetFont("Arial", 10));                  
        document.Add(P);     
        document.Close();     
    }

The above code will generate a PDF file called test.pdf with the string "I Love ASP.Net!".
Note
Your service account should have proper access to the report generation path in order to save the report.

You can also add text through an object called Chunk packed inside iTextSharp.text namespace. Refer below,
protected void btnCreate_Click(object sender, EventArgs e)
    {
        string str ="I Love ASP.Net!";
        Document document = new Document();
        PdfWriter.GetInstance(document, new FileStream(@"C:\Temp\test.pdf", FileMode.Create));
        document.Open();
        Paragraph P = new Paragraph(str, FontFactory.GetFont("Arial", 10));       
        Chunk ch = new Chunk("ASP.Net is a great technology!",FontFactory.GetFont("Arial",6));       
        P.Add(ch);    
        document.Add(P);     
        document.Close();     
    }

When executed, the PDF report will look like,
Export(Generate) to PDF file in ASP.Net - Gridview to PDF, ASPX Page Content to PDF


To generate PDF file from HTML content we have to use a class called HTMLWorker available in iTextSharp.text.html namespace.
Refer the below code,
protected void btnHTMLCreate_Click(object sender, EventArgs e)
    {
        Document document = new Document();
        PdfWriter.GetInstance(document, new FileStream(@"C:\Temp\test.pdf", FileMode.Create));
        document.Open();
        string strHTML = "<B>I Love ASP.Net!</B>";
        HTMLWorker htmlWorker = new HTMLWorker(document);
        htmlWorker.Parse(new StringReader(strHTML));
        document.Close();
    }

The above code will generate PDF report by applying the HTML styles.
Refer below,
Export(Generate) to PDF file in ASP.Net - Gridview to PDF, ASPX Page Content to PDF

You have inlcude the below namespace in your page for the above codes to work.
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html;
using iTextSharp.text.html.simpleparser;

Export Page Content to PDF
At times, we may need to export the page content to a PDF report. For example, providing an option in an article site to download the article in PDF format for future reference.  Assuming, the content you want to export to PDF is inside DIV tag(dvTExt) or Panel, the below code will export the content to a PDF file.
ASPX
<div id="dvText" runat="server">
//Content goes here
</div>
CodeBehind
protected void btnExport_Click(object sender, EventArgs e)
    {
        string attachment = "attachment; filename=Article.pdf";
        Response.ClearContent();
        Response.AddHeader("content-disposition", attachment);
        Response.ContentType = "application/pdf";
        StringWriter stw = new StringWriter();
        HtmlTextWriter htextw = new HtmlTextWriter(stw);
        dvText.RenderControl(htextw);
        Document document = new Document();
        PdfWriter.GetInstance(document, Response.OutputStream);
        document.Open();
        StringReader str = new StringReader(stw.ToString());
        HTMLWorker htmlworker = new HTMLWorker(document);
        htmlworker.Parse(str);
        document.Close();
        Response.Write(document);
        Response.End();
    }  







Export GridView control to PDF
This is one of the very common requirements we will get.  To understand this, we will first bind the GridView control with the employee data fetched from the SQL express database in App_Data folder. The below code will do that.
protected void Page_Load(object sender, EventArgs e)
    {
      gvEmployee.DataSource = GetData();
      gvEmployee.DataBind();
    }
    public DataTable GetData()
    {
        SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString);
        SqlCommand com = new SqlCommand("SELECT [emp_id], [fname], [lname], [job_id], [hire_date] FROM [employee] ORDER BY [emp_id], [fname]", con);
        DataTable dt = new DataTable();
        SqlDataAdapter ada = new SqlDataAdapter(com);
        ada.Fill(dt);
        return dt;
    }
When executed we can see the employee data in our GridView control.

Generate PDF file from GridView
The below code will generate a PDf file from the GridView content.
protected void btnExport_Click(object sender, EventArgs e)
    {
        string attachment = "attachment; filename=Employee.pdf";
        Response.ClearContent();
        Response.AddHeader("content-disposition", attachment);
        Response.ContentType = "application/pdf";
        StringWriter stw = new StringWriter();
        HtmlTextWriter htextw = new HtmlTextWriter(stw);
        gvEmployee.RenderControl(htextw);
        Document document = new Document();
        PdfWriter.GetInstance(document, Response.OutputStream);
        document.Open();       
        StringReader str = new StringReader(stw.ToString());
        HTMLWorker htmlworker = new HTMLWorker(document);
        htmlworker.Parse(str);
        document.Close();
        Response.Write(document);
        Response.End();
    }

When the above code is executed, you will get the below error which ASP.Net throws for security reasons.
Control 'gvEmployee' of type 'GridView' must be placed inside a form tag with runat=server.

You have to include the below event in your page to prevent the error.
public override void VerifyRenderingInServerForm(Control control)
    {

    }

Read Export to Excel in ASP.Net 2.0 – Gridview to Excel, DataTable to Excel to know more.

Note
iTextSharp library will render the HTML styles but it may not understand some CSS styles defined in your GridView control or page content. Read this to know more on this.

Saturday, July 7, 2012