HtmlSettings.cs
// 完毕:
using System;
using System.IO;
using System.Drawing;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Html;

namespace DsPdfWeb.Demos
{
    // 此示例演示如何呈现由 URL 指定的网页
    // PDF。这里我们渲染 WordIndex 示例的 C# 源代码。
    // 与HtmlRenderPage0类似,本示例直接使用GcHtmlRenderer,
    // 但展示了如何指定页面方向、边距等选项,
    // 页眉和页脚。
    // 
    // 作为参考,可以在以下标记扩展中使用
    // 标头和标题模板(本示例中使用了除标题之外的所有模板):
    // - <span class="date"> - 格式化日期
    // - <span class="title"> - 文档标题
    // - <span class="url"> - 文档位置
    // - <span class="pageNumber"> - 当前页码
    // - <span class="totalPages"> - 总页数
    // 
    // 请注意,在页眉/页脚中,图像不能指定为链接,
    // 但如本示例所示,支持 Base64 编码数据。
    // 
    // 另请注意,要在页眉/页脚中显示背景颜色,
    // 应指定以下 webkit CSS 扩展:
    // -webkit-打印颜色-调整:精确;
    // 
    // 请参阅HelloWorldHtml顶部评论中的注释
    // 有关将 GcDocs.Html 添加到项目的详细信息的示例代码。
    public class HtmlSettings
    {
        public void CreatePDF(Stream stream)
        {
            // 获取将在其中呈现网页的临时文件:
            var tmp = Path.GetTempFileName();
            // 要呈现的网页的 Uri:
            var uri = new Uri(@"https://developer.mescius.com/document-solutions/dot-net-pdf-api/demos/view-source-cs/word-index/");
            // 页脚模板中使用的图像:
            var image = @"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFAAAABQCAYAAACOEfKtAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAF8WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDggNzkuMTY0MDM2LCAyMDE5LzA4LzEzLTAxOjA2OjU3ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgMjEuMCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTAzLTI4VDEzOjExOjE1LTA0OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMC0wMS0yMFQxMjo0NjowNi0wNTowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMC0wMS0yMFQxMjo0NjowNi0wNTowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoyNTcxMWNkZC1kZWVmLTU0NDUtYjMwMi0xNTJjNTMzMmE3NDciIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDo1MzdlNGI5OS0zN2M3LTMyNDItYjQzNi1jN2I2YzM4N2JjOGIiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpmNGZmNTI4Ny0yOWE4LTU2NGYtYjQ3YS05ZGZkNjg1NDNiMjciPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmY0ZmY1Mjg3LTI5YTgtNTY0Zi1iNDdhLTlkZmQ2ODU0M2IyNyIgc3RFdnQ6d2hlbj0iMjAxOS0wMy0yOFQxMzoxMToxNS0wNDowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIDIxLjAgKFdpbmRvd3MpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoyNTcxMWNkZC1kZWVmLTU0NDUtYjMwMi0xNTJjNTMzMmE3NDciIHN0RXZ0OndoZW49IjIwMjAtMDEtMjBUMTI6NDY6MDYtMDU6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCAyMS4wIChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5fbzkiAAALSElEQVR4nN2ceZBU1RXGf2/pdbae7qFBhmEfVtlEEUkpVFCKWIpGklhapUYTE4lWRTGmlMQNK0qW0lRFjUlc4pYFDcYYRBHBYAIiRkVRBFkGZmCAYfaZnt7ee/njDktvM72994Z8VVQxr+875/bX595z7rn3HskwDE7FnGtewmYMB5YCC3v/LwH1wJvAI8Be+7oGm57/ZsLfsk39SAcFQdB+4IfAeMADuIFa4BZgD/A44LSpjykYKAReD3QAt2bRdklv25vM7FC2sJvA2cAO4GnA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";

            // PdfOptions 提供 HTML 到 PDF 转换的选项:
            // - PageRanges 允许您跳过在这种情况下为空的第一页。
            // - PageWidth/PageHeight 允许自定义页面大小(此处使用默认值进行演示)。
            // - 页边距指定页边距(默认为无边距)。
            // - 横向允许您更改页面方向。
            // - 缩放允许您放大或缩小渲染尺寸(默认值为 1)。
            // - 要添加自定义标头,需要将 DisplayHeaderFooter 设置为 true。
            // - HeaderTemplate/FooterTemplate 允许指定自定义页面标题。
            var pdfOptions = new PdfOptions()
            {
                PageRanges = "2-100",
                PageWidth = 8.5f,
                PageHeight = 11f,
                Margins = new PdfMargins(0.2f, 1, 0.2f, 1),
                Landscape = true,
                DisplayHeaderFooter = true,
                HeaderTemplate = "<div style='-webkit-print-color-adjust:exact;background-color:#395daa;color:white;" +
                    "padding:0.1in;font-size:12em;width:1000px;margin-left:0.2in;margin-right:0.2in'>" +
                    "<span style='float:left'>Page <span class='pageNumber'></span> of <span class='totalPages'></span></span>" +
                    "<span style='float:right'>Document created on <span class='date'></span>" +
                    "</div>",
                FooterTemplate = "<div style='font-size:12em;width:1000px;margin-left:0.2in;margin-right:0.2in'>" +
                    $"<span>Document location: <span class='url'></span><img style='float:right;' width='40' height='40' src='{image}'></img></div>"
            };

            // 创建一个用于呈现 HTML 的 GcHtmlBrowser 实例:
            using var browser = Common.Util.NewHtmlBrowser();

            // 将源网页渲染到临时文件:
            using var htmlPage = browser.NewPage(uri);
            htmlPage.SaveAsPdf(tmp, pdfOptions);

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