Archive

Archive for the ‘Import Html to other file formats’ Category

HTML to PDF in ASP.Net

March 8, 2015 Leave a comment

In this post I am going to show you how can we easily import html into pdf in asp.net without compromising UI. I was looking for an alternative of crystal reports in asp.net to generate reports without any javascript burden and complexities in developing them.

As crystal reports gives you the feature to import the report into pdf or excel. So I did some research for libraries for these file formats. Most programming folks were recommending for ITextSharp.

I knew and had used ITextSharp for pdf merge in a project. But when I tried to use this for html to pdf I didn’t get the result I wanted and there were a lot of workarounds needed to get all my requirements.

So I looked for some other solutions and fortunately I found this amazing free library NReco. Which by the way is a wrapper library in .net for this wonderful html to pdf exe wkhtmltopdf.

Before going into detail I’d like to mention my requirements when I was working on html to pdf import on a project. So it would be easier for you if it matches your requirements as well.

Requirements

  • Same PDF page as its showing on browser
  • Show Background-color
  • Repeat header on every page
  • Show page number on every page
  • Page number count on every page
  • Show images
  • Option to change page orientation (Landscape, Portrait)
  • Free library
  • Support css

Issues I encountered and resolved.

  • Header overlaps when repeating on other pages
  • Page number
  • deploying on 32bit OS.

I’ve attached the link of a sample asp.net solution at the end of source codes.

Example code;

/// <summary>
/// Converts html into PDF using nReco dll and wkhtmltopdf.exe.
/// </summary>        
private byte[] ConvertHtmlToPDF()
{
   HtmlToPdfConverter nRecohtmltoPdfObj = new HtmlToPdfConverter();
   nRecohtmltoPdfObj.Orientation = PageOrientation.Portrait;
   nRecohtmltoPdfObj.PageFooterHtml = CreatePDFFooter();
   nRecohtmltoPdfObj.CustomWkHtmlArgs = "--margin-top 35 --header-spacing 0 --margin-left 0 --margin-right 0";            
   return nRecohtmltoPdfObj.GeneratePdf(CreatePDFScript() + ShowHtml() + "</body></html>");
}

Html string sample;

        /// <summary>
        /// Returns HTML string.
        /// </summary>
        /// <remarks>Its test data. You can create html using data getting from database or whatever your data source.</remarks>
        /// <returns></returns>
        public string ShowHtml()
        {
            StringBuilder html = new StringBuilder("<table id=\"tblReport\" cellspacing=\"0\" cellpadding=\"0\" style=\"border-width: 0px; border-collapse: collapse; font-family: Tahoma; font-size: 11px; table-layout: fixed; line-height: 20px;\">" +
            "<thead>" +
                "<tr style=\"background-color: #4862A3; font-family: verdana; color: white;\">" +
                    "<th style=\"width: 200px;  text-align: center;\">Name</th>           " +
                    "<th style=\"width: 150px; text-align: center;\">Date Published</th> " +
                    "<th style=\"width: 200px;  text-align: center;\">Category</th>     " +
                    "<th style=\"width: 100px; text-align: center;\">Popularity</th>     " +
                "</tr>" +
            "</thead>" +
            "<tbody>" +
                "<tr>" +
                    "<th style=\"width: 200px; text-align: left; text-align: center;\">Domain Driven Design</th>" +
                    "<th style=\"width: 150px; text-align: left; text-align: center;\">02/05/2011</th>          " +
                    "<th style=\"width: 200px; text-align: center; text-align: center;\">Design Patterns</th>   " +
                    "<th style=\"width: 100px; text-align: left; text-align: center;\">6 out of 10</th>         " +
                "</tr>" +
                "<tr>" +
                    "<th style=\"width: 200px; text-align: left; text-align: center;\">When Not to use jQuery</th> " +
                    "<th style=\"width: 150px; text-align: left; text-align: center;\">02/05/2011</th>             " +
                    "<th style=\"width: 200px; text-align: center; text-align: center;\">jQuery in ASP.Net</th>    " +
                    "<th style=\"width: 100px; text-align: left; text-align: center;\">8 out of 10</th>            " +
                "</tr>" +
                "<tr>" +
                    "<th style=\"width: 200px; text-align: left; text-align: center;\">Programmer's evolution</th> " +
                    "<th style=\"width: 150px; text-align: left; text-align: center;\">02/05/2011</th>             " +
                    "<th style=\"width: 200px; text-align: center; text-align: center;\">General Programming</th>  " +
                    "<th style=\"width: 100px; text-align: left; text-align: center;\">4 out of 10</th>            " +
                "</tr>");
            for (int i = 0; i < 150; i++)
            {
                html.Append("<tr>" +
                    "<th style=\"width: 200px; text-align: left; text-align: center;\">Test Data</th> " +
                    "<th style=\"width: 150px; text-align: left; text-align: center;\">02/05/2011</th>             " +
                    "<th style=\"width: 200px; text-align: center; text-align: center;\">import html to pdf in asp.net</th>  " +
                    "<th style=\"width: 100px; text-align: left; text-align: center;\">4 out of 10</th>            " +
                "</tr>");
            }
            html.Append("</tbody></html>");
            return html.ToString();
        }

Creat Page number on every page with count.

private string CreatePDFScript()
        {
            return "<html><head><style>td,th{line-height:20px;} tr { page-break-inside: avoid }</style><script>function subst() {var vars={};var x=document.location.search.substring(1).split('&');for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}" +
            "var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];for(var i in x) {var y = document.getElementsByClassName(x[i]);" +
            "for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];}}</script></head><body onload=\"subst()\">";
        }

Below image is a snap of the source code. You can download sample asp.net solution here.
ClassStructure