Convert HTML String To PDF Via iTextSharp Library And Send As An Email Attachment

Introduction

In this article, we will see how we can convert a string of data to PDF and then send an email with an attached copy of the generated PDF.

Firstly, we can convert the string of data to PDF by using Popular Library for rendering PDF is ItextSharp. Secondly, we can attach the converted PDF file to an email and send it to the recipient by using the built-in C# Mail messages Class.

So, let's start to build our first step.

Step 1. Convert HTML String to PDF

In this step, we will first create a button that will do the rest of the work on the Click event.

Let's create the button to perform the required operation.

<asp:Button ID="btn_PDFEmail" runat="server" Text="Convert HTML to PDF and Send Email with Attachment" OnClick="btn_PDFEmail_Click" />

The UI view looks like the following.

localhost

So our front end is all set, and we need to apply the CS logic to perform the operation.

Let's start building an HTML string.

StringBuilder sb = new StringBuilder();
sb.Append("<header class='clearfix'>");
sb.Append("<h1>INVOICE</h1>");
sb.Append("<div id='company' class='clearfix'>");
sb.Append("<div>Company Name</div>");
sb.Append("<div>455 John Tower,<br /> AZ 85004, US</div>");
sb.Append("<div>(602) 519-0450</div>");
sb.Append("<div><a href='mailto:[email protected]'>[email protected]</a></div>");
sb.Append("</div>");
sb.Append("<div id='project'>");
sb.Append("<div><span>PROJECT</span> Website development</div>");
sb.Append("<div><span>CLIENT</span> John Doe</div>");
sb.Append("<div><span>ADDRESS</span> 796 Silver Harbour, TX 79273, US</div>");
sb.Append("<div><span>EMAIL</span> <a href='mailto:[email protected]'>[email protected]</a></div>");
sb.Append("<div><span>DATE</span> April 13, 2016</div>");
sb.Append("<div><span>DUE DATE</span> May 13, 2016</div>");
sb.Append("</div>");
sb.Append("</header>");
sb.Append("<main>");
sb.Append("<table>");
sb.Append("<thead>");
sb.Append("<tr>");
sb.Append("<th class='service'>SERVICE</th>");
sb.Append("<th class='desc'>DESCRIPTION</th>");
sb.Append("<th>PRICE</th>");
sb.Append("<th>QTY</th>");
sb.Append("<th>TOTAL</th>");
sb.Append("</tr>");
sb.Append("</thead>");
sb.Append("<tbody>");
sb.Append("<tr>");
sb.Append("<td class='service'>Design</td>");
sb.Append("<td class='desc'>Creating a recognizable design solution based on the company's existing visual identity</td>");
sb.Append("<td class='unit'>$400.00</td>");
sb.Append("<td class='qty'>2</td>");
sb.Append("<td class='total'>$800.00</td>");
sb.Append("</tr>");
sb.Append("<tr>");
sb.Append("<td colspan='4'>SUBTOTAL</td>");
sb.Append("<td class='total'>$800.00</td>");
sb.Append("</tr>");
sb.Append("<tr>");
sb.Append("<td colspan='4'>TAX 25%</td>");
sb.Append("<td class='total'>$200.00</td>");
sb.Append("</tr>");
sb.Append("<tr>");
sb.Append("<td colspan='4' class='grand total'>GRAND TOTAL</td>");
sb.Append("<td class='grand total'>$1,000.00</td>");
sb.Append("</tr>");
sb.Append("</tbody>");
sb.Append("</table>");
sb.Append("<div id='notices'>");
sb.Append("<div>NOTICE:</div>");
sb.Append("<div class='notice'>A finance charge of 1.5% will be made on unpaid balances after 30 days.</div>");
sb.Append("</div>");
sb.Append("</main>");
sb.Append("<footer>");
sb.Append("Invoice was created on a computer and is valid without the signature and seal.");
sb.Append("</footer>");

I am using the StringBuilder class for generating HTML string and passing it to the parser for generating PDF. Before proceeding further, add the following references.

using iTextSharp.text;
using iTextSharp.text.html.simpleparser;
using iTextSharp.text.pdf;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Web;
// Your code here...

Now let's write the code for generating in-memory PDF from HTML string.

