Document Solutions for PDF
Walkthrough / Convert HTML to PDF Report
In This Topic
    Convert HTML to PDF Report
    In This Topic

    The following walkthrough takes you through a step by step process on how to render a PDF report using Render HTML to PDF feature.

    Consider a scenario where a PDF report is to be generated regarding the products available in a supermarket. These products have been grouped into different categories like beverages, condiments, dairy products, seafood etc. The unit price and stock of each product as well as the whole category is also maintained in separate columns.

    The PDF report is generated by using a sample database for the data of products and an HTML template file which outlines the UI of the final PDF report.

    Suppose we have the following pre-requisites available using which we will render a PDF report:

      

    HTML template file

    ProductListTemplate.html
    Copy Code
    <!DOCTYPE html>
    <html>
    <head>
        <style>
            html * {
                font-family: 'Trebuchet MS', Arial, Helvetica, sans-serif !important;
            }
    
            h1 {
                color: #1a5276;
                background-color: #d2b4de;
                text-align: center;
                padding: 6px;
            }
    
            thead {
                display: table-header-group;
            }
    
            #products {
                font-family: 'Trebuchet MS', Arial, Helvetica, sans-serif;
                border-collapse: collapse;
                width: 100%;
            }
    
                #products td, #products th {
                    border: 1px solid #ddd;
                    padding: 8px;
                }
    
                #products tr:nth-child(even) {
                    background-color: #f2f2f2;
                }
    
                #products tr:hover {
                    background-color: #ddd;
                }
    
                #products th {
                    padding-top: 12px;
                    padding-bottom: 12px;
                    text-align: left;
                    background-color: #a569bd;
                    color: white;
                }
                span{
                    float:right;
                }
        </style>
    </head>
    
    <body>
    
        <h1>Products Stock Report</h1>
        <table id='products'>
            <thead>
                <tr>
                    <th>Description</th>
                    <th>Unit Price</th>
                    <th>Quantity Per Unit</th>
                </tr>
            </thead>
            {{#Query}}
            <tr>
                <th colspan="3">{{CategoryName}}   <span align='right'>Total Units in Stock: {{CategoryStockTotal}}</span></th>
            </tr>
    
            {{#ProductList}}
        <tr>
            <td>{{ProductName}}</td>
            <td align='right'>{{UnitPrice}}</td>
            <td align='right'>{{UnitsInStock}}</td>
    
        </tr>
            {{/ProductList}}
            {{/Query}}
        </table>
    </body>
    </html>
    

     

    The below image shows the output of HTML template file:

    HTML template file output

    Create a console application

    1. Create a .NET Core console application in Visual Studio and install 'DS.Documents.Pdf' package from nuget by following the steps mentioned in 'Getting Started'.
    2. Create a class file with name 'ProductListTemplate' and define a method 'CreatePdf' which would be used to convert the HTML to PDF report.

    Fetch data from XML

    1. Load the datasource XML file "GcNWind.xml" using DataSet class and read its XML schema using ReadXML method of DataSet class.
    2. Fetch the DataTable "CategoriesAndProducts" from the DataSet using DataTable class. Cast the XML data of datasource into a list and use a LINQ query to create grouped data from the data table.
      C#
      Copy Code
      using System;
      using System.IO;
      using System.Drawing;
      using System.Collections.Generic;
      using System.Data;
      using System.Linq;
      using System.Reflection;
      using GrapeCity.Documents.Pdf;
      using GrapeCity.Documents.Html;
      using Newtonsoft.Json;
      using System.Text.RegularExpressions;
      using GcPdfWeb.Samples.Common;
      
          public class ProductListTemplate
          {
              public void CreatePDF(Stream stream)
              {
                  using (var ds = new DataSet())
                  {
                      //Fetch data
                      ds.ReadXml(Path.Combine("Resources", "data", "GcNWind.xml"));
      
                      DataTable dtCPts = ds.Tables["CategoriesAndProducts"];
                      var categoryProducts =
                          from prod in dtCPts.Select()
                          group prod by prod["CategoryName"] into newGroup
                          select newGroup;
      
                      //Create grouped data, to display the product list based on Category groups
                      //and calculate the total units in stock for each category
                      List<object> lstCategory = new List<object>();
                      foreach (var nameGroup in categoryProducts)
                      {
                          List<object> lstProduct = new List<object>();
                          int TotalCategoryStock = 0;
                          foreach (var pro in nameGroup)
                          {
                              lstProduct.Add(new
                              {
                                  ProductName = pro["ProductName"].ToString(),
                                  UnitsInStock = pro["UnitsInStock"].ToString(),
                                  UnitPrice = pro["UnitPrice"].ToString()
                              });
                              TotalCategoryStock += Convert.ToInt32(pro["UnitsInStock"]);
                          }
      
                          lstCategory.Add(new
                          {
                              CategoryName = nameGroup.Key.ToString(),
                              CategoryStockTotal = TotalCategoryStock,
                              ProductList = lstProduct
                          });
                      }
                      var dataBound = new { Query = lstCategory };
      

    Bind HTML template with data

    1. Load the HTML template 'ProductListTemplate.html' using ReadAllText method of File class which reads the template file.
    2. Bind the template to datasource using the Render method of StubbleBuilder class (from the StubbleBuilder library).
    C#
    Copy Code
    var template = File.ReadAllText(Path.Combine("Resources", "Misc", "ProductListTemplate.html"));
    
        //Bind the template to data                              
        var builder = new Stubble.Core.Builders.StubbleBuilder();
        var boundTemplate = builder.Build().Render(template, dataBound);
    

    Generate PDF report

    1. Create an instance of GcHtmlBrowser class that is used to render HTML.
    2. To render the bound HTML, pass the data bound template as a parameter to the NewPage method of the browser.
    3. Define PDF options such as header and footer, for rendering HTML to PDF using the PdfOptions class.
    4. Render the generated HTML to a temporary file by using GetTempFileName method of the Path class.
    5. Create a PDF file from the rendered temporary file by using the SaveAsPdf method.
    C#
    Copy Code
    // Create an instance of GcHtmlBrowser that is used to render HTML:
    using var browser = Util.NewHtmlBrowser();
        // Render the bound HTML:
        using var htmlPage = browser.NewPage(boundTemplate);
        // PdfOptions specifies options for HTML to PDF conversion:
        var pdfOptions = new PdfOptions()
        {
            Margins = new PdfMargins(0.2f, 1, 0.2f, 1),
            PreferCSSPageSize = false,
            DisplayHeaderFooter = true,
            HeaderTemplate = "<div style='color:#1a5276; font-size:12px; width:1000px; margin-left:0.2in; margin-right:0.2in'>" +
                "<span style='float:left;'>Product Price List</span>" +
                "<span style='float:right'>Page <span class='pageNumber'></span> of <span class='totalPages'></span></span>" +
                "</div>",
            FooterTemplate = "<div style='color: #1a5276; font-size:12em; width:1000px; margin-left:0.2in; margin-right:0.2in;'>" +
                "<span>(c) MESCIUS, Inc. All Rights Reserved.</span>" +
                "<span style='float:right'>Generated on <span class='date'></span></span></div>"
        };
        // Render the generated HTML to the temporary file:
        var tmp = Path.GetTempFileName();
        htmlPage.SaveAsPdf(tmp, pdfOptions);
    
        // Copy the created PDF from the temp file to target stream:
        using (var ts = File.OpenRead(tmp))
            ts.CopyTo(stream);
        // Clean up:
        File.Delete(tmp);
    }
    

    Save PDF report

    Invoke 'CreatePdf' method to save the PDF report.

    C#
    Copy Code
    static void Main(string[] args)
    {
        var fname = "ProductListTemplate.pdf";
        Console.WriteLine($"Press ENTER to create '{fname}' in the current directory,\nor enter an alternative file name:");
        var t = Console.ReadLine();
        if (!string.IsNullOrWhiteSpace(t))
            fname = t;
        fname = Path.GetFullPath(fname);
        Console.WriteLine($"Generating '{fname}'...");
    
        var sample = new ProductListTemplate();
        using (FileStream fs = new FileStream(fname, FileMode.Create))
        {
            sample.CreatePDF(fs);
            Console.WriteLine($"Created '{fname}' successfully.");
        }
        Console.WriteLine("Press any key to exit...");
        Console.ReadKey();
    }
    

     

    The final PDF report is a multi-page report, one of whose pages is displayed below: 

     

    Multi-page Pdf file