既存PDFに何かしらのテキストを書き込む機会は多い。前回よりPythonで既存PDFに書き込みを行う方法を紹介している。前回は簡単な図形を描画してPDFに保存する方法を紹介したが、今回は実際に申請書に必要事項を書き込む方法を紹介する。特に日本語テキストの書き込み方法や既存PDFを読み込み方法を確認してみよう。

  • 今回作るのはPythonで申請書に項目を自動入力するプログラムだ

    今回作るのはPythonで申請書に項目を自動入力するプログラムだ

ライブラリのインストールが必要

前回よりPDFを作成する方法を紹介している。PythonではいろいろなPDFライブラリがあるが、本稿ではPyPDF2とReportLabを使う方法を紹介する。そのため、前回の内容を参考にして、これらのパッケージをインストールしておこう。

日本語フォントとサンプル素材をダウンロードしよう

なお、ReportLabで日本語フォントを利用するには、フォントファイルを用意する必要がある。ここでは、無料で配布されているIPAexフォントを利用することにしよう。こちらからフォントファイルをダウンロードできる。IPAex明朝とIPAexゴシックがあるが、今回はIPAexゴシックを利用する。ZIPファイルを解凍したらプログラムと同じフォルダにコピーしよう。

また、今回利用するプログラムとサンプルのPDFなどは、こちらのページからダウンロードできる。

日本語を書き込もう

それではPDFに日本語を描画してみよう。以下のプログラムは日本語のテキストをPDFに書き込むものだ。以下のプログラムを「write_ja.py」という名前で保存しよう。

from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4, portrait
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

# フォントのパスを指定する --- (*1)
ttf_file = './ipaexg.ttf'
# フォントを登録する --- (*2)
pdfmetrics.registerFont(TTFont('IPAexGothic', ttf_file))

# A4縦のCanvasを作成 -- (*3)
w, h = portrait(A4)
cv = canvas.Canvas('test.pdf', pagesize=(w, h))

# 描画フォントを指定 --- (*4)
font_size = 40
cv.setFont('IPAexGothic', font_size)

# 文字列を描画する --- (*5)
cv.drawString(20, h-100,  "こんにちは!")
cv.drawString(20, h-160, "日本語をPDFに描画するには")
cv.drawString(20, h-220, "フォントの登録が必要")

# ファイルに保存 --- (*6)
cv.showPage()
cv.save()

プログラムを実行するには、コマンドライン(WindowsならPowerShell、macOSならターミナル.app)で以下のコマンドを実行する。

# Windows
python write_ja.py
# macOS
python3 write_ja.py

実行すると、以下のように日本語が書き込まれたPDF「test.pdf」が生成される。

  • PDFに日本語を書き込んだところ

    PDFに日本語を書き込んだところ

プログラムを確認してみよう。プログラムの(*1)の部分では、フォントのパスを指定し、(*2)でフォントをRportLabに登録する。(*3)の部分は前回も紹介したが描画用のCanvasをA4縦のサイズで作成している。そして、(*4)の部分でCanvasに描画するフォントを指定する。ここでは(*2)で登録したIPAexGothicを指定した。(*5)の部分ではdrawStringメソッドを指定して日本語の文字列を描画する。そして最後(*6)の部分でファイルに保存する。

ここで見たように、ReportLabで日本語を利用するためには、最初にフォントファイルを登録し、CanvasのsetFontメソッドにて、登録したフォントを指定することで利用できるようになる。なおPDFの座標指定は左下が起点なり右上にいくほど座標が大きくなるので注意が必要だ。

既存PDFに日本語テキストを書き込むプログラム

それでは、本題に入ろう。PyPDF2ライブラリを利用して既存PDFに日本語のテキストを書き込むことができる。

以下のプログラムは、申請書PDF「form.pdf」を読み込んで、必要事項を記入して「output.pdf」に保存するものだ。以下のプログラムを「write_form.py」という名前で保存しよう。

from PyPDF2 import PdfFileWriter, PdfFileReader
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4, portrait
from reportlab.lib.units import inch, mm, cm
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

