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ドキュメントを作るには、通常、同じような2、3のステップを踏みます。
- 空の
Document
を作成する。
空のDocument
を作成する * 空のPage
を作成し、Document
に追加する
空のPage
を作成してDocument
に追加する *Page
にPageLayout
を設定する -
PageLayout
にコンテンツを追加する -
Document
を永続化する
コードでどのように見えるか見てみましょう。
from borb.pdf.document import Document
from borb.pdf.page.page import Page
from borb.pdf.canvas.layout.page_layout.multi_column_layout import SingleColumnLayout
from borb.pdf.canvas.layout.page_layout.page_layout import PageLayout
from borb.pdf.pdf import PDF
def main():
# Create empty Document
pdf = Document()
# Create empty Page
page = Page()
# Add Page to Document
pdf.append_page(page)
# Create PageLayout
layout: PageLayout = SingleColumnLayout(page)
# Future content-rendering-code to be inserted here
# Attempt to store PDF
with open("output.pdf", "wb") as pdf_file_handle:
PDF.dumps(pdf_file_handle, pdf)
if __name__ == '__main__':
main()
borbでPDFフライヤーを作成する方法
さて、空のキャンバスができたので、基本的な内容を追加してみましょう。
まず、「貴社」のようなタイトルを追加します。
# New imports
from borb.pdf.canvas.layout.text.paragraph import Paragraph
from borb.pdf.canvas.color.color import HexColor
from decimal import Decimal
# Contact information
layout.add(
Paragraph("Your Company",
font_color=HexColor("#6d64e8"),
font_size=Decimal(20)
)
)
次に、QRコードと連絡先情報を追加します。
これらのコンテンツを簡単に並べて表示するために、Table
を使用します。
また、QRコードの座標も必要です(後で特別なものを追加する予定です)。
まずはそれを宣言することから始めましょう。
# New imports
from borb.pdf.canvas.layout.image.barcode import Barcode, BarcodeType
from borb.pdf.canvas.layout.layout_element import LayoutElement
# Code to generate a QR code LayoutElement
qr_code: LayoutElement = Barcode(
data="https://www.borbpdf.com",
width=Decimal(64),
height=Decimal(64),
type=BarcodeType.QR,
)
これでTable
を構築して追加することができます。
# New imports
from borb.pdf.canvas.layout.table.flexible_column_width_table import FlexibleColumnWidthTable
layout.add(
FlexibleColumnWidthTable(number_of_columns=2, number_of_rows=1)
.add(qr_code)
.add(
Paragraph(
"""
500 South Buena Vista Street
Burbank CA
91521-0991 USA
""",
padding_top=Decimal(12),
respect_newlines_in_text=True,
font_color=HexColor("#666666"),
font_size=Decimal(10),
)
)
.no_borders()
)
このコードを実行して、生成されたPDFがどのように見えるか見てみましょう。
UI/UXの細かい部分を調整するのに最適な方法だと思います。
いい感じですね。
QRコードは会社名のすぐ下にあり、正しい連絡先情報を含み、実際に私たちが提供した連絡先データをエンコードしています。
>
次に、リモート・ゴーイング・アノテーションを追加します。
これは、PDF用語で「PDFの外に出るためのクリック可能なリンク」という意味です。
QRコード全体が、実際に読者を当社のウェブサイトに導くリンクであることを確認するつもりです。
そうすれば、このPDFの印刷版を持っている人は、QRコードをスキャンするだけでいいのです。
デジタル版であれば、QRコードをクリックすればいいのです。
このように、単純な追加機能ですが、ユーザー側のナビゲーションをより快適なものにしています。
page.append_remote_go_to_annotation(
qr_code.get_bounding_box(), uri="https://www.borbpdf.com"
)
製品情報の追加
次に、チラシを作成する製品に関するタイトルとサブタイトルを追加します。
# Title
layout.add(
Paragraph(
"Productbrochure", font_color=HexColor("#283592"), font_size=Decimal(34)
)
)
# Subtitle
layout.add(
Paragraph(
"September 4th, 2021",
font_color=HexColor("#e01b84"),
font_size=Decimal(11),
)
)
同様に、製品概要のタイトルと、ダミーテキストを追加します。
# product overview
layout.add(
Paragraph(
"Product Overview", font_color=HexColor("000000"), font_size=Decimal(21)
)
)
layout.add(
Paragraph(
"""
Far far away, behind the word mountains, far from the countries Vokalia and Consonantia, there live the blind texts.
Separated they live in Bookmarksgrove right at the coast of the Semantics, a large language ocean.
A small river named Duden flows by their place and supplies it with the necessary regelialia.
"""
)
)
layout.add(
Paragraph(
"""
It is a paradisematic country, in which roasted parts of sentences fly into your mouth.
Even the all-powerful Pointing has no control about the blind texts it is an almost unorthographic life.
One day however a small line of blind text by the name of Lorem Ipsum decided to leave for the far World of Grammar.
""",
margin_bottom=Decimal(12)
)
)
注:最後の「段落」では、下部の余白を明示的に追加しています。
これは、「パラグラフ」と次のコンテンツ(画像)の間に少し余裕を持たせるための視覚的な微調整に過ぎません。
このコードを実行すると、次のようなものが表示されます。
最後に、製品情報を追加します。
画像と、その商品の特徴を示すリストを並べることができます。
この場合も、テーブル`を使用することで、横に並べたような見た目にすることができます。
多くの場合、特徴のリストの上にタイトルがあるので、2列(画像と特徴)と2行(タイトルと特徴)のTable
を用意します。
このテーブルはテーブルとしてではなく、単に横並びの見た目を実現するために使用するので、テーブルにボーダーを追加することはありません。
# New imports
from borb.pdf.canvas.layout.image.image import Image
from borb.pdf.canvas.layout.table.table import TableCell
from borb.pdf.canvas.layout.table.fixed_column_width_table import FixedColumnWidthTable
from borb.pdf.canvas.layout.list.unordered_list import UnorderedList
# Table with image and key features
layout.add(
FixedColumnWidthTable(
number_of_rows=2,
number_of_columns=2,
column_widths=[Decimal(0.3), Decimal(0.7)],
)
.add(
TableCell(
Image(
"https://www.att.com/catalog/en/skus/images/apple-iphone%2012-purple-450x350.png",
width=Decimal(128),
height=Decimal(128),
),
row_span=2,
)
)
.add(
Paragraph(
"Key Features",
font_color=HexColor("e01b84"),
font="Helvetica-Bold",
padding_bottom=Decimal(10),
)
)
.add(
UnorderedList()
.add(Paragraph("Nam aliquet ex eget felis lobortis aliquet sit amet ut risus."))
.add(Paragraph("Maecenas sit amet odio ut erat tincidunt consectetur accumsan ut nunc."))
.add(Paragraph("Phasellus eget magna et justo malesuada fringilla."))
.add(Paragraph("Maecenas vitae dui ac nisi aliquam malesuada in consequat sapien."))
)
.no_borders()
)
また、Table
のいくつかのセルにpadding_bottom
を追加して、余分なスペースを確保しています。
出来上がったPDFはほぼ完成です。
残る最後のステップは、右上隅のアートワークとフッターを追加することです。
borbでShapeオブジェクトを使う
borbは任意の
Shapeを
Pageにレンダリングすることができます。
Shapeは任意の点列(typing.Tuple[Decimal, Decimal]`として表されます)を表し、これらはすべて連続した線を形成します。
これは、作成したい図形をかなり創造的にすることができることを意味します。
まずは、ページ
の右上にある三角形と四角形をレンダリングするメソッドを定義することから始めましょう。
# New imports
from borb.pdf.canvas.geometry.rectangle import Rectangle
from borb.pdf.canvas.layout.image.shape import Shape
from borb.pdf.page.page_size import PageSize
import typing
import random
def add_gray_artwork_upper_right_corner(page: Page) -> None:
"""
This method will add a gray artwork of squares and triangles in the upper right corner
of the given Page
"""
grays: typing.List[HexColor] = [
HexColor("A9A9A9"),
HexColor("D3D3D3"),
HexColor("DCDCDC"),
HexColor("E0E0E0"),
HexColor("E8E8E8"),
HexColor("F0F0F0"),
]
ps: typing.Tuple[Decimal, Decimal] = PageSize.A4_PORTRAIT.value
N: int = 4
M: Decimal = Decimal(32)
# Draw triangles
for i in range(0, N):
x: Decimal = ps[0] - N * M + i * M
y: Decimal = ps[1] - (i + 1) * M
rg: HexColor = random.choice(grays)
Shape(
points=[(x + M, y), (x + M, y + M), (x, y + M)],
stroke_color=rg,
fill_color=rg,
).layout(page, Rectangle(x, y, M, M))
# Draw squares
for i in range(0, N - 1):
for j in range(0, N - 1):
if j > i:
continue
x: Decimal = ps[0] - (N - 1) * M + i * M
y: Decimal = ps[1] - (j + 1) * M
rg: HexColor = random.choice(grays)
Shape(
points=[(x, y), (x + M, y), (x + M, y + M), (x, y + M)],
stroke_color=rg,
fill_color=rg,
).layout(page, Rectangle(x, y, M, M))
このメソッドをmainメソッドで呼び出すことで、PDFをより華やかにすることができます。
同様に、ページの下部にもいくつかのグラフィックを追加することができます。
- フッターをページのメインコンテンツから分離するための線
- ページ上部の幾何学的なグラフィックとバランスをとるための小さな幾何学的要素
これらすべてを行うための別のメソッドを書いてみましょう。
from borb.pdf.canvas.line_art.line_art_factory import LineArtFactory
def add_colored_artwork_bottom_right_corner(page: Page) -> None:
"""
This method will add a blue/purple artwork of lines
and squares to the bottom right corner
of the given Page
"""
ps: typing.Tuple[Decimal, Decimal] = PageSize.A4_PORTRAIT.value
# Square
Shape(
points=[
(ps[0] - 32, 40),
(ps[0], 40),
(ps[0], 40 + 32),
(ps[0] - 32, 40 + 32),
],
stroke_color=HexColor("d53067"),
fill_color=HexColor("d53067"),
).layout(page, Rectangle(ps[0] - 32, 40, 32, 32))
# Square
Shape(
points=[
(ps[0] - 64, 40),
(ps[0] - 32, 40),
(ps[0] - 32, 40 + 32),
(ps[0] - 64, 40 + 32),
],
stroke_color=HexColor("eb3f79"),
fill_color=HexColor("eb3f79"),
).layout(page, Rectangle(ps[0] - 64, 40, 32, 32))
# Triangle
Shape(
points=[
(ps[0] - 96, 40),
(ps[0] - 64, 40),
(ps[0] - 64, 40 + 32),
],
stroke_color=HexColor("e01b84"),
fill_color=HexColor("e01b84"),
).layout(page, Rectangle(ps[0] - 96, 40, 32, 32))
# Line
r: Rectangle = Rectangle(Decimal(0), Decimal(32), ps[0], Decimal(8))
Shape(
points=LineArtFactory.rectangle(r),
stroke_color=HexColor("283592"),
fill_color=HexColor("283592"),
).layout(page, r)
ここでも、mainメソッドからこのメソッドを呼び出すことができます。
結果として、ページはこのようになります。
結論
このガイドでは、borb
を使ったPDFドキュメントの基本的な構成要素をいくつか見てきました。
パディングとマージン、そしてフォントサイズとフォントカラーを設定しました。
また、Shape
オブジェクトを使用してグラフィックを生成し、クリック可能なQRコードも作りました。
これらの構成要素を用いて、架空の会社の架空の製品のチラシを作成し、インタラクティブな PDF 文書の作成プロセスを自動化しました。