跳转到内容

生成 PDF/A-4 归档输出

这份 recipe(示例)通过 Pro 的 PdfAManager 生成 PDF/A-4(ISO 19005-4)归档输出。保存时,NextPDF 会调度 OutputIntent、嵌入式 ICC 配置文件以及识别元数据。NextPDF 生成的是力求符合一致性要求的输出;最终是否一致由独立验证器判定。这份 recipe 遵循 examples/32-pdfa4-icc.php

Terminal window
composer require nextpdf/core:^3
composer require nextpdf/pro

PDF/A-4 是 Pro 级功能。在仅安装核心包的环境中,enablePdfA() 会抛出 InvalidConfigException。消息会指出缺少的 security.pdfa 能力,并提示使用 composer require nextpdf/pro 修正。验证步骤需要在 PATH 中提供一个 PDF/A 验证器。示例使用搭配 --flavour 4 的 veraPDF。

PDF/A-4 是构建于 ISO 32000-2(PDF 2.0)之上的 ISO 19005-4 归档配置文件。符合一致性要求的文件具备确定的色彩表现,并且能够自包含。它会声明一个 OutputIntent,并引用一个嵌入式 ICC 目标配置文件,使色彩无需外部资源即可重现(§6.2.3)。每个字体程序都会被嵌入(§6.2.10.4.1)。文件在 XMP 中带有 pdfaid 识别元数据(§6.7.3)。文件会加密(§6.6.4 —— PDF/A 禁止使用 Encrypt trailer 键)。

NextPDF 使用强类型的 ConformanceMode enum 建模 PDF/A。enablePdfA() 会实例化 Pro 的 PdfAManager,并默认为 ConformanceMode::PdfA4。这个管理器会在 save() 期间调度 OutputIntent、ICC 流与 XMP 扩展结构描述。pdfaPart()pdfaConformanceLetter() 这两个判别器会让 pdfaid:part / pdfaid:conformance 元数据与所选变体(44e4f)保持一致。按该部分的要求,基本配置文件不会输出 pdfa:conformance 字母。

此 API 接口由 PHPDoc 生成。主要入口:

  • \NextPDF\Core\Document::createStandalone(): Document
  • Document::enablePdfA(?object $version = null): static
  • \NextPDF\Support\CapabilityRegistry::getInstance()->get('security.pdfa')->isAvailable(): bool
  • \NextPDF\Conformance\ConformanceMode::PdfA4 / PdfA4e / PdfA4f
  • ConformanceMode::pdfaPart(): 2|3|4|nullConformanceMode::pdfaConformanceLetter(): string
examples/32-pdfa4-icc.php
<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Core\Document;
use NextPDF\Support\CapabilityRegistry;
$out = __DIR__ . '/output/32-pdfa4-icc.pdf';
// Probe before activating a Pro-gated feature so a Core-only install
// gets an actionable message instead of a stack trace.
$registry = CapabilityRegistry::getInstance();
if (!$registry->get('security.pdfa')->isAvailable()) {
fwrite(STDERR, "PDF/A-4 requires nextpdf/pro. Run: composer require nextpdf/pro\n");
exit(1);
}
$doc = Document::createStandalone();
$doc->enablePdfA(); // defaults to ConformanceMode::PdfA4
$doc->setTitle('Archival Record 2026-0042');
$doc->setLanguage('en');
$doc->addPage();
$doc->setFont('helvetica', '', 12);
$doc->cell(0, 10, 'This document targets PDF/A-4.', newLine: true);
$doc->save($out); // PdfAManager emits OutputIntent + ICC + XMP here
echo "Created: output/32-pdfa4-icc.pdf\n";

这是一段自包含、可由测试工具执行的程序。生产环境的调用方会把验证器判定作为构建 gate。成功的 save() 证明 NextPDF 已输出这些产物;只有验证器才能证明一致性。

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
use NextPDF\Exception\InvalidConfigException;
use NextPDF\Support\CapabilityRegistry;
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT') ?: (__DIR__ . '/archival.pdf');
if (!CapabilityRegistry::getInstance()->get('security.pdfa')->isAvailable()) {
fwrite(STDERR, "PDF/A-4 requires nextpdf/pro. Run: composer require nextpdf/pro\n");
exit(1);
}
try {
$doc = Document::createStandalone();
$doc->enablePdfA(); // ConformanceMode::PdfA4
$doc->setTitle('Archival Record 2026-0042');
$doc->setLanguage('en');
$doc->addPage();
$doc->setFont('helvetica', '', 12);
$doc->cell(0, 10, 'Long-term archival record. PDF/A-4 (ISO 19005-4).', newLine: true);
// Do NOT call setEncryption(): PDF/A prohibits the Encrypt key and
// the call raises an incompatibility exception in either order.
$doc->save($out);
} catch (InvalidConfigException $e) {
fwrite(STDERR, "PDF/A-4 activation failed: {$e->getMessage()}\n");
exit(1);
}
$exitCode = 0;
$report = [];
exec('verapdf --flavour 4 ' . escapeshellarg($out), $report, $exitCode);
if ($exitCode !== 0) {
fwrite(STDERR, "veraPDF FAILED — output is not PDF/A-4 conforming\n");
fwrite(STDERR, implode("\n", $report) . "\n");
exit(1);
}
echo "veraPDF PASS — archival.pdf is reported PDF/A-4 conforming\n";

