建立並預先填入 PDF 表單
AcroForm 是 PDF 內的互動式表單。這則 recipe(範例)會建立一份表單,並為各欄位預先填入初始值。核心的 HasFormFields trait 是表單編寫(authoring)API:你會在同一次呼叫中建立每個欄位,並提供它的值。文字欄位使用 default 引數,選項欄位使用 selected,核取方塊則使用 checked。開啟 PDF 時,各欄位都已經填好值,而且在符合規範的閱讀器中仍可編輯。任何開啟檔案的人仍然可以更改這些值。這則 recipe 取自 examples/30-form-fields.php。
適用範圍界線。 核心在建立文件時會建立並填入表單欄位, 而不是事後另行處理。它不會讀取已存在於第三方 PDF 中的表單, 也不會把一份值對映表合併進去。在這裡,「填入」指的是帶著值編寫表單, 而不是載入並填寫一份外部 PDF。對外部表單做來回轉換(round-trip)屬於 Premium 與伺服器端的能力,而非核心的公開 API。
composer require nextpdf/core:^3概念說明
標題為「概念說明」的區段AcroForm 欄位會將目前值存放在欄位字典的 V 項目中(ISO 32000-2 §12.7)。它也可以在 DV 中存放一個選用的預設值;執行重設表單動作時,欄位就會回到這個值。NextPDF 會用你傳給每個欄位建構式的值來設定 V。文字的繪製會使用一個預設外觀字串(DA)。
這個設定檔之所以是 structural,是因為文件帶有一個 trailer /ID 陣列。後處理階段會在比較前先正規化那個易變的識別碼。
API 介面
標題為「API 介面」的區段NextPDF\Core\Concerns\HasFormFields(混入 Document):
textField(string $name, float $x, float $y, float $w, float $h, string $default = '', array $options = []): staticcheckBox(string $name, float $x, float $y, float $size, bool $checked = false): staticradioButton(string $name, float $x, float $y, float $size, string $value, string $group): staticcomboBox(string $name, float $x, float $y, float $w, float $h, array $items, string $selected = ''): staticlistBox(string $name, float $x, float $y, float $w, float $h, array $items, string $selected = ''): staticbutton(string $name, float $x, float $y, float $w, float $h, string $caption, string $action = ''): static
其中 default、checked 與 selected 引數會帶入預先填入的值。
程式碼範例 — 快速上手
標題為「程式碼範例 — 快速上手」的區段<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Pre-filled Form');$doc->addPage();
// Text field pre-filled with a value (sets the field dictionary /V entry).$doc->textField(name: 'full_name', x: 20, y: 30, w: 90, h: 8, default: 'Ada Lovelace');
// Choice field pre-selected.$doc->comboBox( name: 'country', x: 20, y: 45, w: 90, h: 8, items: ['United Kingdom', 'Taiwan', 'Japan'], selected: 'Taiwan',);
// Checkbox pre-checked.$doc->checkBox(name: 'newsletter', x: 20, y: 60, size: 5, checked: true);
$doc->save(__DIR__ . '/prefilled-form.pdf');echo "Wrote prefilled-form.pdf\n";程式碼範例 — 正式版
標題為「程式碼範例 — 正式版」的區段以下完整範例對應 examples/30-form-fields.php,是一份含有數個區段的註冊表單。它會寫入 NEXTPDF_COOKBOOK_OUTPUT,供測試載具使用。
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Customer Registration — Pre-filled');$doc->addPage();
$doc->setFont('helvetica', 'B', 20);$doc->cell(0, 14, 'Customer Registration Form', newLine: true);$doc->ln(4);
$leftMargin = 15.0;$fieldX = 70.0;$fieldW = 120.0;$fieldH = 8.0;$rowSpacing = 12.0;
// --- Personal information, pre-filled ---$prefill = [ 'full_name' => 'Ada Lovelace', 'phone' => '+44 20 7946 0000', 'company' => 'Analytical Engines Ltd',];
$y = 40.0;$doc->setFont('helvetica', '', 10);foreach ($prefill as $name => $value) { $doc->setXY($leftMargin, $y); $doc->cell(50, $fieldH, ucwords(str_replace('_', ' ', $name)) . ':'); $doc->textField( name: $name, x: $fieldX, y: $y, w: $fieldW, h: $fieldH, default: $value, options: ['maxLen' => 80], ); $y += $rowSpacing;}
// --- Choice field, pre-selected ---$y += 6;$doc->setXY($leftMargin, $y);$doc->cell(50, $fieldH, 'Country:');$doc->comboBox( name: 'country', x: $fieldX, y: $y, w: $fieldW, h: $fieldH, items: ['United States', 'United Kingdom', 'Germany', 'Japan', 'Taiwan'], selected: 'United Kingdom',);
// --- Checkboxes, pre-set ---$y += $rowSpacing + 6;$doc->setXY($leftMargin, $y);$doc->cell(0, 7, 'Subscribe to newsletter');$doc->checkBox(name: 'newsletter', x: $leftMargin + 70, y: $y, size: 5, checked: true);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');$doc->save($out !== false ? $out : __DIR__ . '/registration-prefilled.pdf');
echo "Wrote pre-filled registration form\n";預期輸出:
Wrote pre-filled registration form當你開啟 PDF 時,每個欄位都已經填好值,而且仍可編輯。
邊界情況與陷阱
標題為「邊界情況與陷阱」的區段- 欄位名稱必須唯一。 兩個共用同一名稱的欄位,在符合規範的閱讀器中會變成一個共享值的邏輯欄位。對連動欄位來說,這正是你要的結果,但在其他情況下會是意外。
- 單選群組語意。
radioButton()會把每個選項繫結到一個group。被選取的選項,就是其value與群組值相符的那一個。同一時間每個群組只會有一個選項處於開啟狀態。 maxLen只是一個提示。maxLen選項會在符合規範的閱讀器中限制輸入長度。它並不會限制你預先填入的儲存值。- API 中的座標以左上角為基準。 這個 trait 會替你轉換成 PDF 的左下角原點,所以請依範例所示傳入左上角座標。
- 不支援填寫外部 PDF。 核心不提供任何方法來載入既有的第三方表單並套用值對映表。請參見上方的適用範圍界線。
表單編寫的效能會隨欄位數量線性成長。每個欄位會新增一個 widget 註解與一份外觀。數百個欄位仍遠在 1500 ms / 64 MB 的預算之內。
安全性說明
標題為「安全性說明」的區段預先填入的值會原封不動地寫進欄位字典。在把任何來自不受信任來源的值放進你要散布的文件之前,必須先對它進行逸出或驗證。預先填入的表單並未受到保護:任何能開啟該 PDF 的人都可以讀取並更改其中的值。當表單內容屬於敏感資訊時,請把這則 recipe 與 使用權限加密搭配使用,並留意該處關於閱讀器需配合的告誡。
符合性
標題為「符合性」的區段| 陳述 | 規範 | 條款 | 參考 ID |
|---|---|---|---|
欄位的目前值儲存在欄位字典的 V 項目中。 | ISO 32000-2 | §12.7 | |
預設值儲存在 DV 項目中,並會在表單重設時還原。 | ISO 32000-2 | §12.7 | |
欄位文字格式化使用預設外觀字串 DA。 | ISO 32000-2 | §12.7 |
NextPDF 會輸出所引用條款所描述的 AcroForm 結構。它並未聲稱完全符合 ISO 32000-2。