Skip to main content Skip to footer

Generating Dynamic PDF Reports from an HTML Template Using C#

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

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

Ready to get started? Download Document Solutions for PDF today!

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, it’s easy to utilize UI programmers who are very familiar with HTML and have them set up the templates while a back-end team works on the data binding. Once that is done, it’s a straightforward 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. Document Solutions for Excel (DsExcel, formerly GcExcel) introduced Excel templates in the previous release. 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.

HTML templates
HTML templates

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 HTML Templating Work?

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

PDF report generation

Step 1:

The first step covers the following two sub-steps:

A.) Creating an HTML Template

To generate data-bound PDF reports dynamically, DsPdf requires an HTML template. This HTML template defines the layout in 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 the ‘Stubble.Core’ package.

Step 3:

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

Use Case – 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; DsPdf 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:

PDF Price List

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 DsPdf 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 DsPdf 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>

Similarly, we'll define other table cells. 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>

ProductListTemplate.html

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

Price list output

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)
    {}
}
​
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.

  using var ds = new DataSet();
  // Fetch data:
  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"],
          Supplier = supp["CompanyName"],
          QuantityPerUnit = prod["QuantityPerUnit"],
          UnitPrice = $"{prod["UnitPrice"]:C}"
      };
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.

// Load the template - HTML file with {{mustache}} data references:
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, new { Query = products });
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 create an instance of the new GcHtmlBrowser to render the HTML, then using the same class, use the SaveAsPdf method with appropriate options to save the PDF in memory before writing it out to a stream and ultimately to a file.

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

using GrapeCity.Documents.Html;

GcHtmlBrowser exposes a method, ‘NewPage', that opens/renders the HTML string in the browser, and then, using the SaveAsPdf method of the page, the PDF file will be saved. The code then cleans up by deleting the temporary file.

      // Find the local version of Edge (or Chromium), then create an instance of
      // GcHtmlBrowser that is used to render HTML:
      var browserpath = BrowserFetcher.GetSystemEdgePath();
      using var browser = new GcHtmlBrowser(browserpath);
     
      // 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) GrapeCity, 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);
      // Done.

Note: Using GcHtmlBrowser requires a DsPdf license to convert HTML to PDF. Only a PDF of up to five pages can be created without a valid license.

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 (Must use Visual Studio 2022)

  1. Installation

  • 1.1 Create a new Console application.

    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 DsPdf 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 this blog's writing, the version should be 6.0.XXX)

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

  • 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;
  • 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();

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);

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

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

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

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

data-bound reports in PDF

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!

Ready to get started? Download Document Solutions for PDF today!

comments powered by Disqus