ProductListTemplate.cs
// 完毕:
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;

namespace DsPdfWeb.Demos
{
    // 此示例展示了如何呈现报告(产品列表)
    // 来自标准 NWind 示例数据库)使用 {{mustache}}
    // HTML 模板。
    // 
    // 数据查询和 HTML 格式与使用的类似
    // 在ProductList 示例中。但与该示例不同的是,这里
    // 我们使用HTML模板文件ProductListTemplate.html
    // 从资源加载,并使用 {{mustache}} 将其绑定到数据。
    // 更改模板文件(保留 {{mustache}} 绑定)
    // 可用于轻松自定义报告的外观。
    // 
    // 此示例​​使用 Stubble.Core 包来绑定数据到模板。
    // 
    // 请参阅HelloWorldHtml顶部评论中的注释
    // 有关将 GcDocs.Html 添加到项目的详细信息的示例代码。
    public class ProductListTemplate
    {
        public void CreatePDF(Stream stream)
        {
            using var ds = new DataSet();
            // 获取数据:
            ds.ReadXml(Path.Combine("Resources", "data", "DsNWind.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}"
                };

            // 加载模板 - HTML 文件,其中包含 {{mustache}} 数据引用:
            var template = File.ReadAllText(Path.Combine("Resources", "Misc", "ProductListTemplate.html"));
            // 将模板绑定到数据:
            var builder = new Stubble.Core.Builders.StubbleBuilder();
            var boundTemplate = builder.Build().Render(template, new { Query = products });

            // 创建一个用于呈现 HTML 的 GcHtmlBrowser 实例:
            using var browser = Common.Util.NewHtmlBrowser();
            // 渲染绑定的 HTML:
            using var htmlPage = browser.NewPage(boundTemplate);
            // PdfOptions 允许您提供 HTML 到 PDF 转换的选项:
            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>"
            };
            // 将生成的 HTML 渲染到临时文件:
            var tmp = Path.GetTempFileName();
            htmlPage.SaveAsPdf(tmp, pdfOptions);

            // 将创建的 PDF 从临时文件复制到目标流:
            using (var ts = File.OpenRead(tmp))
                ts.CopyTo(stream);
            // 清理:
            File.Delete(tmp);
            // 完毕:
        }
    }
}