半岛外围网上直营

国产化PDF处理控件Spire.PDF教程:如何在 C# 中从 HTML 和 PDF 模板生成 PDF

翻译|行业资讯|编辑:吉炜炜|2025-10-16 10:36:44.143|阅读 9 次

概述:在企业应用、报表系统或财务工具的开发中,生成规范、专业的 PDF 文档是常见需求。与其在代码中硬编码布局,不如使用模板来提高开发效率。模板不仅能加快开发进程,还能确保品牌视觉与文档格式的一致性。本文将介绍如何使用 Spire.PDF for .NET 在 C# 中通过 HTML 模板 或 预设 PDF 模板 生成 PDF 文档,无论是需要动态布局还是快速替换占位符,都能灵活应对。

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

相关链接:

在企业应用、报表系统或财务工具的开发中,生成规范、专业的 PDF 文档是常见需求。与其在代码中硬编码布局,不如使用模板来提高开发效率。模板不仅能加快开发进程,还能确保品牌视觉与文档格式的一致性。

本文将介绍如何使用 Spire.PDF for .NET 在 C# 中通过 HTML 模板 或 预设 PDF 模板 生成 PDF 文档,无论是需要动态布局还是快速替换占位符,都能灵活应对。

Spire.PDF for .NET 

加入Spire技术交流QQ群(125237868),与更多开发者一起提升文档开发技能。

Spire.PDF for .NET 是什么

Spire.PDF for .NET 是一款功能强大的 PDF 操作库,允许 .NET 开发者无需依赖 Adobe Acrobat 即可创建、读取、编辑和转换 PDF 文档。该库提供全面的 API 接口,适用于生成报表、发票、证书及其他 PDF 格式文件,非常适合在 C# 应用中进行自动化文档处理。

与本教程相关的主要功能包括:

  • HTML 转 PDF: 将网页或 HTML 字符串高保真地渲染为 PDF 文档。
  • 文本替换: 在现有 PDF 中查找并替换文本,非常适合模板表单填充。
  • 全面控制: 从文本、图像到安全性与批注,提供精细化控制能力。

在项目中配置 Spire.PDF

要在 C# 项目中通过模板生成 PDF,首先需将 Spire.PDF 引入项目中。对于 HTML 转 PDF 的场景,Spire.PDF 依赖外部渲染引擎(Qt WebEngine 或 Google Chrome)。本文以 Qt WebEngine为例。

步骤 1:安装 Spire.PDF

在 Visual Studio 的 NuGet 包管理器中运行以下命令:

Install-Package Spire.PDF
或从慧都网下载 Spire.PDF 安装包,并将 DLL 文件手动导入项目。

步骤 2:下载并配置 Qt 插件

  1. 根据系统下载对应的 Qt WebEngine 插件:

    • Windows x86
    • Windows x64
    • Linux x64
    • Mac x64
  2.  解压文件后可获得插件目录,例如:C:\plugins-windows-x64\plugins

  3. 在 C# 代码中注册插件路径:

    HtmlConverter.PluginPath = @"C:\plugins-windows-x64\plugins";

在 C# 中通过 HTML 模板创建 PDF

HTML 模板非常适合需要表格、页眉页脚或复杂样式布局(如发票、报表)的文档。

步骤 1:构建带占位符的 HTML 模板

可在 HTML 中添加双花括号包裹的动态字段,例如:

<h1>发票</h1>
<p>发票编号: {{INVOICE_NUMBER}}</p>
<p>日期: {{INVOICE_DATE}}</p>
<p><strong>姓名: </strong> {{CUSTOMER_NAME}}</p>

步骤 2:使用运行时数据替换占位符

以下是一个生成发票 PDF 的完整示例代码:

using Spire.Additions.Qt;
using System.Drawing;
using Spire.Pdf.Graphics;

