1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

WeasyPrint + matplotlibでHTMLをPDF化してグラフも埋め込みたい話【初学者が参考書片手にpython学習】

Posted at

はじめに

大高隆・著「動かして学ぶ!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に画像ファイルの場所を記述して終わりですね。

hogefuga.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ジョブズ。

対処②

とりあえず文字化けしてしまったら、
力技でフォントの優先順位をあげるしかない。(脳死単細胞)

hogefuga.css
font-family: 'msmincho'!important;

!importantをつけてみたら、文字化けは無事解決。
だけどこれって根本解決になってない。クサいものには蓋をします。

最後に

先人の方々すごい。技術者すごい。憧れる。
まだまだ初心者を脱するのは時間がかかりそう。日々勉強、ですね。
なぜ、文字化けする(CSSが効いていない)のか。解決せねば。

偉大な参考記事

matplotlib逆引きメモ(フレーム編)
サーバサイドにおけるmatplotlibによる作図Tips
Django2.0 + WeasyPrint でお手軽にPDF出力
PDF output using Weasyprint not showing images (Django)

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?