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