Generating Dynamic PDF Reports from an HTML Template Using C#

Chelsea Devereaux - Sep 30 '22 - - Dev Community

The ability to programmatically create data-bound HTML templates that are then saved as PDF files has been around in the GrapeCity Documents realm since the GrapeCity Documents V4.1 release.

Although we created a blog for the release, we felt it was high time for us to update that blog to help people further understand the power of this feature. This blog also addresses the code in the new .NET 6 space, so be sure to have the latest and greatest Microsoft Visual Studio 2022 installed and ready to go for testing!

Why use an HTML template to Convert to PDF using C#?

HTML templates are easy to use because, generally speaking, many developers have a basic understanding of HTML. This makes it very easy to create a template as no further coding is involved with creating the template. Therefore, you could utilize your UI programmers, who are very familiar with HTML, and have them set up the templates while your back-end team works on the data-binding. Once that is done, it’s a very simple few lines of C# code to bring them all together and output a PDF file for consumer consumption and/or download.

Generating documents through a template saves time and avoids possible errors. In the previous release, GcExcel introduced Excel templates. Excel templates offer the ability to create dynamic Excel & PDF reports. This article will describe how to generate PDF reports from HTML templates.

Before digging deeper into the implementation, let’s first understand how HTML templates differ from standard HTML files.

HTML vs HTML Templates

While HyperText Markup Language (HTML) is a standard markup language for pages designed to display in a web browser, HTML templates also define placeholders for containing upcoming data fields using mustache syntax. This syntax allows binding data fields to a data source and shows the data value in these placeholders.

This article demonstrates how to generate data-bound PDF files using C# .NET. Here, we'll learn how to create a valid HTML template, collect data, and make PDF documents based on the HTML template.

How Does Templating Work?

Data-bound PDF report generation is a 3-step process.

Step 1:

The first step covers the following two sub-steps:

A.) Creating an HTML Template

To generate data-bound PDF reports dynamically, GcPdf requires an HTML template. This HTML template defines the layout which the final PDF report is rendered.

B.) Accessing Data

We can use data from various data sources like DataTable, etc. The data obtained will be used to bind the HTML template created above.

Step 2:

Once the template is ready and data is accessed, bind the template to the accessed data. This is done through ‘Stubble.Core’ package.

Step 3:

Completion of step 2 outputs a bound HTML. This HTML is converted to a final PDF report through ‘GcHtmlRenderer’ class. Now that we understand how the dynamic report generation process works, let’s take a look at a real-life scenario.

Use Cases – Dynamically Generating a Product Price List using HTML Templates and Data Binding with C#

A retail corporation has a large set of products they manage. These products are commodities in one way or another, so their pricing and availability change frequently. The retailer's outlets need to access accurate lists of products, prices, and quantities of each item. To do this, it will be necessary to tie to the corporate data sources. In this case, we will use an XML file that we will say is created daily (we’re actually just using the Northwind database).

It can be difficult for a corporation to track and update product prices and lists continuously. This is where dynamic report generation, through templates, helps.

Before converting HTML to PDF using C#, the HTML template needs to be applied with simple code to bind the template with the database; GcPdf will quickly generate a separate PDF report listing pricing for the products.

Below you can see how the final product PDF price list (in a PDF report) would look:

Product list template PDF

The HTML template creation is crucial when generating any report, and the product price list is no exception. Especially when converting HTML to PDF with C#, the data will not show correctly if the template is formatted incorrectly. This all depends on the precise formatting of our HTML templates.

Let’s familiarize ourselves with creating valid HTML templates.

Creating HTML Templates for GcPdf to Bind to Data Sources Using C#

Before getting started, a valid HTML template needs to be created following the Mustache template system. Any HTML can be a valid HTML template for GcPdf as long as the proper syntax is used. Also, any other HTML or stylesheets may be used in creating these files to meet clients' needs (headers, footers, images, logos, etc.). The syntax used in the system is straightforward, requiring no complicated logic for getting object values.

To understand better, let's create an HTML template for our use case in converting it to a PDF file with C#: generating a product price list. The most crucial portion of the HTML template is the portion that includes placeholders for data. The data placeholders are where you want to show dynamically generated field values (like Product name, Supplier name).

To understand precisely how to define data fields, let's see how to show a product's ID as displayed in the final PDF report image above.

According to the report image, the values are in tabular format, where each record contains a product ID value. Therefore, we should define the table cell as:

    <tr>
      <td>{{ProductID}}</td>
    </tr>
