Posted at

Django2.0 + WeasyPrint でお手軽にPDF出力


WeasyPrintとは


  • HTMLを簡単なコードでPDFやPNGなどの静的ファイルに変換、出力ができるPythonで書かれたOSSライブラリです。

  • 公式サイト


導入方法



  • ここを参照


    • 環境にもよるが、 libffi などの外部ライブラリが必要なので必要に応じてインストールする。参考:Macの場合




基本的な使い方

ここにも書いてありますが、

from weasyprint import HTML

で weasyprintのHTML classをimportして

HTML('https://qiita.com/').write_pdf('/tmp/qiita.pdf')

のように引数に対象ページのURLを指定したHTMLオブジェクトの write_pdf メソッドで引数に出力パスを指定するだけでPDF化されます。

生のHTMLを渡してレンダリングされたものをPDF化することも可能です。

from weasyprint import HTML

HTML(string='''
<h1>Hello World</h1>
'''
)


Djangoで表示されるTemplateをPDF化してみよう

DjangoのViewにPDF出力用の関数を用意し、そこにURLルーティングしている前提です。

def pdf_export(request):

まずはDjangoのTemplateをロードする。

from django.template.loader import get_template

html_template = get_template('hoge/fuga.html')

次に、ロードしたTemplateをHTML化する

# Templateに渡すオブジェクトがある場合は、以下のようにdictで指定する。

html_str = html_template.render({
'param1': 'hoge',
'param2': 'fuga',
}, request)

生成したHTMLをPDF化する

pdf_file = HTML(string=html_str).write_pdf(

# 必要に応じてCSSを指定する。Template内で直接指定しているCSSはWeasyPrint経由だと参照されないので注意。
stylesheets=[
CSS('/static/css/hoge.css')
],
)

生成したPDFをHTTPのレスポンスとして返却する

response = HttpResponse(pdf_file, content_type='application/pdf')

# ストレージに保存する際のデフォルトファイル名を指定できる
response['Content-Disposition'] = 'filename="fuga.pdf"'

return response

これだけです。

とても簡単ですね。

最終的に以下のような形になります。

def pdf_export(request):

from django.template.loader import get_template
html_template = get_template('hoge/fuga.html')

html_str = html_template.render(request) # ここでrequestを渡してあげないと、Template側で必要な変数やプリセットなどが取得できずエラーになる場合がある

pdf_file = HTML(string=html_str).write_pdf(
# 必要に応じてCSSを指定する。Template内で直接指定しているCSSはWeasyPrint経由だと参照されないので注意。
stylesheets=[
CSS('/static/css/hoge.css')
],
)

response = HttpResponse(pdf_file, content_type='application/pdf')
# ストレージに保存する際のデフォルトファイル名を指定できる
response['Content-Disposition'] = 'filename="fuga.pdf"'

return response

上記の関数にブラウザからアクセスすると、指定したTemplateのPDFがダウンロードできます。