PythonでPDFを生成したい そしてサイコロを作りたい
研究室に毎日行っているわけだが,夜もいるので,どうしても夕食は外食となる.
嬉しいことに,我が大学の近くには食事するところがたくさんある.
しかし,長年大学に通っていると,どこに行くか決めづらくなる.
で,最近導入されたのが「食事する場所を決めるサイコロ(紙製組立型)」.
各面に食事する場所が載っていて,サイコロを振って,ランダムに決めるという優れものとなっている.
素晴らしい先輩が作ってくださった.
それを使っていて,サイコロの面に色んなことを載せて,ランダムに決められるのって楽しいなって思った.
んで,各面に載せる語句を指定するだけで,そのサイコロの展開図の載ったpdfを生成するプログラムでも作りたいなーって思った.
というわけで,作ってみた.
まあ,Pythonを使ったpdfの生成なんてしたことなかったし,それをまとめてみる.
reportlab
PythonでPDFを扱えるようにするためのライブラリとして,reportlabがある.
ReportLab: Open Source Python Libraries for PDF creation - ReportLab.com
環境構築
仮想環境
まず,virtualenvを使って,仮想環境を作る.
(別にこんなことしなくてもできる)
環境名はenv-pdfで.
$ mkvirtualenv env-pdf
virtualenvとかの使い方はここ.
> Pythonの仮想環境 virtualenvとvirtualenvwrapper - [[ともっくす alloc] init]
reportlabのインストール
pipを使うだけ.
env-pdfがアクティベートされていることを確認して,
$ pip install reportlab
virtualenvを使わない場合は,
$ sudo pip install reportlab
でいいかも.
以上.
使ってみる
とりあえず,サンプルとして書いたコードはこんな感じ.
# -*- coding: utf-8 -*- from reportlab.pdfgen import canvas from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.cidfonts import UnicodeCIDFont import reportlab.lib.colors as color def make(filename="pdftest"): pdf_canvas = set_info(filename) print_string(pdf_canvas) print_figure(pdf_canvas) print_line(pdf_canvas) pdf_canvas.save() # 初期設定 def set_info(filename): pdf_canvas = canvas.Canvas("./{0}.pdf".format(filename), bottomup=False) # 原点は左上 pdf_canvas.setAuthor("ともっくす") pdf_canvas.setTitle("pythonを使ってpdf_canvasを生成する") pdf_canvas.setSubject("reportlab") return pdf_canvas # 文字 def print_string(pdf_canvas): # フォントを登録する pdfmetrics.registerFont(UnicodeCIDFont("HeiseiKakuGo-W5")) pdfmetrics.registerFont(UnicodeCIDFont("HeiseiMin-W3")) # ゴシック体をサイズ15で pdf_canvas.setFont("HeiseiKakuGo-W5", 15) pdf_canvas.drawString(50, 50, "ゴシック体をサイズ15で") # 明朝体をサイズ30で pdf_canvas.setFont("HeiseiMin-W3", 30) pdf_canvas.drawString(300, 100, "明朝体をサイズ30で") # 図形 def print_figure(pdf_canvas): # 枠線のみの四角 pdf_canvas.rect(50, 150, 200, 250) # 青色の円 pdf_canvas.setFillColor(color.blue) pdf_canvas.circle(400, 350, 50, stroke=False, fill=True) # 線 def print_line(pdf_canvas): # 普通の線 pdf_canvas.line(50, 450, 500, 450) # 赤い太い線 pdf_canvas.setStrokeColor(color.red) pdf_canvas.setLineWidth(10) pdf_canvas.line(100, 500, 550, 500) # 破線 pdf_canvas.setStrokeColor(color.black) pdf_canvas.setLineWidth(5) pdf_canvas.setDash([2, 8, 5, 10]) pdf_canvas.line(150, 550, 600, 550) # 複数の線 pdf_canvas.setLineWidth(1) pdf_canvas.setDash([]) lines = [(100, 650, 200, 750), (200, 750, 300, 650), (300, 650, 300, 750), (100, 700, 400, 700)] pdf_canvas.lines(lines) if __name__ == '__main__': make()
で,これを実行すると,
いい感じ.
初期設定(set_info)
まず,Canvasを使って,pdf生成のためのキャンバス(?)を生成する.
このときに,ファイル名も与える.
で,図形を描いたりするんだけど,デフォルトでは原点が左下になってる.
普通はこれでいいかもしれなけど,原点を左上にしてほしい人も多いと思う.(自分も)
そのために,bottomup=Falseを指定する.
さらに,生成されるpdfファイルに色んな情報を付加することもできる.
上みたいに設定することで,プロパティを見ると,こうなってる.(Macの場合)
おー.
文字(print_string)
日本語を使う場合にはフォントを登録する必要がある.
デフォルトで用意されているのは,ゴシック体のHeiseiKakuGo-W5と明朝体のHeiseiMin-W3だけ.
他にもどうにかしたらできるっぽいけど,やっていない.
で,setFont(文字フォント, 文字サイズ)を使って,フォントとサイズを指定する.
そして,drawString(x, y, 表示したい文字列)で,文字列を描画できる.
xは文字の左端,yは文字の下端になるので,注意が必要.
drawString(0, 0, "あいう")とかしても,見えない.
図形(print_figure)
図形としては,矩形と円と楕円が描画できる,はず.
矩形は,rect(x, y, 幅, 高さ)で描画する.
原点を左上にしている場合には,xとyは矩形の左上の座標を表す.
(原点が左下の場合には,xとyは矩形の左下の座標になる*1)
円は,circle(x, y, 半径)で描画する.
円の中心の座標がxとyに対応する.
各メソッドには,strokeとfillという引数を与えることができる.
strokeは枠線を描くかどうかを表すフラグで,Falseで枠線を描画しない設定にできる.
fillはその図形を塗りつぶすかどうかを表すフラグで,Trueで設定された色で塗りつぶすことができる.
塗りつぶす色はsetFillColor(色)で指定できる.
線(print_line)
直線は,line(x_start, y_start, x_end, y_end)で描画できる.
線の色はsetStrokeColor(色)で指定でき,(図形の枠線も同じ)
線の太さはsetLineWidth(太さ)で指定できる.
また,破線は,setDash(間隔のリスト)で指定できる.
さらに,線の座標をリストにして,lines(リスト)に渡すと,一括で描画することもできる.
こんな感じだろうか.
他にも色々できるっぽい.
図形の描画じゃなくて,それっぽい文書の作成とか.
でも,如何せん,日本語の情報が少なくてツラい.
サイコロのコードとか実物?
そんなもの載せたくない.
*1:文字の場合は原点の位置に関係なく文字の左下が基準になるのに,矩形の場合は原点の位置によって基準が変わるのはなぜだ