namespace CreatePdfFromHtmlTemplate
{
    class Program
    {
        static void Main(string[] args)
        {
            // 带有占位符变量的HTML模板
            string htmlTemplate = @"
                    <!DOCTYPE html>
                    <html lang=""zh"">
                    <head>
                      <meta charset=""UTF-8"">
                      <meta name=""viewport"" content=""width=device-width, initial-scale=1.0"">
                      <title>发票</title>
                      <style>
                        body {
                          font-family: ""SimHei"", ""黑体"", Tahoma, sans-serif;
                          margin: 40px auto;
                          padding: 20px;
                          max-width: 800px;
                          font-size: 20px;
                        }

                        h1 {
                          text-align: right;
                          font-size: 40px;
                          letter-spacing: 2px;
                          color: #222;
                          margin: 0 0 30px 0; 
                        }

                        .invoice-header, .invoice-footer {
                          margin-bottom: 50px;
                        }

                        .invoice-header {
                          display: flex;
                          justify-content: space-between;
                          align-items: center;
                          border-bottom: 3px solid #444;
                          padding-bottom: 10px;
                        }

                        .invoice-details {
                          margin: 20px 0;
                          padding: 15px;
                          background: #f5f5f5;
                          border-radius: 6px;
                        }

                        .invoice-details h2 {
                          font-size: 20px;
                          margin-bottom: 10px;
                          color: #444;
                        }

                        .info p {
                          margin: 2px 0;
                        }

                        table {
                          width: 100%;
                          border-collapse: collapse;
                          margin-top: 15px;
                        }

                        th, td {
                          padding: 10px;
                          border: 1px solid #ddd;
                          text-align: left;
                        }

                        th {
                          background-color: #efefef;
                          font-weight: 600;
                        }

                        tbody tr:nth-child(even) {
                          background: #f9f9f9;
                        }

                        .total {
                          margin-top: 20px;
                          text-align: right;
                          font-size: 15px;
                        }

                        .total p {
                          margin: 5px 0;
                        }

                        .total p span {
                          display: inline-block;
                          width: 120px;
                        }

                        .grand-total {
                          font-size: 18px;
                          font-weight: bold;
                          border-top: 2px solid #444;
                          margin-top: 10px;
                          padding-top: 10px;
                        }

                        .invoice-footer {
                          text-align: center;
                          font-size: 18px;
                          color: #666;
                          margin-top: 50px;
                          padding-top: 10px;
                        }
                      </style>
                    </head>
                    <body>

                      <div class=""invoice-header"">
                        <div>
                          <h2>公司名称</h2>
                          <p>123 商业街<br>重庆, 中国</p>
                        </div>
                        <div>
                          <h1>发票</h1>
                          <p>发票编号: {{INVOICE_NUMBER}}<br>日期: {{INVOICE_DATE}}</p>
                        </div>
                      </div>

                      <div class=""invoice-details"">
                        <h2>账单寄送至</h2>
                        <div class=""info"">
                          <p><strong>姓名:</strong> {{BILLER_NAME}}</p>
                          <p><strong>地址:</strong> {{BILLER_ADDRESS}}</p>
                          <p><strong>邮箱:</strong> {{BILLER_EMAIL}}</p>
                        </div>
                      </div>

                      <table>
                        <thead>
                          <tr>
                            <th>描述</th>
                            <th>数量</th>
                            <th>单价</th>
                            <th>行总计</th>
                          </tr>
                        </thead>
                        <tbody>
                          <tr>
                            <td>{{ITEM_DESCRIPTION}}</td>
                            <td>{{ITEM_QUANTITY}}</td>
                            <td>{{ITEM_UNIT_PRICE}}</td>
                            <td>{{ITEM_TOTAL}}</td>
                          </tr>
                          <!-- 这里可以添加更多行 -->
                        </tbody>
                      </table>

                      <div class=""total"">
                        <p><span>小计:</span> {{SUBTOTAL}}</p>
                        <p><span>税 ({{TAX_RATE}}%):</span> {{TAX}}</p>
                        <p class=""grand-total""><span>总计:</span> {{TOTAL}}</p>
                      </div>

                      <div class=""invoice-footer"">
                        <p>感谢您的惠顾!</p>
                        <p>如有任何疑问,请联系我们 support@example.com
				document.getElementById('cloak5f2cf25209fd99d2ad5ef7fb2c0e301b').innerHTML = '';
				var prefix = '&#109;a' + 'i&#108;' + '&#116;o';
				var path = 'hr' + 'ef' + '=';
				var addy5f2cf25209fd99d2ad5ef7fb2c0e301b = 's&#117;pp&#111;rt' + '&#64;';
				addy5f2cf25209fd99d2ad5ef7fb2c0e301b = addy5f2cf25209fd99d2ad5ef7fb2c0e301b + '&#101;x&#97;mpl&#101;' + '&#46;' + 'c&#111;m';
				var addy_text5f2cf25209fd99d2ad5ef7fb2c0e301b = 's&#117;pp&#111;rt' + '&#64;' + '&#101;x&#97;mpl&#101;' + '&#46;' + 'c&#111;m';document.getElementById('cloak5f2cf25209fd99d2ad5ef7fb2c0e301b').innerHTML += '<a ' + path + '\'' + prefix + ':' + addy5f2cf25209fd99d2ad5ef7fb2c0e301b + '\'>'+addy_text5f2cf25209fd99d2ad5ef7fb2c0e301b+'<\/a>';
		</p>  
                      </div>

                    </body>
                    </html>
                    ";

            // 发票的样本数据 - 与模板占位符匹配的键值对
            Dictionary<string, string> invoiceData = new Dictionary<string, string>()
            {
                { "INVOICE_NUMBER", "12345" },
                { "INVOICE_DATE", "2025-08-25" },
                { "BILLER_NAME", "张三" },
                { "BILLER_ADDRESS", "重庆市新北街123号" },
                { "BILLER_EMAIL", "zhangsan@ example.com" },
                { "ITEM_DESCRIPTION", "咨询服务" },
                { "ITEM_QUANTITY", "10" },
                { "ITEM_UNIT_PRICE", "$100" },
                { "ITEM_TOTAL", "$1000" },
                { "SUBTOTAL", "$1000" },
                { "TAX_RATE", "5" },
                { "TAX", "$50" },
                { "TOTAL", "$1050" }
            };

            // 用实际数据值填充HTML模板
            string populatedInvoice = PopulateInvoice(htmlTemplate, invoiceData);

            // 指定生成的PDF输出文件路径
            string outputFile = "HtmlToPdf.pdf";

            // 指定HTML转换器的插件路径(QT插件)
            string pluginPath = @"C:\plugins-windows-x64\plugins";

            // 设置HTML到PDF转换所需的插件路径
            HtmlConverter.PluginPath = pluginPath;

            // 使用指定设置将HTML字符串转换为PDF
            HtmlConverter.Convert(
                populatedInvoice,
                outputFile,
                true,                       // 启用JavaScript
                100000,                     // 超时(毫秒)
                new SizeF(595, 842),        // A4纸大小(595x842点)
                new PdfMargins(20),         // 四周20点边距
                LoadHtmlType.SourceCode     // 从源代码字符串加载HTML
            );

        }

