We often generate the invoice form as PDF format and send the customer as reference. Microsoft Crystal Report and Telerik Report are handy but expensive for small business. There are other API. Among them, I prefer iTextSharp since it is widely used and lot of examples online. You can download here. I show you how to used iTextSharp for generating PDF as below :
Our interface has textboxs and gridview for accepting and displaying Data. It has two options (Download PDF and Send PDF with email). If select the first radio and press "Create PDF" button, it downloads the PDF. Otherwise, it gets the byte array of invoice PDF in code-behind. Web interface should be as below :
First, we download the "itextsharp.dll" and add reference at web site as below:
We need the following namespace in web page as below:
Copy the following code to code-behind for class variables and data binding for gridview :
Hope this helps,
SI THU
Reference :
http://www.4guysfromrolla.com/articles/030911-1.aspx
http://www.mikesdotnetting.com/Article/86/iTextSharp-Introducing-Tables
![]() |
Invoice PDF |
![]() |
User Input Data |
We need the following namespace in web page as below:
using System.IO; using iTextSharp.text; using iTextSharp.text.pdf; using System.Data;Copy the following code into form tag for interface :
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="Order No :" Width="120px"></asp:Label>
<asp:TextBox ID="txtOrderNo" runat="server"></asp:TextBox><br/>
<asp:Label ID="Label2" runat="server" Text="Customer Name :" Width="120px"></asp:Label>
<asp:TextBox ID="txtCustomerName" runat="server">John Willion</asp:TextBox><br />
<asp:Label ID="Label3" runat="server" Text="Address :" Width="120px"></asp:Label>
<asp:TextBox ID="txtAddress" runat="server" Height="74px" TextMode="MultiLine" Width="249px">No. 123, New Panasin Street, Ramkhamkeang 24/1, Bangkapi, Bangkok, 10200.</asp:TextBox>
</div>
<div>
<asp:RadioButton ID="rdoDownload" runat="server" Checked="True" GroupName="pdf" Text="Download PDF" />
<asp:RadioButton ID="rdoSendEmail" runat="server" GroupName="pdf" Text="Send PDF with email" />
</div>
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false" Font-Names="Arial"
Font-Size="11pt" AlternatingRowStyle-BackColor="#C2D69B" HeaderStyle-BackColor="green"
AllowPaging="true" PageSize="10" OnPageIndexChanging="GridView1_PageIndexChanging">
<Columns>
<asp:BoundField ItemStyle-Width="150px" DataField="NO" HeaderText="NO" />
<asp:BoundField ItemStyle-Width="150px" DataField="ITEM" HeaderText="ITEM" />
<asp:BoundField ItemStyle-Width="150px" DataField="QUANTITY" HeaderText="QUANTITY" />
<asp:BoundField ItemStyle-Width="150px" DataField="AMOUNT" HeaderText="AMOUNT(IDR)" />
</Columns>
</asp:GridView>
</div>
<div>
<asp:Button ID="Button1" runat="server" Text="Create PDF" OnClick="Button1_Click" />
</div>
</form>
Copy the following code to code-behind for class variables and data binding for gridview :
//Class Variables string orderNo = DateTime.Now.Ticks.ToString().Substring(0, 6); string orderDate = DateTime.Now.ToString("dd MMM yyyy"); decimal totalAmtStr; string accountNo = "0123456789012"; string accountName = "John Willion"; string branch = "Phahon Yothin Branch"; string bank = "Kasikorn Bank"; // for Gridview DataTable dt = new DataTable(); protected void Page_Load(object sender, EventArgs e) { //This sample used iTextShart.dll - 4.1.6.0 // DataTable binding txtOrderNo.Text = orderNo; dt.Columns.Add("NO", Type.GetType("System.String")); dt.Columns.Add("ITEM", Type.GetType("System.String")); dt.Columns.Add("QUANTITY", Type.GetType("System.String")); dt.Columns.Add("AMOUNT", Type.GetType("System.String")); for (int i = 0; i < 10; ++i) { dt.Rows.Add(); dt.Rows[i]["NO"] = (i + 1).ToString(); dt.Rows[i]["ITEM"] = "Item " + i.ToString(); dt.Rows[i]["QUANTITY"] = (i + 1).ToString(); dt.Rows[i]["AMOUNT"] = (i + 1).ToString(); totalAmtStr += (i + 1); } //GridView GridView1.DataSource = dt; GridView1.DataBind(); }Let's create "CreatePDF()" function in code-behind as below:
protected MemoryStream CreatePDF() { // Create a Document object Document document = new Document(PageSize.A4, 70, 70, 70, 70); //MemoryStream MemoryStream PDFData = new MemoryStream(); PdfWriter writer = PdfWriter.GetInstance(document, PDFData); // First, create our fonts var titleFont = FontFactory.GetFont("Arial", 14, Font.BOLD); var boldTableFont = FontFactory.GetFont("Arial", 10, Font.BOLD); var bodyFont = FontFactory.GetFont("Arial", 10, Font.NORMAL); Rectangle pageSize = writer.PageSize; // Open the Document for writing document.Open(); //Add elements to the document here #region Top table // Create the header table PdfPTable headertable = new PdfPTable(3); headertable.HorizontalAlignment = 0; headertable.WidthPercentage = 100; headertable.SetWidths(new float[] { 4, 2, 4 }); // then set the column's __relative__ widths headertable.DefaultCell.Border = Rectangle.NO_BORDER; //headertable.DefaultCell.Border = Rectangle.BOX; //for testing headertable.SpacingAfter = 30; PdfPTable nested = new PdfPTable(1); nested.DefaultCell.Border = Rectangle.BOX; PdfPCell nextPostCell1 = new PdfPCell(new Phrase("ABC Co.,Ltd", bodyFont)); nextPostCell1.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER; nested.AddCell(nextPostCell1); PdfPCell nextPostCell2 = new PdfPCell(new Phrase("111/206 Moo 9, Ramkhamheang Road,", bodyFont)); nextPostCell2.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER; nested.AddCell(nextPostCell2); PdfPCell nextPostCell3 = new PdfPCell(new Phrase("Nonthaburi 11120", bodyFont)); nextPostCell3.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER; nested.AddCell(nextPostCell3); PdfPCell nesthousing = new PdfPCell(nested); nesthousing.Rowspan = 4; nesthousing.Padding = 0f; headertable.AddCell(nesthousing); headertable.AddCell(""); PdfPCell invoiceCell = new PdfPCell(new Phrase("INVOICE", titleFont)); invoiceCell.HorizontalAlignment = 2; invoiceCell.Border = Rectangle.NO_BORDER; headertable.AddCell(invoiceCell); PdfPCell noCell = new PdfPCell(new Phrase("No :", bodyFont)); noCell.HorizontalAlignment = 2; noCell.Border = Rectangle.NO_BORDER; headertable.AddCell(noCell); headertable.AddCell(new Phrase(orderNo, bodyFont)); PdfPCell dateCell = new PdfPCell(new Phrase("Date :", bodyFont)); dateCell.HorizontalAlignment = 2; dateCell.Border = Rectangle.NO_BORDER; headertable.AddCell(dateCell); headertable.AddCell(new Phrase(orderDate, bodyFont)); PdfPCell billCell = new PdfPCell(new Phrase("Bill To :", bodyFont)); billCell.HorizontalAlignment = 2; billCell.Border = Rectangle.NO_BORDER; headertable.AddCell(billCell); headertable.AddCell(new Phrase(txtCustomerName.Text + "\n" + txtAddress.Text, bodyFont)); document.Add(headertable); #endregion #region Items Table //Create body table PdfPTable itemTable = new PdfPTable(4); itemTable.HorizontalAlignment = 0; itemTable.WidthPercentage = 100; itemTable.SetWidths(new float[] { 10, 40, 20, 30 }); // then set the column's __relative__ widths itemTable.SpacingAfter = 40; itemTable.DefaultCell.Border = Rectangle.BOX; PdfPCell cell1 = new PdfPCell(new Phrase("NO", boldTableFont)); cell1.HorizontalAlignment = 1; itemTable.AddCell(cell1); PdfPCell cell2 = new PdfPCell(new Phrase("ITEM", boldTableFont)); cell2.HorizontalAlignment = 1; itemTable.AddCell(cell2); PdfPCell cell3 = new PdfPCell(new Phrase("QUANTITY", boldTableFont)); cell3.HorizontalAlignment = 1; itemTable.AddCell(cell3); PdfPCell cell4 = new PdfPCell(new Phrase("AMOUNT(USD)", boldTableFont)); cell4.HorizontalAlignment = 1; itemTable.AddCell(cell4); foreach (DataRow row in dt.Rows) { PdfPCell numberCell = new PdfPCell(new Phrase(row["NO"].ToString(), bodyFont)); numberCell.HorizontalAlignment = 0; numberCell.PaddingLeft = 10f; numberCell.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER; itemTable.AddCell(numberCell); PdfPCell descCell = new PdfPCell(new Phrase(row["ITEM"].ToString(), bodyFont)); descCell.HorizontalAlignment = 0; descCell.PaddingLeft = 10f; descCell.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER; itemTable.AddCell(descCell); PdfPCell qtyCell = new PdfPCell(new Phrase(row["QUANTITY"].ToString(), bodyFont)); qtyCell.HorizontalAlignment = 0; qtyCell.PaddingLeft = 10f; qtyCell.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER; itemTable.AddCell(qtyCell); PdfPCell amtCell = new PdfPCell(new Phrase(row["AMOUNT"].ToString(), bodyFont)); amtCell.HorizontalAlignment = 1; amtCell.Border = Rectangle.LEFT_BORDER | Rectangle.RIGHT_BORDER; itemTable.AddCell(amtCell); } // Table footer PdfPCell totalAmtCell1 = new PdfPCell(new Phrase("")); totalAmtCell1.Border = Rectangle.LEFT_BORDER | Rectangle.TOP_BORDER; itemTable.AddCell(totalAmtCell1); PdfPCell totalAmtCell2 = new PdfPCell(new Phrase("")); totalAmtCell2.Border = Rectangle.TOP_BORDER; //Rectangle.NO_BORDER; //Rectangle.TOP_BORDER; itemTable.AddCell(totalAmtCell2); PdfPCell totalAmtStrCell = new PdfPCell(new Phrase("Total Amount", boldTableFont)); totalAmtStrCell.Border = Rectangle.TOP_BORDER; //Rectangle.NO_BORDER; //Rectangle.TOP_BORDER; totalAmtStrCell.HorizontalAlignment = 1; itemTable.AddCell(totalAmtStrCell); PdfPCell totalAmtCell = new PdfPCell(new Phrase(totalAmtStr.ToString("#,###.00"), boldTableFont)); totalAmtCell.HorizontalAlignment = 1; itemTable.AddCell(totalAmtCell); PdfPCell cell = new PdfPCell(new Phrase("*** Please note that ABC Co., Ltd’s bank account is USD Bank Account ***", bodyFont)); cell.Colspan = 4; cell.HorizontalAlignment = 1; itemTable.AddCell(cell); document.Add(itemTable); #endregion Chunk transferBank = new Chunk("Your Bank Account:", boldTableFont); transferBank.SetUnderline(0.1f, -2f); //0.1 thick, -2 y-location document.Add(transferBank); document.Add(Chunk.NEWLINE); // Bank Account Info PdfPTable bottomTable = new PdfPTable(3); bottomTable.HorizontalAlignment = 0; bottomTable.TotalWidth = 300f; bottomTable.SetWidths(new int[] { 90, 10, 200 }); bottomTable.LockedWidth = true; bottomTable.SpacingBefore = 20; bottomTable.DefaultCell.Border = Rectangle.NO_BORDER; bottomTable.AddCell(new Phrase("Account No", bodyFont)); bottomTable.AddCell(":"); bottomTable.AddCell(new Phrase(accountNo, bodyFont)); bottomTable.AddCell(new Phrase("Account Name", bodyFont)); bottomTable.AddCell(":"); bottomTable.AddCell(new Phrase(accountName, bodyFont)); bottomTable.AddCell(new Phrase("Branch", bodyFont)); bottomTable.AddCell(":"); bottomTable.AddCell(new Phrase(branch, bodyFont)); bottomTable.AddCell(new Phrase("Bank", bodyFont)); bottomTable.AddCell(":"); bottomTable.AddCell(new Phrase(bank, bodyFont)); document.Add(bottomTable); //Approved by PdfContentByte cb = new PdfContentByte(writer); BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, true); cb = writer.DirectContent; cb.BeginText(); cb.SetFontAndSize(bf, 10); cb.SetTextMatrix(pageSize.GetLeft(300), 200); cb.ShowText("Approved by,"); cb.EndText(); //Image Singature iTextSharp.text.Image logo = iTextSharp.text.Image.GetInstance(Server.MapPath("~/Images/Bill_Gates2.png")); logo.SetAbsolutePosition(pageSize.GetLeft(300), 140); document.Add(logo); cb = new PdfContentByte(writer); bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, true); cb = writer.DirectContent; cb.BeginText(); cb.SetFontAndSize(bf, 10); cb.SetTextMatrix(pageSize.GetLeft(70), 100); cb.ShowText("Thank you for your business! If you have any questions about your order, please contact us at 800-555-NORTH."); cb.EndText(); writer.CloseStream = false; //set the closestream property // Close the Document without closing the underlying stream document.Close(); return PDFData; }Copy the following function to code-behind for downloading the Invoice PDF:
protected void DownloadPDF(System.IO.MemoryStream PDFData) { // Clear response content & headers Response.Clear(); Response.ClearContent(); Response.ClearHeaders(); Response.ContentType = "application/pdf"; Response.Charset = string.Empty; Response.Cache.SetCacheability(System.Web.HttpCacheability.Public); Response.AddHeader("Content-Disposition", string.Format("attachment;filename=Receipt-{0}.pdf", orderNo)); Response.OutputStream.Write(PDFData.GetBuffer(), 0, PDFData.GetBuffer().Length); Response.OutputStream.Flush(); Response.OutputStream.Close(); Response.End(); }Finally, copy the following code into "Button1_Click" :
protected void Button1_Click(object sender, EventArgs e)
{
if (rdoDownload.Checked)
{
DownloadPDF(CreatePDF());
}
else
{
MemoryStream ms = CreatePDF();
ms.Position = 0; //Set pointer to the beginning of the stream
byte[] PDFData = new byte[ms.Length];
ms.Read(PDFData, 0, (int)ms.Length); // get byte arrary for PDF
// Attach byte array to email here
}
}
Hope this helps,
SI THU
Reference :
http://www.4guysfromrolla.com/articles/030911-1.aspx
http://www.mikesdotnetting.com/Article/86/iTextSharp-Introducing-Tables
Yes, this would be a great solution for all invoicing issues. Try http://www.fetchflow.com/Signup/PayPal It offers a robust free level with unlimited invoicing and customers. It allows you to accept Paypal.
ReplyDeletethanks for this tutorial. Please help! I am trying to load data from my dataset into my invoice but it comes out blank every time
ReplyDeleteSorry, I reply late. Pls send me your project. I can look your code.
Deletethanks a lot its extremely good to help............
Deletethanks a lot its extremely good to help.
ReplyDeletehttp://www.odix.in/
Beginner C#, jQuery, SQL Server, ASP.NET MVC, LINQ and much more..
ReplyDeleteBeginner Programming Tutorials
This comment has been removed by the author.
ReplyDeleteNice stuff
ReplyDeleteThank you SI Thu
Rao Tran
Thanks
ReplyDeleteThanks for sharing the info, keep up the good work going.... I really enjoyed exploring your site. good resource.. best timesheet software
ReplyDeletewhat is Gridview1, it seems not to be resolvable
ReplyDeleteAsp. Net with c# invoice project send me kindly sir
ReplyDeleteThis mail I'd i2birajsodari@gmail.com
This comment has been removed by the author.
ReplyDeletegreat
ReplyDeletevery nice and useful articles thanks for sharing knowledge.
ReplyDeleteSantosh Singh
https://www.dotnetgorilla.in
This was really an interesting topic and I kinda agree with what you have mentioned here! online invoice app
ReplyDeletethank u sir.....!!!!
ReplyDelete