ReportLabで日本語を含んだPDFを出力するサンプル (platypus)

bonlifeです。会社の一番苦手な女性社員(年下)にドラクエのメインテーマの弾き方を教えてる夢を見ました。何度教えても、「教え方が悪いから分からないんですよ。」みたいなことを言われる拷問な夢。だんだんテンパってきて、曲も思い出せなくなったところで目が覚める…orz 外はキレイな雪景色でした。
ということで、Pythonで日本語を含んだPDF出力ですよ。platypusを使わないと複数ページに出力させるのが面倒っぽかったので、マニュアル読みながらplatypusを使ってみました。基本的には本家にあるマニュアルそのままです。日本語表示させるためにフォントの設定だけ要注意。id:ExaField:20080206:1202300126 あたりでも触れられていますが、ページが切り替わるタイミングでフォント(だけかしら?)の情報がフッ飛ぶ仕様っぽい。ということで、早速コード。

# -*- coding: utf8 -*-
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
from reportlab.pdfbase import pdfmetrics
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.rl_config import defaultPageSize
from reportlab.lib.units import inch

pdfmetrics.registerFont(UnicodeCIDFont("HeiseiKakuGo-W5"))

PAGE_HEIGHT=defaultPageSize[1]
PAGE_WIDTH=defaultPageSize[0]

styles = getSampleStyleSheet()
my_style = styles["Normal"]
my_style.name = "bonlife"
my_style.fontName = "HeiseiKakuGo-W5"

Title = u"ReportLabで日本語を扱うサンプルなんだぜ?"
pageinfo = u"日本語PDFのサンプルなんだぜ?"

def myFirstPage(canvas, doc):
    canvas.saveState()
    canvas.setFont("HeiseiKakuGo-W5",18)
    canvas.drawCentredString(PAGE_WIDTH/2.0, PAGE_HEIGHT-70, Title)
    canvas.setFont("HeiseiKakuGo-W5",9)
    canvas.drawString(inch, 0.75*inch, u'これは "%s" の表紙なんだぜ?' % pageinfo)
    canvas.restoreState()

def myLaterPages(canvas, doc):
    canvas.saveState()
    canvas.setFont("HeiseiKakuGo-W5", 9)
    canvas.drawString(inch, 0.75*inch, u'これは "%s" の %d ページなんだぜ?' % (pageinfo, doc.page))
    canvas.restoreState()

def go():
    doc = SimpleDocTemplate("reportlab_japanese.pdf")
    Story = [Spacer(1, 0.2*inch)]
    style = my_style
    for i in range(5):
        bogustext = (u"「覚悟」とは!! 暗闇の荒野に!!進むべき道を切り開く事だッ! (段落番号は %s) " % (i + 1)) * 50
        p = Paragraph(bogustext, style)
        Story.append(p)
        Story.append(Spacer(1, 0.2*inch))
    doc.build(Story, onFirstPage=myFirstPage, onLaterPages=myLaterPages)

go()

基本的な表示情報をひとまとめにしたものを、getSampleStyleSheet()で取得できるので、その中のフォントだけ上書き。結構、楽々ですね。でも、PDFにしたい!って思うことがあまりないので、今後使うことはないかもしれませんね!