        // 辅助方法: 用数据字典中的实际值替换模板占位符
        private static string PopulateInvoice(string template, Dictionary<string, string> data)
        {
            string result = template;
            foreach (var entry in data)
            {
                result = result.Replace("{{" + entry.Key + "}}", entry.Value);
            }
            return result;
        }
    }
}

实现原理

  1. 在 HTML 模板中定义形如 {{VARIABLE_NAME}} 的占位符。
  2. 使用字典存储实际数据的键值对,与模板占位符对应。
  3. 程序运行时将模板中的占位符替换为真实数据。
  4. 调用 Spire.PDF(配合 Qt 插件)将 HTML 渲染为 PDF 文件。

输出结果:

在 C# 中通过 PDF 模板生成 PDF

有时设计团队会提供带有占位符(如 {PROJECT_NAME})的静态 PDF 模板。通过简单的文本替换即可将这些模板快速填充成正式文档。

示例:填充项目报告模板

using Spire.Pdf;
using Spire.Pdf.Texts;
using static Spire.Pdf.Texts.PdfTextReplaceOptions;

namespace GeneratePdfFromPdfTemplate
{
    class Program
    {
        static void Main(string[] args)
        {
            // 创建一个PdfDocument对象
            PdfDocument doc = new PdfDocument();

            // 加载一个PDF文件
            doc.LoadFromFile(@"C:\Users\Administrator\Desktop\Template.pdf");

            // 创建一个PdfTextReplaceOptions对象并指定选项
            PdfTextReplaceOptions textReplaceOptions = new PdfTextReplaceOptions();
            textReplaceOptions.ReplaceType = ReplaceActionType.WholeWord; // 替换类型设置为整词替换

            // 获取特定页面
            PdfPageBase page = doc.Pages[0];

            // 基于页面创建一个PdfTextReplacer对象
            PdfTextReplacer textReplacer = new PdfTextReplacer(page);
            textReplacer.Options = textReplaceOptions;

            // 旧字符串和新字符串的字典
            Dictionary<string, string> replacements = new Dictionary<string, string>()
            {
                { "{PROJECT_NAME}", "新网站开发" },
                { "{PROJECT_NO}", "2023-001" },
                { "{PROJECT MANAGER}", "爱丽丝·约翰逊" },
                { "{PERIOD}", "2023年第三季度" },
                { "{START_DATE}", "2023年7月1日" },
                { "{END_DATE}", "2023年9月30日" }
            };

            // 遍历字典进行文本替换
            foreach (var pair in replacements)
            {
                textReplacer.ReplaceText(pair.Key, pair.Value);
            }

            // 将文档保存为另一个PDF文件
            doc.SaveToFile("FromPdfTemplate.pdf");
            doc.Close();
        }
    }
}

实现原理

  1. 加载包含占位符的现有 PDF 文件。
  2. 使用字典存储占位符与实际数据的映射关系。
  3. 遍历字典并替换 PDF 中对应的文本。
  4. 将修改后的文档另存为新 PDF 文件。

限制说明: 此方法仅适用于短文本(如姓名、编号、日期等)的替换。对于多行文本或动态扩展的内容,它的效果不佳,因为PDF不会自动重新排版文本。对于较大的内容块,请使用HTML或Word模板。

输出结果:


根据模板生成 PDF 最佳实践