在已安装 nextpdf/pro、且 verapdf 报告文件一致的主机上,预期 STDOUT 为:

veraPDF PASS — archival.pdf is reported PDF/A-4 conforming

在仅安装核心包的主机上,程序会在 STDERR 打印 PDF/A-4 requires nextpdf/pro. Run: composer require nextpdf/pro 后以非零退出码结束。如果 verapdf 报告有问题,程序会在打印 veraPDF FAILED — output is not PDF/A-4 conforming 后以非零退出码结束。这里的措辞把判定归于 veraPDF —— NextPDF 本身并不声称 PDF/A-4 一致性。

  • Pro gate。 在仅安装核心包的环境中,enablePdfA() 会抛出 InvalidConfigException。消息会指出 security.pdfa,并提示使用 composer require nextpdf/pro 修正。先查询注册表,才能得到面向操作人员的清晰消息。
  • 加密冲突。 在 PDF/A 文件上调用 setEncryption()useAesGcm()setPublicKeyEncryption(),无论调用顺序如何,都会抛出不兼容异常 —— PDF/A-4 禁止使用 Encrypt trailer 键(ISO 19005-4 §6.6.4)。
  • 一致性变体。 把 Pro 的 PdfAVersion 传给 enablePdfA(),即可选择 4e(工程、3D)或 4f(文件附件)。基本配置文件不会输出 pdfa:conformance 字母;4e/4f 则会设置 E/FConformanceMode 判别器会让 pdfaid:part 保持一致。
  • 标记是独立的。 PDF/A-4 基础变体将标记视为可选。如果要交付同时兼顾无障碍归档的文件,请分别启用标记模式与 PDF/A;请参阅 PDF/UA-2 的 recipe。
  • gate 是验证器。 成功的 save() 只代表产物已输出,并不代表文件符合一致性要求。在验证器通过之前,不要声称符合 PDF/A-4 一致性。

OutputIntent 会增加一个 ICC 配置文件流(sRGB 约数百 KB),外加 XMP 数据包。当文件使用非基本 14 字体时,字体嵌入会成为文件大小的主要来源。对于典型的归档文件,这份 recipe 会维持在 2000 ms / 128 MB 的预算内。适用语义可复现性配置文件:面向验证器的交付物会以结构化 AST 与元数据进行比较,而不是比较原始字节。

归档输出的设计目标就是长期保存并保持自包含。内容中的任何个人数据都会在归档存续期间持续存在。嵌入式 ICC 配置文件与元数据会随文件一同流通。归档前请应用保存与最小化政策。PDF/A-4 没有遮蔽(redaction)语义。

这份 recipe 只会写出一行固定的进度消息。veraPDF 的输出可能包含内容片段 —— 对于含敏感内容的文件,请避免将验证器日志发送到共享的日志聚合端。

PDF/A-4 是归档保真度的配置文件,并非完整性或真实性控制。它不会为文件签名,也不会提供篡改迹象。当你关注 provenance(来源信息)时,请搭配签名一起使用。另有一份 recipe 涵盖签名。按规格要求,加密与 PDF/A 互斥。

这份 recipe 不执行任何密码学运算。FIPS 模式不会改变其行为。PDF/A-4 禁止加密,因此不会选择任何密码算法。

陈述规格条款参考 ID
PDF/A-4 要求一个 OutputIntent,并引用一个嵌入式 ICC 配置文件。ISO 19005-4§6.2.3
通过输出目标配置文件,色彩与设备无关。ISO 19005-4§6.2.4.3
每个字体程序都会被嵌入。ISO 19005-4§6.2.10.4.1
文件在 XMP 中带有 pdfaid 识别信息。ISO 19005-4§6.7.3
PDF/A-4 禁止加密。ISO 19005-4§6.6.4
由验证器而非生成器来判定一致性。ISO 19005-4§6.7.3

NextPDF 生成的是力求符合 PDF/A-4 一致性的输出。**支持不等于一致;经过测试的配置文件不等于认证。**这份 recipe 并不声称一致性;该判定由独立验证器(例如 veraPDF)作出。请把验证器判定作为构建 gate。