# ファイルの指定
template_file = './form.pdf' # 既存のテンプレートPDF
output_file = './output.pdf' # 完成したPDFの保存先
tmp_file = './__tmp.pdf' # 一時ファイル

# A4縦のCanvasを作成 -- (*1)
w, h = portrait(A4)
cv = canvas.Canvas(tmp_file, pagesize=(w, h))

# フォントを登録しCanvasに設定 --- (*2)
font_size = 20
ttf_file = './ipaexg.ttf'
pdfmetrics.registerFont(TTFont('IPAexGothic', ttf_file))
cv.setFont('IPAexGothic', font_size)

# 文字列を描画する --- (*3)
cv.setFillColorRGB(0, 0, 0.4)
cv.drawString(70*mm, h-103*mm, "令和3年 1月 20日")
cv.drawString(70*mm, h-150*mm, "クジラ飛行机")

# 一時ファイルに保存 --- (*4)
cv.showPage()
cv.save()

# テンプレートとなるPDFを読む --- (*5)
template_pdf = PdfFileReader(template_file)
template_page = template_pdf.getPage(0)

# 一時ファイルを読んで合成する --- (*6)
tmp_pdf = PdfFileReader(tmp_file)
template_page.mergePage(tmp_pdf.getPage(0))

# 書き込み先PDFを用意 --- (*7)
output = PdfFileWriter()
output.addPage(template_page)
with open(output_file, "wb") as fp:
  output.write(fp)

コマンドラインで以下のコマンドを実行すれば「output.pdf」というPDFが生成される。

# Windowsの場合
python write_form.py
# macOSの場合
python3 write_form.py

元となる申請書のPDFは以下のようなものだ。時々見かけるのだが、このような指定の申請書PDFしか受け付けないという場面がある。

  • 元となる申請書のPDF

    元となる申請書のPDF

そして、プログラムを実行して生成されたPDFファイルは以下のようなものだ。申請書PDFを読み込み、そこにReportLabで生成したPDFを重ね合わせるという手法でPDFを生成する。

  • Pythonによって生成されたPDF - フォームに項目を書き込んだところ

    Pythonによって生成されたPDF - フォームに項目を書き込んだところ

プログラムを確認してみよう。プログラムの(*1)ではA4縦サイズのCanvasを生成する。そして、(*2)でフォントをReportLabに登録し、Canvasで利用するように指定を行う。(*3)の部分では文字列を描画する。(*4)では一時ファイルに書き込んだ内容を保存する。

そして、(*5)の部分でテンプレートとなる元のPDFを読み込む。(*6)では先ほどReportLabで作成した一時ファイルを読み込み、(*5)のテンプレートのPDFとmergeメソッドを利用して重ね合わせる。それから最後(*7)の部分で重ね合わせたPDFを保存するようにしている。

プログラムを読むと分かるが、ReportLabでテキストを書き込み一時ファイルに保存し、PyPDF2を利用して一時ファイルを読み込んでテンプレートに重ね合わせるという処理になっている。そのため、あくまでもReportLabがしているのはPDFを作成するだけ、PyPDF2は読み込んで重ね合わせるだけと役割分担がしっかりしているのが分かるだろう。

また、プログラムの(*3)の部分を見ると分かるが、テキストを書き込む位置をミリで指定できる。実際に印刷した用紙があるなら、定規でだいたいの位置を測って指定することもできるだろう。また、前回作成した方眼紙を参考にして基準線をPDFに描画することで、だいたいの位置を調べることができるだろう。

まとめ

以上、既存PDFに書き込みを行う方法を紹介した。今回はテキストをだけを書き込む方法を紹介した。しかし、前回紹介したようにReportLabには豊富な図形描画の機能があるので、これを利用する事でテキストだけでなく表や画像なども書き込むことが可能だ。今回のプログラムを参考にして自動でPDF書き込みプログラムを作れば業務効率化に役立てることができるだろう。

自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2004年度未踏ユース スーパークリエータ認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。