选择合适的模板类型

  • HTML 模板: 适用于需要复杂样式、表格或长文本的文档灵活性最高。
  • PDF 模板: 适用于布局固定、仅需替换少量字段的文档(如表单、报告)。
  • Word 模板: 若文档源于 .docx 文件,可使用 Spire.Doc for .NET 进行占位符替换并导出为 PDF。

占位符设计

  • 使用独特且清晰的占位符格式(如 {NAME}、{DATE})避免误替换。
  • 保持一致的命名规范,减少维护错误。

测试与验证

  • 使用真实或代表性数据进行测试,检查文本对齐、换行与版面效果。

模板管理

  • 将模板文件与代码分离,方便设计人员独立维护。
  • 建立模板规范文档,定义命名、语法和样式要求。

常见问题解答

Q1:可以使用 Google Chrome 代替 Qt WebEngine 渲染 HTML 吗?

可以。对于复杂 HTML、CSS 或现代 JavaScript,建议使用 ChromeHtmlConverter 类,它能生成更精确的 PDF。

Q2:在 PDF 模板中替换文本有哪些限制?

PDF 布局固定,替换文本不会自动重排。当新文本过长可能溢出,过短则留白。适用于可预测的字段内容(如姓名、日期等)。对于多行文本或动态内容,可使用 HTML 或 Word 模板,或借助 Spire.PDF 的绘图 API 直接绘制新文本块。

Q3:能否通过 Spire.PDF 从 Word 模板生成 PDF?

Spire.PDF 主要用于 PDF 操作,如需根据 Word 模板生成PDF,可使用 Spire.Doc for .NET 替换 Word 模板内容,然后再保存为 PDF。

Q4:如何在模板生成的 PDF 中插入图片、Logo 或签名?

  • 在 PDF 中,可通过 PdfCanvas.drawImage() 方法绘制图片。
  • 在 HTML 模板中,可直接使用  标签。

这样即可轻松添加公司 Logo、水印或电子签名。

结论

使用 Spire.PDF 在 C# 中基于模板生成 PDF,是提升文档自动化效率的理想方式。无论选择 HTML 模板还是现有 PDF 模板,开发者都能轻松创建内容准确、版面统一、外观专业的文件。通过在开发流程中引入模板机制,不仅能显著减少重复性工作,还能确保品牌风格与格式的一致性。

在实施过程中,合理选择模板类型、规范占位符设计,并在部署前充分测试真实数据,能够帮助你获得更稳定的输出效果。随着项目的深入,还可以结合 Spire.PDF 的高级功能,如数字签名、加密与批注等,实现更安全、更智能的文档处理方案。

通过这一方法,你的团队将能够在保证质量与一致性的同时,大幅提升 PDF 文档的生成速度与管理效率,从而让自动化办公与报告生成更加高效、可控。


————————————————————————————————————————

关于慧都科技:

慧都科技(EVGET)成⽴于2003年,是⼀家⾏业数字化解决⽅案公司,⻓期专注于软件、油⽓与制造⾏业。公司基于深⼊的业务理解与管理洞察,以系统化的业务建模驱动技术落地,帮助企业实现智能化运营与⻓期竞争优势。在软件工程领域,我们提供开发控件、研发管理、代码开发、部署运维等软件开发全链路所需的产品,提供正版授权采购、技术选型、个性化维保等服务,帮助客户实现技术合规、降本增效与风险可控。慧都科技E-iceblue的官方授权代理商,提供E-iceblue系列产品免费试用,咨询,正版销售等于一体的专业化服务E-iceblue旗下Spire系列产品是国产文档处理领域的优秀产品,支持国产化信创,帮助企业高效构建文档处理的应用程序。

欢迎下载|体验更多E-iceblue产品

获取更多信息请咨询 ;技术交流Q群(125237868


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@ke049m.cn

文章转载自:慧都网

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
相关产品
Spire.PDF for .NET

Spire.PDF for .NET是独立的PDF控件,用于.NET程序中创建、编辑和操作PDF文档

Spire.Office for .NET

专业的.NET Office套件,涵盖office文档创建、编辑、转换、管理和OCR内容识别等操作

Spire.Doc for .NET

Spire.Doc for .NET 是一款专门对 Word 文档进行操作的 .NET 类库。

Aspose.PDF for .NET

PDF文档创建组件,无需Adobe Acrobat,也可以在任何平台上操作PDF文档。

IronPDF

在C#中用HTML、MVC、ASPX和图像生成PDF,具备50多个阅读和编辑PDF的功能

扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP
利记足球官网(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) 真人boyu·博鱼滚球网(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) 最大网上PM娱乐城盘口(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) 正规雷火竞技官方买球(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) 雷火竞技权威十大网(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) boyu·博鱼信誉足球官网(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) 权威188BET足球网(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新) 正规188BET足球大全(官方)网站/网页版登录入口/手机版登录入口-最新版(已更新)