跳到內容

封存與 PDF/A

Spec: ISO 19005-4:2020, PDF/A-4 Spec: ISO 19005-2, PDF/A-2 Evidence: Standard-backed

PDF/A 是當一份文件必須在數十年後、面對今日尚不存在的軟體時,仍可讀且能忠實重現,你會採用的格式。 本頁說明這項保證實際涵蓋什麼、NextPDF 如何產生一份符合規範的檔案,以及最常讓團隊感到意外的部分。 產生 PDF/A,以及 證明一份檔案確實是 PDF/A,是兩件不同的工作。 後者仍由你負責。

封存義務通常安靜卻毫不寬容。 檔案在今天看起來沒問題,於是被歸檔。 而失敗——未內嵌的字型、與裝置相依的色彩、加密過的尾段——往往多年後才浮現;那時原始環境已不復存在,也沒有人能重建這份文件原本應有的樣貌。 到那時,代價已不只是重新算繪一次,而是一筆你再也無法信任的紀錄。

PDF/A 之所以存在,正是為了消除這一類失敗。 但「我們用了一套 PDF/A 函式庫」並不等同於「這份檔案符合規範」。 把兩者混為一談, 正是封存庫累積出那些看似已被保存、實際上並非如此的文件的原因。

  • PDF/A 的目的,是讓文件能隨時間以忠實、自我完備且與裝置無關的方式重現——它保存一份文件的靜態視覺外觀,獨立於製作它的工具之外(ISO 19005-2 導論)。
  • 這需要具體的約束:所有字型皆內嵌與裝置無關的色彩(直接指定,或透過輸出意圖;ISO 19005-4 §6.2.4.1),以及尾段中不得加密
  • NextPDF 透過一個明確、需主動啟用的模式來產生 PDF/A,該模式會拒絕不相容的操作,而不是交出一份暗中不符合規範的檔案。
  • 符合性是由檢核工具判定的,而非由產生器宣稱。 即便標準本身也指出,成功封存取決於周邊的封存環境與程序(ISO 19005-4 導論)。 驗證輸出結果,仍是你必須執行的一步。

NextPDF 把 PDF/A 視為文件所處的一種模式,而不是後處理的過濾器。 這個模式必須主動啟用。 一旦啟用,它就會主動守護文件,防範任何會破壞符合性的操作。 其設計原則是快速失敗。 與其交回一份看似可封存、實則不然的檔案,不如明確拒絕一個加密的 PDF/A 要求。

這個情境有四個階段,而第三個正是團隊最常略過的那一個。

  1. Compose for permanence Embed every font, use device-independent colour or an output intent, and avoid features the chosen PDF/A part forbids.
  2. Enable the PDF/A mode Opt in explicitly to the target conformance level. The mode now guards the document against incompatible operations.
  3. Validate independently Run a conformance checker. A passing report — not the producing library — is the evidence the archive needs.
  4. Preserve with procedure Store under records-management policy. The standard itself notes archival success depends on the environment, not the file alone.
從頭到尾的封存情境:引擎產生一份符合規範的候選檔,並拒絕會破壞符合性的操作;由獨立的驗證器交出對封存而言真正重要的裁定。

這個主動啟用是一道真正的防護,而不是一個旗標。 當 PDF/A 模式已啟用,卻又嘗試進行不相容的操作時——例如開啟 AES-GCM 或標準加密處理器——引擎會丟出一個具型別的不相容錯誤。 這道防護在兩種順序下都有效:先啟用 PDF/A 再要求加密,或先要求加密再啟用 PDF/A。 無論哪一種,結果都是明確的拒絕。 ISO 19005 禁止在符合規範的檔案尾段中出現 Encrypt 金鑰, 而引擎將這一點視為具拘束力,而非僅供參考。

這個模式也會讓自身狀態保持誠實。 為某個特定部分啟用 PDF/A(例如選擇位元組忠實層級的 PDF/A-3 而非 PDF/A-4)時,會把文件的符合性判別值設定為相符。 凡是依賴該部分的寫入端關卡,便會看到正確的值,而不是過時的預設值。 正是這種內部一致性,決定了驗證器是否會讓這份檔案通過。

本頁通篇皆屬於標準佐證 Evidence: Standard-backed

目的由標準界定。 Spec: ISO 19005-2 指出 PDF/A 的主要目的是一套用來表述電子文件的機制,使其靜態視覺外觀能隨時間保存,並獨立於所使用的工具與系統之外。 而約束則由此衍生: Spec: ISO 19005-4:2020, §6.2.4.1 要求色彩須以與裝置無關的方式指定,直接指定或透過 PDF/A 輸出意圖。 字型要求則由基礎格式所強化—— Spec: ISO 32000-2:2020, §9 指出最可預期、 最可靠的算繪,會在所有字型皆內嵌時發生,而這正是封存庫不可或缺的性質。

這個邊界同樣寫在標準裡,而不只是一句編輯上的提醒。 Spec: ISO 19005-4:2020 在其導論中指出, 針對封存目的的成功實作,取決於組織的封存環境、紀錄管理政策,以及其他持久保存的條件。 符合性是由檢核工具依標準的規範性要求來判定的——而非由產生器宣告。

引擎行為則有程式碼佐證 Evidence: Code-backed Document::enablePdfA() 是一個明確的主動啟用;當加密與 PDF/A 組合在一起時,不論順序為何,便會丟出一個具型別的不相容錯誤, 並讓文件的符合性判別值與所選部分保持同步一致。