Enter fullscreen mode Exit fullscreen mode

Similarly, we'll define other table cells. The following is the complete code set for the body in the HTML template:

   <body>
        <h1>Product Price List</h1>
        <table id='products'>
          <thead>
            <th>Product ID</th>
            <th>Description</th>
            <th>Supplier</th>
            <th>Quantity Per Unit</th>
            <th>Unit Price</th>
          </thead>
          {{#Query}}
          <tr>
            <td>{{ProductID}}</td>
            <td>{{ProductName}}</td>
            <td>{{CompanyName}}</td>
            <td>{{QuantityPerUnit}}</td>
            <td align='right'>{{UnitPrice}}</td>
          </tr>
          {{/Query}}
        </table>
      </body>
Enter fullscreen mode Exit fullscreen mode

ProductListTemplate.html

Once the HTML template is complete, with any styles appended, then the output should look like the below image:

Programmatically Creating Data-Bound PDF from HTML Template Using C#

Once the HTML template with placeholders for data is built, further implementation to convert it to a PDF with C# can be broadly categorized into:

  1. Data access
  2. Bind the HTML template to the data
  3. Convert the bound HTML to PDF format
  4. Customize the PDF

To implement these, let’s create a C# class called ‘ProductListTemplate’ with a ‘CreatePdf’ method. Since we need to import an HTML template and generate a PDF report, let’s declare this method to take two arguments, the path to the template file and the output path for the completed PDF:

    public class ProductListTemplate
    {
        public void CreatePDF(string TemplatePath, string PdfPath)
        {}
    }
Enter fullscreen mode Exit fullscreen mode
1. Accessing Data

Now we will use data from the shared database ‘GcNwind.xml’ that contains multiple tables like Categories, Products, and Orders.

As we see in the final PDF image above, data fields like ProductName, Supplier, and QuantityPerUnit are present in the final expected report. We will access the Products & Suppliers tables and join them to show only the relevant data about the product details required for our project, such as UnitPrice and Supplier.

The following C# code demonstrates the implementation of accessing the data:

    // Fetch data
    DataSet ds = new DataSet();
    ds.ReadXml(Path.Combine("Resources", "data", "GcNWind.xml"));

    DataTable dtProds = ds.Tables["Products"];
    DataTable dtSupps = ds.Tables["Suppliers"];

    var products = from prod in dtProds.Select()
                   join supp in dtSupps.Select()
                   on prod["SupplierID"] equals supp["SupplierID"]
                   orderby prod["ProductName"]
                   select new
                   {
                       ProductID = prod["ProductID"],
                       ProductName = prod["ProductName"],
                       CompanyName = supp["CompanyName"],
                       QuantityPerUnit = prod["QuantityPerUnit"],
                       UnitPrice = $"{prod["UnitPrice"]:C}"
                   };
Enter fullscreen mode Exit fullscreen mode
2. Binding HTML Template to Data Using C#

As the HTML template and the product-related data are available in a data source, we need to bind the HTML template to the data. For binding the template, we'll use Stubble.Core package and its StubbleBuilder class.

    // Bind the template to data:
    var builder = new Stubble.Core.Builders.StubbleBuilder();
    var boundTemplate = builder.Build().Render(TemplatePath, new { Query = products });
Enter fullscreen mode Exit fullscreen mode
3. Converting Bound HTML to PDF using C# and GcHtml

The final step is to generate the product price list. To convert the bound HTML that was returned through the render method in the StubbleBuilder class, we'll use the GcHtmlRenderer class with the bound HTML template string as its parameter.

However, to use the GcHtmlRenderer class, we first need to import the following namespace:

`using GrapeCity.Documents.Html;`
Enter fullscreen mode Exit fullscreen mode

We will also need to ensure that we install all appropriate platform dependent packages from the NuGet site; these packages are as follows (and fairly self-explanatory based on the name of the platform). You can download one or all of these packages depending on the systems you wish to target for deployment:

  • GrapeCity.Documents.Html - REQUIRED
  • GrapeCity.Documents.Html.Windows.X64 - For Windows deployments
  • GrapeCity.Documents.Html.Mac.X64 - For Apple/Mac deployments
  • GrapeCity.Documents.Html.Linux.X64 - For Linux deployments

GcHtmlRenderer exposes a method ‘RenderToPdf’ that converts the HTML string and creates a corresponding pdf file. With the help of this method, we will convert the bound HTML to PDF format.

    // Render the bound HTML
    using (var re = new GcHtmlRenderer(boundTemplate))
    {
        re.RenderToPdf(PdfPath};
    }
Enter fullscreen mode Exit fullscreen mode

Note: Using GcHtmlRenderer requires a GcPdf license to convert HTML to PDF. Only a PDF of up to five pages can be created without a valid license. GcHtml allows licensing a single instance of GcHtmlRenderer (using ApplyGcPdfLicenseKey method) or licensing all cases of GcHtmlRenderer (using SetGcPdfLicenseKey method).

4. Customizing the PDF

Additionally, while creating the PDF file, we can customize it programmatically using the PdfSettings class. Most items can be customized, but in this example, we will update the margins, header, and footer while converting the bound HTML template with GcHtmlRenderer.

Example: We can add the page numbers in a page header and the corporate brand name in the page footer.

This can be done through the PdfSettings class in the namespace GrapeCity.Documents.HTML. The PdfSettings can be passed to the RenderToPdf method used above.

    // Render the bound HTML
    using (var re = new GcHtmlRenderer(boundTemplate))
    {
        // PdfSettings allow to provide options for HTML to PDF conversion:
        var pdfSettings = new PdfSettings()
        {
            Margins = new Margins(0.2f, 1, 0.2f, 1),
            IgnoreCSSPageSize = true,
            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) GrapeCity, Inc. All Rights Reserved.</span>"+"<span style='float:right'>Generated on <span class='date'></span></span></div>" 
        };
        // Render the generated HTML to the pdf file path:
        re.RenderToPdf(PdfPath, pdfSettings);
    }
Enter fullscreen mode Exit fullscreen mode

This completes the ‘ProductListTemplate’ class that shows how an HTML template can generate a PDF report for listing product prices.

ProductListTemplate.cs

Now, let’s implement this and create a full-blown .NET 6 application to use the class created above to generate a price list of the products in PDF format using an HTML template.

Setting up the Application (using Visual Stuidio 2022)

1. Installation

  • 1.1 Create a new Console application.

  • 1.2 Name it ProductListTemplate (or whatever you would like)
  • 1.3 Select .NET 6.0 (Long-term Support) for the framework
  • 1.4 To add GcPdf assemblies, right-click ‘Dependencies" and select ‘Manage NuGet Packages."
  • 1.5 Under the ‘Browse’ tab, search for GrapeCity.Documents.Pdf and click Install. (as of the writing of this blog, the version should be 5.2.x.xxx)

  • Next, Follow the same steps to install GrapeCity.Documents.Html

  • Also, be sure to install one or more of the following packages depending on which system you want to target:

  • GrapeCity.Documents.Html.Windows.X64 - For Windows deployments

  • GrapeCity.Documents.Html.Mac.X64 - For Apple/Mac deployments

  • GrapeCity.Documents.Html.Linux.X64 - For Linux deployments

  • 1.6 While installing, you’ll receive two confirmation dialogs: ‘Preview Changes’ and ‘License Acceptance.' click ‘Ok’ and ‘I Agree’ respectively to continue.

2. Setup your project

  • 2.1 Add namespace

In the Program file, import the following namespace:

`using GrapeCity.Documents.Pdf;`
Enter fullscreen mode Exit fullscreen mode
  • 2.2 Creating PDF from HTML template-To get the price list of products in PDF from the HTML template, create an object of the class ‘ProductListTemplate’ we created above:
`var sample = new ProductListTemplate();`
Enter fullscreen mode Exit fullscreen mode

Now, using the ‘ProductListTemplate’ object, invoke its ‘CreatePdf’ method with the template path and expected PDF report name:

    string templatePath = File.ReadAllText(Path.Combine("Resources", "Misc", "ProductListTemplate.html"));
    string pdfPath = "ProductListTemplate.pdf";
    sample.CreatePdf(templatePath, pdfPath);
Enter fullscreen mode Exit fullscreen mode

The code above will generate a PDF listing the products' prices based on our HTML template and using C#.

The complete sample application can be downloaded here. Feel free to experiment!

You can also check the full implementation and other features of GcPdf here.

We discussed what HTML templates are, how to create them, and how these templates can be used to dynamically generate data-bound PDF reports programmatically using C#.

If you want to generate data-bound reports in PDF, try using this feature. If you have any suggestions, feel free to leave a comment below.

As always, have fun with this, and happy coding!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .