PythonのPDF作成用ライブラリを試してみた。

PythonでPDFを出力する必要があり、試した内容をメモしたいと思います。
試したライブラリは以下の2つです。
・ReportLab
・xhtml2pdf

※試した内容はすべてLinux(CentOS7)で実施しています

# ReportLab
ReportLabには無料版(ReportLab open-source)と有料版(ReportLab PLUS)あります。
PLUSだとtemplating toolsなど追加機能があるようです。
グラフや表も描画できます。
BSD License

参考
https://gammasoft.jp/blog/pdf-japanese-font-by-python/
https://www.reportlab.com/
https://www.reportlab.com/docs/reportlab-userguide.pdf
https://www.reportlab.com/chartgallery/

```bash:前準備
$ python3 -m venv myenv1
$ source myenv1/bin/activate
$ mkdir pdftest1
$ cd pdftest1
$ pip install reportlab -t .
$ vi test.py
$ python3 test.py
$ deactivate
```

```python:Reportlabサンプルコード
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4, portrait
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
import webbrowser

FILENAME = 'HelloWorld.pdf'
c = canvas.Canvas(FILENAME, pagesize=portrait(A4))

font_size = 20
pdfmetrics.registerFont(UnicodeCIDFont('HeiseiMin-W3'))
c.setFont('HeiseiMin-W3', 20)

width, height = A4
c.drawCentredString(width / 2, height / 2 - font_size * 0.4, 'へろーわーるど')

c.showPage()
c.save()
```

![2021-08-10_18h17_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200585/d3856e5f-9d24-3612-ae17-453b6ef890f5.png)


#xhtml2pdf
xhtml2pdfの内部では上記のReportLabが使用されています。
HTMLファイルをPDFに変換できます。
サンプルではHTMLの文字列を変換しています。
そのままだと文字化けしてしまうため、フォントを入れないとダメなよう。。
(styleタグの`@font-face`でダウンロードして配置したフォントを指定することで日本語の文字化けを防げた)
すべてのCSSのパラメタをサポートしているわけではないようです。
JavaScriptもうまくは読み込んでくれず断念。
Apache License 2.0

参考
https://githubja.com/xhtml2pdf/xhtml2pdf
https://xhtml2pdf.readthedocs.io/en/latest/index.html

```bash:前準備
$ python3 -m venv myenv2
$ source myenv2/bin/activate
$ mkdir pdftest2
$ cd pdftest2
$ pip install xhtml2pdf -t .
$ vi test.py
$ python3 test.py
$ deactivate

# 「http://jikasei.me/font/genshin/#_8」からフォントをダウンロードして以下に配置
# pdftest2/font/GenShinGothic-Monospace-Medium.ttf
```

```python:xhtml2pdfサンプルコード
from xhtml2pdf import pisa

sourceHtml = """
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <!-- -->
        <style>
            @font-face {
                font-family: "japanese";
                src: url(font/GenShinGothic-Monospace-Medium.ttf);
            }
            body {
                font-family: "japanese"
            }
        </style>
    </head>

    <body>
        <h1>HTML To PDF</h1>
        <p>test</p>
        <p>日本語</p>
         <table border="1" width="500" cellspacing="0" cellpadding="5" bordercolor="#333333">
            <tr>
                <th bgcolor="#EE0000"><font color="#FFFFFF">aaa</font></th>
                <th bgcolor="#EE0000"><font color="#FFFFFF">iii</font></th>
            </tr>
            <tr>
                <td bgcolor="#99CC00">test</td>
                <td bgcolor="#FFFFFF">テスト</td>
            </tr>
            <tr>
                <td bgcolor="#99CC00">TEST</td>
                <td bgcolor="#FFFFFF">テストテスト</td>
            </tr>
        </table>
    </body>
</html>
"""

outputFilename = "test.pdf"

def convertHtmlToPdf(sourceHtml, outputFilename):
    resultFile = open(outputFilename, "w+b")

    pisaStatus = pisa.CreatePDF(
            src=sourceHtml.encode('utf-8'),
            dest=resultFile,
            encoding='utf-8')
    resultFile.close()

    return pisaStatus.err

if __name__ == "__main__":
    pisa.showLogging()
    convertHtmlToPdf(sourceHtml, outputFilename)

```

![2021-08-10_19h10_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200585/57a9878f-324f-9dc0-681d-02c2aba4eb84.png)

#おわり
他にもいくつか試しましたが、メモが残っておらず、、
今回は上記２つのみの紹介になってしまいました。
最終的にReportLabの無料版を使用することにしました。

今回は以上です。