フォームフィールドを静的なページコンテンツにフラット化する
このレシピでは、インタラクティブな AcroForm をフラット化します。各フィールドの現在値を通常のグラフィックスとしてページコンテンツストリームに描画し、その後 AcroForm ディクショナリを削除します。結果は、フォームフィールドの静的な表現である非インタラクティブなフォームです。フォームをサポートしないリーダーを含め、どの環境でも同じように表示されます(ISO 32000-2 §12.7)。このレシピでは、examples/30-form-fields.php でフォームを構築し、その後 flattenForms() を呼び出します。
インストール
「インストール」という見出しのセクションcomposer require nextpdf/core:^3概念の概要
「概念の概要」という見出しのセクションフラット化では、各ウィジェットを対応するページに「印刷」します。テキストフィールドは BT … Tj … ET のテキストになります。チェックボックスとラジオボタンは描画パスになります。選択フィールドは選択された項目を描画します。プッシュボタンは静的なボタン状のボックスを描画します。これは、フィールドの内容が事前に分かっている場合に使用される、静的に定義された外観という仕様上のモデルに一致します(ISO 32000-2 §12.7)。値が焼き込まれるため、非推奨の NeedAppearances の仕組みは必要ありません。
プロファイルは structural です。ドキュメントにはトレーラーの /ID が含まれており、ポストパスは 2 回の実行結果を比較する前にこれを正規化します。
API の概要
「API の概要」という見出しのセクションNextPDF\Core\Concerns\HasFormFields::flattenForms(): static は、ドキュメント上に作成されたすべてのフィールドを静的なページコンテンツへフラット化し、AcroForm を削除します。フィールドが存在しない場合は何も行いません。内部的には、この処理を NextPDF\Form\FormFlattener に委譲します。
フィールドコンストラクターを使ってフォームを構築します。手順については、PDF フォームの構築と事前入力を参照してください。その後、save() の前に flattenForms() を呼び出します。
コードサンプル — クイックスタート
「コードサンプル — クイックスタート」という見出しのセクション<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Flattened Form');$doc->addPage();
$doc->textField(name: 'full_name', x: 20, y: 30, w: 90, h: 8, default: 'Ada Lovelace');$doc->checkBox(name: 'agree', x: 20, y: 45, size: 5, checked: true);
// Bake the field values into the page; the AcroForm is removed.$doc->flattenForms();
$doc->save(__DIR__ . '/flattened.pdf');echo "Wrote flattened.pdf (no interactive fields)\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 — Flattened');$doc->addPage();
$doc->setFont('helvetica', 'B', 20);$doc->cell(0, 14, 'Customer Registration (read-only copy)', newLine: true);$doc->ln(4);
$leftMargin = 15.0;$fieldX = 70.0;$fieldW = 120.0;$fieldH = 8.0;$rowSpacing = 12.0;
$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); $y += $rowSpacing;}
$y += 6;$doc->setXY($leftMargin, $y);$doc->cell(0, 7, 'Newsletter');$doc->checkBox(name: 'newsletter', x: $leftMargin + 70, y: $y, size: 5, checked: true);
// Flatten: widgets become static page content; the AcroForm is dropped.$doc->flattenForms();
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');$doc->save($out !== false ? $out : __DIR__ . '/registration-flattened.pdf');
echo "Wrote flattened registration form\n";期待される出力:
Wrote flattened registration form出力には同じ値が表示されますが、インタラクティブなフィールドはありません。フォームをサポートしないリーダーでも、同じように描画されます。
エッジケースと注意点
「エッジケースと注意点」という見出しのセクション- フラット化は元に戻せません。 一度
save()を呼び出すと、インタラクティブなフィールドは失われます。後で値を編集する可能性がある場合は、フラット化していないソースを保管しておいてください。 - 呼び出しの順序。
flattenForms()は、フィールドを作成した後、save()の前に実行します。フィールドがない状態で呼び出しても何も行われず、安全です。 - 署名フィールドはフラット化されません。
/Sigフィールドの視覚的な表示面は、その CMS SignedData から生成された外観であり、再描画可能な値ではありません。これを再ラスタライズすると、検証可能な署名と一致しない静的な「ゴースト」グラフィックが作成されてしまいます。そのため、フラット化処理は意図的に署名フィールドをスキップします。フォームのフラット化は署名する前に行い、署名後には決して行わないでください。 - チェックボックスの真偽判定。 チェックボックスは、その値が
Yes/On/1/trueの場合にチェックマークを描画します。空の値またはOffの値の場合は、ボックスのみを描画します。 - フラット化されたテキストのフォント。 フラット化されたテキストは現在のフォントを使用します。フォントが設定されていない場合は、Helvetica にフォールバックします。CJK やカスタムフォントのフィールド値の場合は、
flattenForms()の前に使用したいフォントを設定してください。
パフォーマンス
「パフォーマンス」という見出しのセクションフラット化はフィールド数に対して線形にスケールします。各フィールドについて、有界なコンテンツブロックを追加し、その後 AcroForm オブジェクトを削除します。一般的なフォームでは、1500 ms / 64 MB の予算に十分収まります。
セキュリティに関する注意
「セキュリティに関する注意」という見出しのセクションフラット化により、通常のリーダーではフィールドの値を編集できなくなります。これは表示上の変更であり、アクセス制御ではありません。値はページコンテンツ内に表示されたままであり、任意のテキストツールで抽出できます。フラット化を、墨消し(編集による削除)や機密値の保護として扱わないでください。機密性を確保するには、権限付きで暗号化するを使用してください。権限ビットも読み取り制限を強制しないため、そちらのリーダー依存に関する注意事項も併せてお読みください。署名済みのドキュメントを決してフラット化しないでください。先にフラット化してから署名します。
| 記述 | 仕様 | 箇条 | リファレンス ID |
|---|---|---|---|
| フラット化されたフォームは、フィールドの非インタラクティブ(静的)な表現。 | ISO 32000-2 | §12.7 | |
| 内容が事前に分かっている場合の、フィールド外観の静的定義。 | ISO 32000-2 | §12.7 | |
焼き込まれた外観による、非推奨の NeedAppearances フラグの不要化。 | ISO 32000-2 | §12.7 |
NextPDF は、引用された箇条で説明されている静的な構造を生成します。これは ISO 32000-2 への全面的な準拠を主張するものではありません。