表單扁平化¶
表單扁平化(Form Flattening)將互動式 AcroForm 欄位的當前填寫內容「燒錄」到頁面內容串流中,生成不可再編輯的靜態 PDF。常用於歸檔已完成的表單、防止表單內容被篡改,以及確保在不支援 AcroForm 的閱讀器中正確顯示。
基本扁平化¶
use NextPDF\Form\FormFlattener;
use NextPDF\Form\FlattenOptions;
use NextPDF\Form\FlattenResult;
$flattener = FormFlattener::create();
$result = $flattener->flatten(
sourcePdf: file_get_contents('/path/to/filled-form.pdf'),
options: FlattenOptions::default(),
);
if ($result->isSuccess()) {
file_put_contents('/path/to/static.pdf', $result->getPdfBytes());
}
FlattenResult¶
use NextPDF\Form\FlattenResult;
use NextPDF\Form\FlattenStatus;
$result = $flattener->flatten(sourcePdf: $pdfBytes);
// 檢查結果
echo $result->getStatus()->value; // success | partial | failed
echo $result->getFlattenedCount(); // 成功扁平化的欄位數
echo $result->getSkippedCount(); // 跳過的欄位數
// 查看跳過的欄位與原因
foreach ($result->getSkippedFields() as $field) {
echo $field->getName() . ': ' . $field->getSkipReason();
}
// 取得輸出 PDF
$flatPdfBytes = $result->getPdfBytes();
選擇性扁平化¶
use NextPDF\Form\FlattenOptions;
// 只扁平化特定欄位
$result = $flattener->flatten(
sourcePdf: $pdfBytes,
options: FlattenOptions::create(
fields: ['firstName', 'lastName', 'email'], // 僅扁平化指定欄位
skipSignatureFields: true, // 保留簽章欄位(不扁平化)
skipEmptyFields: false, // 即使空白也扁平化
),
);
// 扁平化所有欄位除了指定欄位
$result = $flattener->flatten(
sourcePdf: $pdfBytes,
options: FlattenOptions::create(
excludeFields: ['digitalSignature'],
),
);
扁平化品質設定¶
$options = FlattenOptions::create(
renderQuality: RenderQuality::High, // Low | Medium | High | Print
fontEmbedding: true, // 確保扁平化後的文字使用嵌入字型
preserveAnnotations: true, // 保留非表單的標注(如:連結、備註)
);
扁平化後的簽章保護¶
// 若 PDF 含有有效的數位簽章,扁平化時必須特別處理
$options = FlattenOptions::create(
signatureHandling: SignatureHandling::PreserveValidity,
// PreserveValidity: 增量更新(不破壞現有簽章的 ByteRange)
// Strip: 移除所有簽章(扁平化整份文件)
);
批量扁平化¶
// 批量處理多份表單 PDF
$results = $flattener->flattenBatch(
sources: [
'/path/to/form1.pdf',
'/path/to/form2.pdf',
'/path/to/form3.pdf',
],
options: FlattenOptions::default(),
outputDir: '/path/to/output/',
);
foreach ($results as $filename => $result) {
if (!$result->isSuccess()) {
logger()->error("Failed to flatten {$filename}", ['result' => $result]);
}
}