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

## はじめに
[大高隆・著「動かして学ぶ！Python Django開発入門」](https://www.amazon.co.jp/dp/B07YY5RDPC/ref=cm_sw_r_tw_dp_U_x_TCsYEbRH6SF0V)を使用して
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化コードと同じ
```

ちなみに、下記記述がない場合、エラーになります。
たったこれだけの記述に時間を奪われてしまった...
[お借りした先人の知恵はこちら](https://qiita.com/TomokIshii/items/3a26ee4453f535a69e9e)

```
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逆引きメモ（フレーム編）](https://qiita.com/cnloni/items/20b5908fbae755192498)
・[サーバサイドにおけるmatplotlibによる作図Tips](https://qiita.com/TomokIshii/items/3a26ee4453f535a69e9e)
・[Django2.0 + WeasyPrint でお手軽にPDF出力](https://qiita.com/mag-chang/items/c01ccb21a05c51cb1b45)
・[PDF output using Weasyprint not showing images (Django)](https://stackoverflow.com/questions/48988707/pdf-output-using-weasyprint-not-showing-images-django)