はじめに
大高隆・著「動かして学ぶ!Python Django開発入門」を使用して
python・Djangoの学習を始めた初学者です。
ruby・railsを使用して4ヶ月ほどプログラミングの勉強をしていましたが、
エンジニア転職にあたり、pythonを使用することになったのでこの本を片手に勉強を始めました。
ド級の素人なので、補足・ご指摘等コメントいただけると大変助かります。
概要
HTMLのページをPDF化して表示させたい。
ついでにグラフを'matplotlib'で作成して画像としてPDFに入れてあげたい。
①HTML→PDFの道のり
HTML↓
from django.shortcuts import render
def html_view(request):
.
.
.
# 変数をcontextにつめてHTMLへ渡す
context = {
"hoge": hoge,
"fuga": fuga,
}
return render(request, 'hogefuga.html', context)
PDF化↓
from django.http import HttpResponse
from django.shortcuts import render
from weasyprint import HTML, CSS
from django.template.loader import get_template
def pdf_view(request):
.
.
.
# テンプレートの指定&変数を渡す
html_template = get_template('hogefuga.html')
html_str = html_template.render({
"hoge": hoge,
"fuga": fuga,
}, request)
# PDF化
pdf_file = HTML(string=html_str, encoding='utf-8').write_pdf(
stylesheets=[
# WeasyPrintではここでCSSファイルを指定してあげないと適応されません。
CSS('./static/css/hogefuga.css'),
],
)
response = HttpResponse(pdf_file, content_type='application/pdf')
response['Content-Disposition'] = 'filename="hogefuga.pdf"'
return response
②matplotlibでグラフを作成してPDFに表示させる
先人の方々の知恵すごい。ここまでは苦戦しつつもなんとか...
さて、グラフも作成してあげましょう。
from django.http import HttpRespons
from django.shortcuts import render
from weasyprint import HTML, CSS
from django.template.loader import get_template
import matplotlib.pyplot as plt
import matplotlib as mpl
mpl.use('Agg')
def pdf_graph_view(request):
x = [1, 2, 3, 4, 5]
y = [1, 2, 3, 4, 5]
fig = plt.figure(figsize=(4.0, 3.0))
ax = fig.add_subplot(111)
ax.plot(x, y)
plt.savefig('static/img/graph.png', format='png', dpi=200)
.
.
.
以下PDF化コードと同じ
ちなみに、下記記述がない場合、エラーになります。
たったこれだけの記述に時間を奪われてしまった...
お借りした先人の知恵はこちら
mpl.use('Agg')
③画像(グラフ)がPDFに表示されない
さて、HTMLに画像ファイルの場所を記述して終わりですね。
<img src="{% static 'img/graph.png' %}">
ところがどっこい、そうは問屋が卸さない。
なぜかPDFには画像が表示されない。なぜだ。
対処①
pdf_file = HTML(string=html_str, base_url=request.build_absolute_uri(), encoding='utf-8')
に変更。
すると、グラフは表示されるが、文字化け。
いよいよPC破壊しそう。goodbyeジョブズ。
対処②
とりあえず文字化けしてしまったら、
力技でフォントの優先順位をあげるしかない。(脳死単細胞)
font-family: 'msmincho'!important;
!importantをつけてみたら、文字化けは無事解決。
だけどこれって根本解決になってない。クサいものには蓋をします。
最後に
先人の方々すごい。技術者すごい。憧れる。
まだまだ初心者を脱するのは時間がかかりそう。日々勉強、ですね。
なぜ、文字化けする(CSSが効いていない)のか。解決せねば。
偉大な参考記事
・matplotlib逆引きメモ(フレーム編)
・サーバサイドにおけるmatplotlibによる作図Tips
・Django2.0 + WeasyPrint でお手軽にPDF出力
・PDF output using Weasyprint not showing images (Django)