ドキュメントの自動処理ワークフローにおいて、PDF フォームを扱う必要が生じることは少なくありません。フォーム入力後、内容の意図しない変更を防ぎ、リーダー間で表示が一致するようにするため、フォームフィールドを「フラット化」(Flatten)することが一般的です。本記事では、Python を用いてこの操作を実装する方法を紹介します。
1. フォームフィールドのフラット化とは
PDF フォームフィールドは本質的には対話型の注釈(インタラクティブ・アノテーション)であり、ページコンテンツストリームとは独立して存在します。ユーザーは PDF リーダー上でクリック、入力、または選択してフィールドの値を変更できます。
フラット化とは、これらの対話型フォームフィールドを、ページ上の静的なグラフィックコンテンツに変換することです。フラット化後は以下の特徴があります。
- フォームフィールドは編集不可、クリック不可になる
- フィールド値がページコンテンツストリームに「描画」され、通常のテキストとして埋め込まれる
- ドキュメントサイズが縮小されることが多い
- あらゆる PDF リーダーで一貫した表示が保証される
簡単に言えば、「記入可能なフォーム」を「読み取り専用のドキュメント」に変える操作です。
2. 適用シーン
以下のようなシーンでフォームのフラット化が求められます。
- アーカイブ保存:フォーム記入後の原本として、内容の改ざんを防止する
- 配布・公開:記入済みフォームを外部に公開する際、受取側による誤編集を防ぐ
- 形式変換:PDF を画像や Word などに変換する前にフラット化し、フィールドの欠落を回避する
- 印刷出力:印刷時に全てのフィールド内容が正しくレンダリングされるようにする
- 署名前の処理:デジタル署名前にフラット化することで、署名後にフォーム操作が原因で検証が無効になるのを防ぐ
3. 環境準備
本記事では、無料ライブラリ Free Spire.PDF for Python を使用してフォームフィールドのフラット化を実装します。これは Adobe Acrobat 環境に依存しないスタンドアロンの PDF 処理ライブラリです。
インストール
pip install Spire.PDF.Free
インストール完了後、Python スクリプトからインポートして使用できます。無料版では 1 ドキュメントあたり 10 ページの制限があることにご注意ください。
4. コア実装
4.1 PDF 内の全フォームフィールドをフラット化
最も一般的なニーズは、ドキュメント内の全てのフォームフィールドを一度にフラット化することです。
from spire.pdf.common import *
from spire.pdf import *
# 入力ファイルと出力ファイルのパスを指定
input_file = "フォーム.pdf"
output_file = "フラット化結果_全フィールド.pdf"
# PdfDocument オブジェクトを作成し、PDFファイルを読み込む
pdf = PdfDocument()
pdf.LoadFromFile(input_file)
# IsFlatten を True に設定し、全てのフォームフィールドをフラット化
pdf.Form.IsFlatten = True
# 結果を保存
pdf.SaveToFile(output_file)
pdf.Close()
核心はたった 1 行、pdf.Form.IsFlatten = True です。このコードにより、ドキュメント内の全フィールドが走査されフラット化されます。
4.2 PDF 内の特定フォームフィールドのみをフラット化
特定の 1 つまたは複数のフィールドだけをフラット化し、その他のフィールドは編集可能な状態に保ちたい場合があります。その場合は PdfField.Flatten プロパティを使用します。
from spire.pdf.common import *
from spire.pdf import *
input_file = "フォーム.pdf"
output_file = "フラット化結果_特定フィールド.pdf"
pdf = PdfDocument()
pdf.LoadFromFile(input_file)
# PDF 内のフォームコレクションを取得
loadedForm = pdf.Form
# PdfFormWidget に変換して個別フィールドにアクセス
formWidget = PdfFormWidget(loadedForm)
# インデックスを指定して 2 番目のフォームフィールドを取得(インデックスは 0 から始まる)
form = formWidget.FieldsWidget.get_Item(1)
# そのフォームフィールドをフラット化
form.Flatten = True
pdf.SaveToFile(output_file)
pdf.Close()
form.Flatten = True を設定することで、単一フィールドに対してフラット化を実行でき、他のフィールドは対話機能を維持します。
4.3 指定した複数フィールドを一括フラット化
複数の特定フィールドをフラット化する必要がある場合は、ループまたは個別処理で対応します。
# フラット化するフィールド名のリスト
target_fields = ["氏名", "身分証番号", "署名"]
for field_name in target_fields:
try:
form = formWidget.FieldsWidget.get_Item(field_name)
form.Flatten = True
except Exception as e:
print(f"フィールド '{field_name}' のフラット化に失敗: {e}")
5. まとめ
本記事では、無料の Python ライブラリを使用して PDF フォームフィールドをフラット化する 2 つの方法を紹介しました。
| 方法 | 適用シーン | コアプロパティ/メソッド |
|---|---|---|
| 全フィールドのフラット化 | 全フォームデータのアーカイブ、固定化 | pdf.Form.IsFlatten = True |
| 特定フィールドのフラット化 | 一部フィールドのみ固定し、他は編集可能に維持 | form.Flatten = True |
いずれの方法も、PDF 読み込み → フラット化プロパティ設定 → 保存 というシンプルなフローであり、コードは簡潔で自動化ワークフローへの統合が容易です。
実際のプロジェクトでは、この機能をドキュメントワークフローに組み込み、フォーム処理チェーンの最終段階として活用することで、配布されるドキュメントのフォーマットの安定性と内容の不変性を確保できます。
