10分钟上手pdfmake:轻松生成符合PDF/A标准的归档文档
你是否还在为如何生成长期可保存的PDF文档而烦恼?企业档案、电子合同、政府报表等重要文件需要确保几十年后仍能准确显示,这就需要符合PDF/A标准。本文将带你用pdfmake这个纯JavaScript库,在10分钟内从零开始生成符合PDF/A-3a标准的归档文档,无需复杂配置,只需简单几步即可完成。
PDF/A标准简介
PDF/A是国际标准化组织(ISO)制定的用于长期归档的PDF格式标准,它确保文档在未来仍可访问和呈现。与普通PDF相比,PDF/A有以下特点:
- 禁止使用可能随时间变化的外部资源
- 必须嵌入所有字体
- 支持元数据存储
- 保证颜色再现的一致性
目前最新的版本是PDF/A-3a,它在PDF/A-2a的基础上增加了对嵌入式文件的支持,非常适合需要附加原始数据的归档场景。
pdfmake简介
pdfmake是一个功能强大的JavaScript库,支持在客户端和服务器端生成PDF文档。它提供了声明式的文档定义语法,让你可以轻松创建复杂的PDF文档。项目核心代码位于src/browser-extensions/pdfMake.js,完整功能列表可查看README.md。
主要特点
- 支持文本、图像、表格、列表等多种元素
- 丰富的样式定义和继承
- 页面页眉页脚和页码控制
- 支持PDF/A、PDF/UA等标准
- 客户端直接生成,无需服务器参与
快速开始:生成PDF/A文档
步骤1:引入pdfmake库
在HTML页面中引入pdfmake库,建议使用国内CDN以确保访问速度:
<script src="https://cdn.bootcdn.net/ajax/libs/pdfmake/0.2.7/pdfmake.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/pdfmake/0.2.7/vfs_fonts.js"></script>
步骤2:定义PDF/A文档
创建一个基本的PDF/A文档定义,关键是设置subset: 'PDF/A-3a'和适当的元数据:
// 文档定义
const docDefinition = {
version: '1.5', // PDF版本
subset: 'PDF/A-3a', // 指定PDF/A-3a标准
tagged: true, // 标记为Tagged PDF,提升可访问性
displayTitle: true, // 在窗口标题中显示文档标题
info: {
title: '财务报表归档文档', // 文档标题
author: '财务部门', // 作者
subject: '2024年度财务报表', // 主题
keywords: '财务,报表,归档,PDF/A' // 关键词
},
content: [
{ text: '2024年度财务报表', style: 'header' },
{ text: '生成日期: ' + new Date().toLocaleDateString(), style: 'subheader' },
{ text: '财务摘要', style: 'heading' },
{ text: '本年度公司营收达到1000万元,同比增长15%。净利润200万元,毛利率维持在30%的水平。', style: 'bodyText' }
],
styles: {
header: {
fontSize: 24,
bold: true,
margin: [0, 0, 0, 10]
},
subheader: {
fontSize: 12,
color: '#666',
margin: [0, 0, 0, 20]
},
heading: {
fontSize: 16,
bold: true,
margin: [0, 15, 0, 5]
},
bodyText: {
fontSize: 12,
margin: [0, 5, 0, 5]
}
}
};
步骤3:生成并下载PDF
使用pdfmake的createPdf方法生成PDF并下载:
// 创建PDF实例
const pdfDocGenerator = pdfMake.createPdf(docDefinition);
// 下载PDF文件
pdfDocGenerator.download('财务报表归档.pdf');
完整示例:带表格和图像的PDF/A文档
下面是一个更完整的示例,包含表格和图像元素,展示了pdfmake的更多功能:
const docDefinition = {
version: '1.5',
subset: 'PDF/A-3a',
tagged: true,
displayTitle: true,
info: {
title: '月度销售报告',
author: '销售部门',
subject: '2024年5月销售数据',
keywords: '销售,报告,PDF/A,归档'
},
content: [
{ text: '月度销售报告', style: 'header' },
{ text: '2024年5月', style: 'subheader' },
{ text: '销售概览', style: 'heading' },
{ text: '本月销售总额达到85万元,完成月度目标的106%,同比增长12%。各产品线均实现正增长,其中新产品系列表现突出,贡献了35%的销售额。', style: 'bodyText' },
{ text: '销售数据明细', style: 'heading' },
// 表格示例
{
table: {
headerRows: 1,
widths: ['*', 'auto', 'auto', 'auto'],
body: [
['产品名称', '销售量', '单价', '销售额'],
['标准版', 120, 1999, 239880],
['专业版', 85, 3499, 297415],
['企业版', 42, 5999, 251958],
['', '', '总计', 789253]
]
},
style: 'table'
},
{ text: '销售趋势图', style: 'heading' },
// 图像示例
{
image: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...', // 图像base64数据
width: 500,
style: 'image'
}
],
styles: {
header: { fontSize: 24, bold: true, margin: [0, 0, 0, 10] },
subheader: { fontSize: 14, color: '#666', margin: [0, 0, 0, 20] },
heading: { fontSize: 16, bold: true, margin: [0, 20, 0, 10] },
bodyText: { fontSize: 12, margin: [0, 5, 0, 5] },
table: { margin: [0, 10, 0, 20] },
image: { margin: [0, 10, 0, 20] }
}
};
// 生成并下载PDF
pdfMake.createPdf(docDefinition).download('202405销售报告.pdf');
服务器端使用
除了客户端,pdfmake也可以在Node.js环境中使用。首先安装依赖:
npm install pdfmake
然后使用以下代码生成PDF/A文档:
const pdfmake = require('pdfmake');
const fs = require('fs');
// 字体定义 - PDF/A必须嵌入所有字体
const fonts = {
Roboto: {
normal: 'fonts/Roboto-Regular.ttf',
bold: 'fonts/Roboto-Medium.ttf',
italics: 'fonts/Roboto-Italic.ttf',
bolditalics: 'fonts/Roboto-MediumItalic.ttf'
}
};
// 创建打印机实例
const printer = new pdfmakePrinter(fonts);
// 文档定义,与客户端类似
const docDefinition = {
version: '1.5',
subset: 'PDF/A-3a',
tagged: true,
info: {
title: '服务器端生成的PDF/A文档',
author: 'Node.js应用'
},
content: [
'这是一个在服务器端生成的PDF/A-3a文档示例'
]
};
// 创建文档
const pdfDoc = printer.createPdfKitDocument(docDefinition);
pdfDoc.pipe(fs.createWriteStream('server-generated.pdf'));
pdfDoc.end();
项目中提供了完整的服务器端示例,可参考examples/pdfa.js。
常见问题解决
问题1:中文字体显示异常
PDF/A要求必须嵌入所有字体,解决方法是确保正确加载中文字体:
// 字体定义
pdfMake.fonts = {
Roboto: {
normal: 'Roboto-Regular.ttf',
bold: 'Roboto-Medium.ttf',
italics: 'Roboto-Italic.ttf',
bolditalics: 'Roboto-MediumItalic.ttf'
},
SimSun: { // 中文字体
normal: 'SimSun.ttf',
bold: 'SimSun.ttf',
italics: 'SimSun.ttf',
bolditalics: 'SimSun.ttf'
}
};
// 在文档中使用
const docDefinition = {
content: [
{ text: '这是一段中文文本', font: 'SimSun' }
]
};
问题2:PDF/A验证失败
如果生成的文档无法通过PDF/A验证,检查以下几点:
- 确保所有字体都已嵌入
- 检查是否使用了不支持的功能(如JavaScript)
- 验证颜色空间是否符合PDF/A标准
- 确保元数据完整
总结
pdfmake提供了一种简单高效的方式来生成符合PDF/A标准的归档文档。通过本文的介绍,你已经了解了如何:
- 配置PDF/A文档参数
- 创建基本的PDF/A文档
- 在客户端和服务器端使用pdfmake
- 解决常见问题
现在你可以开始使用pdfmake来创建自己的归档文档了。更多高级功能和示例,请参考项目中的examples/目录和官方文档。
扩展学习
- 官方文档:https://pdfmake.github.io/docs/
- 项目示例:examples/
- PDF/A标准详解:ISO 19005-3:2012
希望本文对你有所帮助,如有任何问题,欢迎在项目仓库提交issue或参与讨论。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



