PDF(Portable Document Format)は、WYSIWYG(What You See is What You Get)形式ではありません。
プラットフォームに依存せず、基盤となるオペレーティングシステムやレンダリングエンジンに依存しないように開発されました。
これを実現するために、PDFはプログラミング言語のようなもので操作できるように構築されており、結果を得るためには一連の命令と操作に依存することになります。
実際、PDFはスクリプト言語であるPostScriptをベースにしています。
PostScriptは、デバイスに依存しない最初のページ記述言語でした。
このガイドでは、PDF文書の読み取り、操作、生成に特化したPythonライブラリであるborbを使用します。
borbは、低レベルモデル(正確な座標やレイアウトにアクセスできる)と高レベルモデル(余白や位置などの正確な計算をレイアウトマネージャーに委ねることができる)の両方を提供します。
>
このガイドでは、記入可能なフォームを持つPDFを生成する方法を見ていきます。
borbのインストール
borbはGitHubのソースからダウンロードするか、pip
経由でインストールすることができます。
$ pip install borb
borb による PDF 文書の生成
さて、borb
がインストールされたので、ビルディングブロックをインポートして、簡単なPDFページを構築してみましょう。
from borb.pdf.document import Document
from borb.pdf.page.page import Page
from borb.pdf.pdf import PDF
from borb.pdf.canvas.layout.page_layout.multi_column_layout import SingleColumnLayout
from borb.pdf.canvas.layout.page_layout.page_layout import PageLayout
次のコードは、borb
を使ってPDFドキュメントを作成する基本的なステップを表しています。
- 空のドキュメントを作成する
空のドキュメントを作成する * 空のページを作成する
空のドキュメントを作成する * ページをドキュメントに追加する
空のドキュメントを作成する * 空のページを作成する * ドキュメントにページを追加する * コンテンツのフローを処理するPageLayoutを作成する (ここではSingleColumnLayoutを使用します) - PageLayout にコンテンツを追加する。
- ドキュメントをディスクに永続化する
それでは、Document
を作成してみましょう。
# Create empty Document
pdf = Document()
# Create empty Page
page = Page()
# Add Page to Document
pdf.append_page(page)
# Create PageLayout
layout: PageLayout = SingleColumnLayout(page)
最初のステップを終えたら、コンテンツを追加していきましょう。
この例では、記入可能なフォームを作成します。
ここでは、名前、苗字などの基本的なユーザー情報の質問を含むフォームを作成します。
- 名前
- 苗字
- 性別
- 居住地
- 国籍
すべてが正しくレイアウトされるように、この内容を Table
に追加します。
左側のカラムにはフィールド名(例:”name”、”surname”)、右側のカラムには入力されるフィールドが入ります。
さらに、フォームのすぐ上に、注釈を付けるための Paragraph
をもう一つ追加します。
# New import(s)
from borb.pdf.canvas.layout.table.fixed_column_width_table import FixedColumnWidthTable
from borb.pdf.canvas.layout.text.paragraph import Paragraph
from borb.pdf.canvas.layout.forms.text_field import TextField
from borb.pdf.canvas.color.color import HexColor
from decimal import Decimal
from borb.pdf.canvas.layout.layout_element import Alignment
from borb.pdf.canvas.layout.forms.drop_down_list import DropDownList
# Let's start by adding a heading
layout.add(Paragraph("Patient Information:", font="Helvetica-Bold"))
# Use a table to lay out the form
table: FixedColumnWidthTable = FixedColumnWidthTable(number_of_rows=5, number_of_columns=2)
# Name
table.add(Paragraph("Name : ", horizontal_alignment=Alignment.RIGHT, font_color=HexColor("56cbf9")))
table.add(TextField(value="Doe", font_color=HexColor("56cbf9"), font_size=Decimal(20)))
# Surname
table.add(Paragraph("Surname : ", horizontal_alignment=Alignment.RIGHT, font_color=HexColor("56cbf9")))
table.add(TextField(value="John", font_color=HexColor("56cbf9"), font_size=Decimal(20)))
これらのインプットフィールドは TextField
で、文字列を渡すことができます。
ここでは、性別のフィールドをドロップダウンリストとしてモデル化し、そこから読者が4つの選択肢のうちの1つを選ぶことができるようにするつもりです。
- 女性
- 男性
- その他
- 開示しない
では、borb
にどのように変換されるか見てみましょう。
# Gender
table.add(Paragraph("Gender : ", horizontal_alignment=Alignment.RIGHT))
table.add(DropDownList(
possible_values=[
"Female",
"Male",
"Other",
"Prefer not to disclose",
]
))
居住国や国籍についても同じようなことができますが、世界中のすべての国のリストを見つけて、 DropDownList
のコンストラクタに渡す必要があります。
これは、十分に長いリストであれば、どのようなものでも構いません。
この特定のフィールド (すべての国のリスト) は非常に一般的な要件なので、 borb
には CountryDropDownList
クラスがあらかじめ含まれています。
# New import(s)
from borb.pdf.canvas.layout.forms.country_drop_down_list import CountryDropDownList
# Country of Residence
table.add(Paragraph("Country of Residence : ", horizontal_alignment=Alignment.RIGHT))
table.add(CountryDropDownList(value="Belgium"))
# Nationality
table.add(Paragraph("Nationality : ", horizontal_alignment=Alignment.RIGHT))
table.add(CountryDropDownList(value="Belgium"))
これでようやく、Table
を PageLayout
に追加することができます。
# Set some properties on the table to make the layout prettier
table.set_padding_on_all_cells(Decimal(5), Decimal(5), Decimal(5), Decimal(5))
table.no_borders()
# Adding Table to PageLayout
layout.add(table)
それでは、(無意味な)データ保護ポリシーを追加してみましょう。
# Data protection policy
layout.add(Paragraph("Data Protection Policy",
font="Helvetica-Bold"))
# Dummy text
layout.add(Paragraph(
"""
** Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
""",
font="Helvetica-Oblique"
))
最後にフッターを追加して、物事を締めくくりましょう。
今のところ、ページの下にアクセントカラーで塗りつぶした長方形を追加するだけです。
あまり派手なことはしないでください。
# New import(s)
import typing
from borb.pdf.canvas.geometry.rectangle import Rectangle
from borb.pdf.page.page_size import PageSize
from borb.pdf.canvas.line_art.line_art_factory import LineArtFactory
from borb.pdf.canvas.layout.image.shape import Shape
ps: typing.Tuple[Decimal, Decimal] = PageSize.A4_PORTRAIT.value
r: Rectangle = Rectangle(Decimal(0), Decimal(32), ps[0], Decimal(8))
Shape(points=LineArtFactory.rectangle(r), stroke_color=HexColor("56cbf9"), fill_color=HexColor("56cbf9")).layout(page, r)
最後に、PDF
クラスを使って作成した Document
を保存します。
# New import(s)
from borb.pdf.pdf import PDF
# Store
with open("output.pdf", "wb") as out_file_handle:
PDF.dumps(out_file_handle, pdf)
最終的にこれはどのように見えるのでしょうか?コードを実行してPDFファイルを作成すると、いくつかの空のフィールドを持つことになります。
これらのフィールドを選択することで、キーボードを使って詳細を入力することができます。
結論
このガイドでは、PDFにフォーム要素を含める方法を学び、読者がPDFと対話することを可能にしました。