下方的程式碼展示了邊界處的防護行為。 其中 PDF/A 模式本身屬於 Premium 層級的功能。 而符合性檢核則是一道獨立且分離的步驟。

<?php
declare(strict_types=1);
use NextPDF\Contracts\PdfDocumentInterface;
use NextPDF\Security\Exception\IncompatiblePdfAModeException;
/**
* Produce an archival candidate, then prove it independently.
*
* The engine refuses conformance-breaking combinations; it does NOT
* certify the result. A validator does that.
*
* @param PdfDocumentInterface $doc A document with all fonts embedded
* @param object $pdfaLevel The target PDF/A version (Premium enum)
*
* @return string The archival candidate's bytes — not yet a verified PDF/A
*/
function buildArchivalCandidate(
PdfDocumentInterface $doc,
object $pdfaLevel,
): string {
try {
// Opt in explicitly. From here the mode guards the document.
$doc->enablePdfA($pdfaLevel);
} catch (IncompatiblePdfAModeException $e) {
// e.g. encryption was already requested — refused, not silently
// downgraded into a non-conforming "archival" file.
throw new \RuntimeException(
'PDF/A and encryption are mutually exclusive for a conforming '
. 'file; resolve before archiving.',
previous: $e,
);
}
$bytes = $doc->getPdfData();
// The step teams skip: this is a CANDIDATE. Run an independent
// conformance validator before treating it as a preserved record.
return $bytes;
}

回傳值上的那行註解,正是這裡的重點。 函式名稱刻意用了候選(candidate)這個字。 引擎產出了一份應當符合規範的檔案。 唯有檢核工具,才能把「應當」變成證據。

有一個誤解讓封存庫塞滿了其實未被保存的文件:「函式庫說它是 PDF/A,所以這份檔案就是 PDF/A。」 但這個裁定並非函式庫所能給予。 一個產生器可以產出一份意圖符合規範的檔案,卻仍然漏掉某項規範性要求。 符合性是由驗證工具依標準判定的。 稽核人員或未來的讀者所倚賴的,正是那項判定。 把產生函式庫的意圖當成證明,正是這裡的核心錯誤。

第二個更不易察覺的陷阱:以為光靠 PDF/A 就能保存文件。 標準本身就把封存的成功,繫於周邊的環境與程序。 一份符合規範的檔案,若放在一個欠缺紀律的儲存庫中,仍然處於風險之中。 這個格式是必要的,卻不充分。

  • NextPDF 產生的是一份符合規範的候選檔;它並不認證符合性。 請執行獨立的驗證器。 通過的報告才是證據,而非產生檔案的函式庫。
  • PDF/A 的符合性模式屬於 Premium 層級的功能。 Core 產出純粹的 PDF 2.0,並提供一條可付諸行動的升級路徑。 它不提供 PDF/A 的保證。 請參閱下方的邊界說明。
  • PDF/A 與加密,對一份符合規範的檔案而言是互斥的。 引擎會以任一順序拒絕這種組合,而不是悄悄地降級。
  • 引擎無法內嵌你未提供的字型,也無法修正你所提供、與裝置相依的色彩。 為求永久保存而進行編排——內嵌字型、與裝置無關的色彩——是輸入端的責任。
  • 封存的持久性取決於流程,而非僅靠檔案本身。 ISO 19005 把組織的留存與紀錄管理程序,納為成功保存的一部分。
  • 就 Premium 範圍而言,本頁是標準佐證且屬於行為層級的內容。 它不主張任何認證,也不授予任何認證。
PDF/A archival conformance — edition availability
Edition Availability
Core

Core 只產出純粹的 PDF 2.0。 enablePdfA() 會丟出一個可付諸行動的升級錯誤,指向商業套件。 不存在僅靠 Core 的 PDF/A 保證。

Pro

提供 PDF/A 符合性模式(包含位元組忠實的 PDF/A-3 層級與 PDF/A-4),並附帶加密不相容防護。

Enterprise

增設一套結構化的 PDF/A 符合性政策與報告(仍然屬於結構檢核,而非認證——最終判定屬於驗證器與你的合規團隊)。

  • 字型:最難的部分——為什麼看似正確的字型,仍可能讓檔案不符合規範或無法搜尋。
  • 黃金檔測試——固定的參考輸出如何捕捉那些悄悄破壞封存保證的位元組偏移。
  • 發票與電子發票——最接近的相鄰主題:一個混合式發票載體本身就是一份 PDF/A 檔案。
  • PDF/A——ISO 19005 系列:一套用於長期保存的受限 PDF 設定檔,設計用以隨時間重現一份文件的靜態外觀,且獨立於產生它的工具之外。
  • 符合性層級/部分——特定的 PDF/A 變體(例如 PDF/A-2PDF/A-3PDF/A-4 及其子層級);各自約束可使用的 PDF 功能。
  • 輸出意圖——一個內嵌的色彩特性化設定檔,讓與裝置相依的色彩能以與裝置無關的方式被解讀。
  • 與裝置無關的色彩——以某種方式指定,使其無論在何種算繪裝置上都能一致重現的色彩,這是 PDF/A 的要求。
  • 符合性檢核器/驗證器——獨立軟體,依標準的規範性要求評斷一份檔案;它是符合性裁定的來源。
  • 封存候選檔——一份意圖符合規範而產出的檔案,尚待獨立驗證器確認其確實符合規範。