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-.aspxLets start with designing the .pdf generator page in .NET
Here, I have shown- How to generate .pdf from GridView dynamically on the fly
- Generate .pdf and download
- Download the .pdf with custom text
- Generate .pdf with image
<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.In order to show the .NET .pdf generation, I have created a common function called GeneratePDF. Its code looks like belowusing 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;
A common GeneratePDF method
This method takes path, fileName, download and text parameters and act acordingly.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 withResponse.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./// <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 firstStringBuilder 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 objectusing (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();}}
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.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./// <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){}
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.Make sure that your page has VerifyRenderingInServerForm method explained above in your code behind page./// <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, "");}
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.Make sure that your page has VerifyRenderingInServerForm method explained above in your code behind page./// <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();}
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, theStringBuilder 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.
My generated .pdf document with custom text and image looks like below/// <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 textdoc.Add(new Paragraph("ITFunda.Com"));// Add the image nowiTextSharp.text.Image gif = iTextSharp.text.Image.GetInstance(Server.MapPath("~/itfunda.gif"));doc.Add(gif);}catch (Exception ex){lblMessage.Text = ex.ToString();}finally{doc.Close();}}
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.
Sem comentários:
Enviar um comentário