StringReader sr = new StringReader(sb.ToString());
Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
using (MemoryStream memoryStream = new MemoryStream())
{
    PdfWriter writer = PdfWriter.GetInstance(pdfDoc, memoryStream);
    pdfDoc.Open();
    htmlparser.Parse(sr);
    pdfDoc.Close();
    byte[] bytes = memoryStream.ToArray();
    memoryStream.Close();
}

Now let's understand the Line of code. After building the string, we can read from the string as we have passed the generated string.

StringReader sr = new StringReader(sb.ToString());

We are building the PDF document with a default page size of A4 Page size.

Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);

Parse the HTML string using the HTMLWorker of Itextsharp library.

HTMLWorker htmlparser = new HTMLWorker(pdfDoc);

Use the memory stream to keep the file in memory.

using (MemoryStream memoryStream = new MemoryStream())
{
    // Your code inside this block...
}

Now we get the PDF and memory stream to create the instance and write the document. Then first open the document, parse by the html worker, and then after completing the work, close the document (dispose of the resources), managing the resource properly.

using (MemoryStream memoryStream = new MemoryStream())
{
    PdfWriter writer = PdfWriter.GetInstance(pdfDoc, memoryStream);
    pdfDoc.Open();
    htmlparser.Parse(sr);
    pdfDoc.Close();
}

Now we add the created document to the memory stream and use the bytes of it as an in-memory reference to later attach to the email.

StringReader sr = new StringReader(sb.ToString());
Document pdfDoc = new Document(PageSize.A4, 10f, 10f, 10f, 0f);
HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
using (MemoryStream memoryStream = new MemoryStream())
{
    PdfWriter writer = PdfWriter.GetInstance(pdfDoc, memoryStream);
    pdfDoc.Open();
    htmlparser.Parse(sr);
    pdfDoc.Close();
    byte[] bytes = memoryStream.ToArray();
    memoryStream.Close();
    // Now you have the PDF content in the 'bytes' array
    // You can save it to a file, send it as an email attachment, etc.
}

This is all about the first step, which will generate the PDF file, and we will later use this as an attachment.

First Output

Now let's proceed to the second step.

Step 2. Email the Generated PDF File as an attachment.

We will now use the Mail Message class to send emails with in-memory generated PDF files.

using System;
using System.Configuration;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Text;
namespace YourNamespace
{
    public class YourClass
    {
        public void SendEmailWithAttachment(byte[] pdfBytes)
        {
            // From web.config
            string fromEmail = ConfigurationManager.AppSettings["fromEmail"].ToString();
            string smtpServer = ConfigurationManager.AppSettings["SmtpServer"].ToString();
            string smtpUsername = ConfigurationManager.AppSettings["SmtpUsername"].ToString();
            string smtpPassword = ConfigurationManager.AppSettings["SmtpPassword"].ToString();
            int smtpPort = Convert.ToInt32(ConfigurationManager.AppSettings["SmtpPort"]);
            using (MemoryStream memoryStream = new MemoryStream(pdfBytes))
            {
                MailMessage mm = new MailMessage();
                mm.To.Add("recipientaddress");
                mm.From = new MailAddress(fromEmail);
                mm.Subject = "Online Request";
                mm.Body = "Thanks for your time. Please find the attached invoice";
                mm.Attachments.Add(new Attachment(memoryStream, "Invoice.pdf"));
                mm.IsBodyHtml = true;
                SmtpClient smtp = new SmtpClient();
                smtp.Host = smtpServer;
                smtp.EnableSsl = false;
                smtp.UseDefaultCredentials = false;
                smtp.Credentials = new NetworkCredential(smtpUsername, smtpPassword);
                smtp.Port = smtpPort;
                try
                {
                    smtp.Send(mm);
                }
                catch (Exception ex)
                {
                    // Handle exception or log error
                }
            }
        }
    }
}

You can use any email you receive from ID by just authorizing the account i.e, providing the network credentials. I have also used some application settings from the web. config file and use it here to get from there.

 

<configuration>
  <appSettings>
    <add key="fromEmail" value="[email protected]" />
    <add key="SmtpServer" value="smtp.gmail.com" />
  </appSettings>
</configuration>

Final Output

invoicepdf

Read more articles on C#.


Similar Articles