PDF/A 是 ISO 标准化的长期归档格式,它将文档中的字体、色彩和元数据固化到统一的合规层级,确保文档在未来数十年内无论使用何种 PDF 阅读器都能完整重现。与之相对,普通 PDF 在日常编辑和内容提取上更加灵活。实际业务中通常需要在两种格式间灵活切换:合同归档时转为 PDF/A 以满足法规要求,审计复核时又需还原为普通 PDF 以提取文本内容。
Spire.PDF for JavaScript 基于 WebAssembly 在浏览器端直接完成 PDF 与 PDF/A 之间的双向转换,通过虚拟文件系统(VFS)管理输入输出文件,无需后端服务支持。
本文介绍两个核心功能点:
有关安装和项目配置,请参考 React 项目中集成 Spire.PDF for JavaScript。以下示例默认已安装 Spire.PDF 并完成 WebAssembly 模块初始化。
转换 PDF 到 PDF/A
PDF/A 归档转换的核心在于将普通 PDF 中的字体、色彩和元数据固化到符合 ISO 标准的层级。Spire.PDF 通过 PdfStandardsConverter 组件一键完成此操作,产品支持 PDF/A-1a、PDF/A-1b、PDF/A-2a、PDF/A-2b、PDF/A-3a、PDF/A-3b 等多个合规级别。
PdfStandardsConverter 支持的转换标准及其适用场景如下:
| 方法 | 标准 | 说明 |
|---|---|---|
ToPdfA1B |
PDF/A-1b | 基于 PDF 1.4,仅保证视觉外观的可再现性,是最常用的归档级别 |
ToPdfA1A |
PDF/A-1a | 在 1b 基础上要求文档标签与结构信息,支持无障碍阅读 |
ToPdfA2A |
PDF/A-2a | 基于 PDF 1.7,要求标签与结构信息,支持图层和透明度 |
ToPdfA2B |
PDF/A-2b | PDF/A-2 基本合规级别,允许透明度、图层和嵌入 OLE 对象 |
ToPdfA3A |
PDF/A-3a | 在 2a 基础上允许嵌入 XML、Excel 等任意格式文件作为附件 |
ToPdfA3B |
PDF/A-3b | PDF/A-3 基本合规级别,支持嵌入任意格式附件 |
ToPdfX1A2001 |
PDF/X-1a:2001 | 印刷交换标准,适合出版和打印工作流 |
以下以 PDF/A-2b 为例演示转换过程:
function App() {
const convertToPDFA = async () => {
// 获取 Spire.PDF WASM 模块
const pdfModule = window.wasmModule?.spirepdf;
// 检查模块是否就绪
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// 将字体和 PDF 文件载入 VFS
await window.spire.FetchFileToVFS('arial.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = '电影介绍.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 创建 PdfStandardsConverter
let converter = new pdfModule.PdfStandardsConverter({ filePath: inputFileName });
// 转换为 PDF/A-1b 格式
const outputFileName = 'ToPDFA_result.pdf';
converter.ToPdfA2B({ filePath: outputFileName });
// // 转换为 PDF/A-1a
// converter.ToPdfA1A({ filePath: outputFileName });
// // 转换为 PDF/A-2a
// converter.ToPdfA2A({ filePath: outputFileName });
// // 转换为 PDF/A-2b
// converter.ToPdfA2B({ filePath: outputFileName });
// // 转换为 PDF/A-3a
// converter.ToPdfA3A({ filePath: outputFileName });
// // 转换为 PDF/A-3b
// converter.ToPdfA3B({ filePath: outputFileName });
// // 转换为 PDF/X-1a:2001
// converter.ToPdfX1A2001({ filePath: outputFileName });
// 从 VFS 读取转换后的文件,触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
// 释放资源
converter.Dispose();
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Convert PDF To PDF/A</h1>
<button onClick={convertToPDFA}>
Generate
</button>
</div>
);
}
export default App;
通过 PdfStandardsConverter 转换后生成的 PDF/A 输出

转换 PDF/A 到 PDF
PDF/A 是长期归档的标准格式,但在日常编辑和内容提取场景中,可能需要将 PDF/A 还原为标准 PDF。Spire.PDF for JavaScript 通过加载 PDF/A 文档后逐页复制内容到新文档的方式实现这一反向转换,确保输出的标准 PDF 不保留 PDF/A 合规约束。
function App() {
const convertToNormalPDF = async () => {
// 获取 Spire.PDF WASM 模块
const pdfModule = window.wasmModule?.spirepdf;
// 检查模块是否就绪
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// 将字体和 PDF 文件载入 VFS
await window.spire.FetchFileToVFS('arial.ttf', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
const inputFileName = 'PDFA_JP.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// 创建 PdfDocument 对象
let doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// 创建新的 PDF 文档用于在新文件上绘制内容
let newDoc = new pdfModule.PdfNewDocument();
newDoc.CompressionLevel = pdfModule.PdfCompressionLevel.None;
// 遍历原始文档中的每一页
for (let i = 0; i < doc.Pages.Count; i++) {
let page = doc.Pages.get_Item(i);
// 获取当前页面的大小
let size = page.Size;
// 向新文档添加相同大小且无边距的页面
let newPage = newDoc.Pages.Add({ size: size, margins: new pdfModule.PdfMargins() });
// 将原始页面的内容绘制到新页面上
let template = page.CreateTemplate();
let layoutWidget = new pdfModule.PdfLayoutWidget(template.H);
layoutWidget.Draw({ page: newPage, x: 0, y: 0 });
// page.CreateTemplate().Draw({page: newPage, x: 0, y: 0});
}
// 定义输出文件名
const outputFileName = "PDFAToPdf_result.pdf";
// 保存文档到指定路径
newDoc.Save(outputFileName);
// 从 VFS 读取生成的文件并触发下载
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
// 释放资源
newDoc.Dispose();
doc.Dispose();
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Convert PDF/A To Normal PDF</h1>
<button onClick={convertToNormalPDF}>
Generate
</button>
</div>
);
}
export default App;
通过创建新文档逐页复制内容生成的普通 PDF 输出

常见问题
加密的 PDF 能否转换为 PDF/A
原因:需要输入密码才能打开的加密 PDF 无法直接被 PdfStandardsConverter 处理,需要在加载时提供密码。
解决:PdfStandardsConverter 方法支持传入 password 参数,转换带密码的 PDF 到 PDF/A:
// 创建 PdfStandardsConverter 时指定密码
let converter = new pdfModule.PdfStandardsConverter({ filePath: inputFileName, password: "password" });
converter.ToPdfA2A({ filePath: outputFileName });
converter.Dispose();
获取免费许可证
如果您希望删除结果文档中的评估消息,或者摆脱功能限制,请该Email地址已收到反垃圾邮件插件保护。要显示它您需要在浏览器中启用JavaScript。获取有效期 30 天的临时许可证。







