使用邮件合并进行文档生成,就是从数据源读取数值,并把每个值放入模板中对应的占位符。你需要保留两样东西:一个包含合并字段(等待填充的变量)的模板,以及一个提供这些值、并包含每份副本都相同内容的数据源。PDF4me 的报表引擎接收这两个文件,返回一份完成的文档。
PDF4me 接受 Word、HTML 和 PDF 模板,其中功能最丰富的是 Word。借助一套简短易读的语法,你可以设计一个 Word 模板,涵盖发票、收据、合同、报价单或任何个性化文档,然后从数据批量生成成千上万份。本指南将走遍完整语法——合并字段、条件、格式化、表格、图片和内联 HTML——并配有可直接复制的示例,以及一个可下载并运行的示例模板。每个语法链接都指向 Word 模板语法文档中对应的确切页面。
在 Word 文档中把占位符写成 <<[FieldName]>>。再用少量额外的 token 添加条件、格式化、循环、图片和 HTML。把该模板连同一个 JSON(或 XML)数据文件发送给 PDF4me 的 Generate Document 操作,你就会收到一份完成的个性化文档——一次,或成千上万次。
如何设计 Word 模板?
一切从一个占位符开始。凡是要插入值的地方,就输入用双尖括号和方括号包裹的字段名:
<<[FieldName]>>
括号内的名称必须与数据源中的某个属性匹配。名称要有描述性,坚持一种命名约定(camelCase 或 PascalCase),并避免特殊字符。下面是一个最简模板以及填充它的数据:
Dear <<[CustomerName]>>,
Thank you for your order #<<[OrderNumber]>>.
{
"CustomerName": "John Smith",
"OrderNumber": "12345"
}
引擎返回:
Dear John Smith,
Thank you for your order #12345.
这就是全部思路。下面的一切都是同一原理的变体——条件、循环和格式化始终包裹着普通的合并字段。完整细节见语法概览。
如何为模板添加条件?
Generate Document 操作可以根据你的数据进行分支。依据某个条件是否为真,它会插入这一块或另一块内容。基本的 if / elseif / else 结构如下:
<<if [condition1]>> Add the first block
<<elseif [condition2]>> Add the second block
<<else>> Add the fallback block
<</if>>
条件可以直接检验一个值,也可以借助枚举方法(见下文),例如 <<if [employees.Any(p => p.Age > 50)]>>。完整的比较和逻辑运算符见条件逻辑。
如何为模板中的值设置格式?
原始值往往需要在放入前进行处理——特定样式的日期、四舍五入的数字、转为大写的文本。在字段名后面添加格式说明,用冒号分隔并置于引号内:
<<[token]:"format">>
日期使用 .NET 风格的模式:
Invoice Date: <<[invoiceDate]:"dd.MM.yyyy">>
Due Date: <<[dueDate]:"MMMM dd, yyyy">>
大小写有各自的简短开关——:upper、:caps(每个单词首字母大写)和 :firstCap:
Customer: <<[customerName]:upper>>
Product: <<[productName]:caps>>
数字使用标准数字格式,因此 <<[price]:"F2">> 会把一个值固定为两位小数。日期、文本和数字模式的完整列表见模板中的格式化。
如何从列表生成表格?
表格正是文档生成大显身手之处——一行模板会扩展为数据所拥有的那么多行。创建一个普通的 Word 表格,在第一个单元格打开 <<foreach>> 循环,在随后的每个单元格添加一个合并字段,并在最后一个单元格关闭循环:
Column 1: <<foreach [product in products]>><<[product.productName]>>
Column 2: <<[product.manufactured]:"yyyy.MM.dd">>
Column 3: <<[product.price]>><</foreach>>
products 数组中的每个对象都会成为一行,你可以像在其他任何地方一样就地为单元格设置格式。更多表格模式,包括过滤和聚合的行,见模板中的表格。
如何重复段落和区段?
同一个 <<foreach>> 循环在表格之外也同样有效。包裹任意一块内容——一个段落、一个标题加正文、一整个区段——它就会按集合中的每个项目重复一次:
<<foreach [item in collection]>>
Content with <<[item.property]>>
<</foreach>>
循环可以嵌套(每个部门一个区段,其中每位员工一行),并且可以在遍历时对集合进行过滤或排序。嵌套和条件示例见重复段落和区段。
如何为模板添加图片?
PDF4me 可以从公共 URL 或 Base64 字符串把图片引入生成的文档。有一条规则很重要:图片字段必须位于 Word 文本框内。先在你想要图片的位置创建文本框,然后添加该字段。
来自公共 URL:
<<image [imageUrl]>>
来自 Base64 编码的字符串:
<<image [imageBase64]>>
你可以用 -keepRatio、-fitHeight、-fitWidth 和 -fitSize 等开关来控制尺寸,例如 <<image [companyLogo] -keepRatio>>。完整的尺寸参考和按行插入图片的示例见插入图片。
如何在模板中插入 HTML?
如果你的数据已经包含格式化的 HTML,就用 -html 开关就地渲染它,而不是把它转义为纯文本:
<<[token] -html>>
引擎会把字段值解析为 HTML,并在生成的文档中应用相应格式——粗体、斜体、列表、标题、彩色 span 等等。支持的标签和样式列于插入 HTML。
用枚举方法处理你的数据
除了简单字段之外,引擎还提供了可以直接在 token 内调用的 IEnumerable 风格方法——过滤、排序、计数、求平均等等。几个示例:
Total products: <<[products.Count()]>>
Average price: $<<[products.Average(p => p.price)]:"F2">>
Top items: <<foreach [p in products.OrderByDescending(x => x.price).Take(5)]>><<[p.name]>><</foreach>>
它们能与条件和循环自然组合。完整的方法列表——Where、OrderBy、GroupBy、Sum、Any、First 等——见模板中的枚举。
示例数据如下所示——一个供应商、一个客户,以及模板要遍历的产品列表:
{
"VendorName": "PDF4me",
"VendorCity": "Zurich",
"VendorCountry": "Switzerland",
"VendorZip": "8630",
"VendorContact": "123456",
"InvoiceDate": "22-08-2022",
"CustomerName": "John Doe",
"CustomerCity": "Start City",
"CustomerCountry": "US",
"CustomerZip": "3214",
"products": [
{ "productName": "PDF Converter", "value": 2000, "expires": "01/08/2025" },
{ "productName": "PDF API", "value": 1250, "expires": "18/02/2029" },
{ "productName": "PDF Editor", "value": 1999, "expires": "12/12/2027" }
],
"comments": "This document is <b>computer generated</b> and does not require a signature."
}
注意 comments 携带了 HTML——把它与 <<[comments] -html>> 开关搭配,<b> 标签就会在输出中呈现为粗体。
设计模板的快捷链接
常见问题
如何在 Word 模板中创建合并字段?
在任何要插入值的位置,把字段名写在双尖括号和方括号内,例如 <<[CustomerName]>>。名称必须与你的 JSON 或 XML 数据源中的某个属性匹配。你可以在任意位置手动添加字段——标题、段落、表格单元格或文本框。
PDF4me 支持哪些模板格式?
Word(.docx、.doc)、HTML 和 PDF。三者使用相同的合并字段语法,因此你为 Word 模板学到的知识可以迁移。Word 对版面、条件、表格和图片提供最完整的控制。
我可以给 Word 模板添加 if/else 条件吗?
可以。用 <<if [condition]>> ... <<elseif [condition]>> ... <<else>> ... <</if>> 包裹内容。条件可以直接比较字段,也可以调用像 Any() 或 Count() 这样的枚举方法。这样一个模板就能处理数据的每种变体,而不必为每种情况维护一个文件。
如何在模板中格式化日期和数字?
把格式放在字段名之后并置于引号中:日期用 <<[invoiceDate]:"dd.MM.yyyy">>,两位小数的数字用 <<[price]:"F2">>。大小写有简短开关——:upper、:caps 和 :firstCap。
如何生成一个随数据增长的表格?
创建一个 Word 表格,在第一个单元格打开 <<foreach [item in collection]>>,在其余每个单元格放入一个合并字段,并在最后一个单元格用 <</foreach>> 关闭。集合中的每个项目都会自动成为一行。
故障排除
后续步骤
模板只需设计一次,把它接到你的数据上,PDF4me 就会按需生成个性化的发票、合同和报表——来自单次 API 调用,或一次处理成千上万份的自动化。
