【Python】Django:足し算テストアプリを作成(Reportlabで日本語を出力)

  • URLをコピーしました!
目次

Django

前回、PDF出力用のライブラリ「Reportlab」を使って、足し算テストをPDF化してみました。

ただ前回はフォントを「Helvetica」という英字用のフォントを用いたため、日本語の出力ができませんでした。

そこで今回は「Reportlab」で日本語を出力する方法を試していきます。

フォントはGoogle Fontsからダウンロードした「しっぽり明朝」のRegularを使います。

Google Fontsをまだ試したことない方は、こちらの記事をどうぞ。

それでは始めていきましょう。

フォントの配置

まずはダウンロードしたフォントを配置していきます。

/webapp/tashizan1の下に新たに「static」フォルダ、その中に「tashizan1」、さらに「fonts」というフォルダを作成します。

その下に「Shippori_Mincho」フォルダ、そしてその中に「ShipporiMincho-Regular.ttf」ファイルと「OFL.txt」ファイルを配置します。

webapp
├── ...
└── tashizan1
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── forms.py    
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── static
    │   └── tashizan1
    │       └── fonts
    │           └── Shippori_Mincho
    │               ├── OFL.txt                          <- 配置
    │               └── ShipporiMincho-Regular.ttf       <- 配置
    ├── templates
    │   └── tashizan1
    │       ├── answercheck.html
    │       └── index.html
    ├── tests.py
    ├── urls.py
    └── views.py

この「しっぽり明朝」はワードクラウドアプリでも使用しているので、全アプリ共有のstaticフォルダに入れて使用した方が将来的にはいいかもしれませんが、とりあえず今回はこれで。

/webapp/tashizan1/views.py

次にviews.pyの修正を行います。

修正点としては大まかに言って以下の3点。

  • Reportlabにフォントを登録するためのライブラリのインポート
  • Reportlabにフォント登録
  • フォント指定

まずフォントを登録するためのライブラリ2つをインポートします。

from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

上がフォント登録ライブラリ、下がTTFという形式のフォントの読み込みのためのライブラリです。

次にフォントを登録しますが、使用するpdf関数の中にこちらの2行を追加します。

    font_url = r'./tashizan1/static/tashizan1/fonts/Shippori_Mincho/ShipporiMincho-Regular.ttf'
    pdfmetrics.registerFont(TTFont('ShipporiMincho', font_url))

上がフォントのパス、下がReportlabに登録するコマンドです。

「TTFont(‘ShipporiMincho’, font_url)」は「TTFont(‘フォントの名前’, 場所)」で指定した場所にあるTTFフォントを指定した名前のフォントとして読み込みます。

つまり後々この名前でフォントを呼び出すことになります。

そして読み込んだフォントを「pdfmetrics.registerFont()」でReportlabに登録します。

そしてフォントを設定するのは、前にも出てきた「pdf_file.setFont(‘フォント名’, フォントサイズ)」です

ということでviews.py全体としてはこんな感じです。

from django.shortcuts import render
from django.http import HttpResponse
from .forms import Tashizan1Form
import sys
sys.path.append('../')
from webapp import definitions
import random

from reportlab.lib.pagesizes import A4, portrait
from reportlab.lib.units import mm
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

def index(request):
    params = definitions.readjson()

    num_range = range(0,10)

    params['qa'] = random.choices(num_range, k=10)
    params['qb'] = random.choices(num_range, k=10)

    params['forms'] = Tashizan1Form()

    return render(request, 'tashizan1/index.html', params)

def answercheck(request):
    params = definitions.readjson()

    qa = request.POST.getlist('qa')
    qb = request.POST.getlist('qb')
    input_answers = [int(request.POST['answer0']),int(request.POST['answer1']),int(request.POST['answer2']),\
        int(request.POST['answer3']),int(request.POST['answer4']),int(request.POST['answer5']),\
        int(request.POST['answer6']),int(request.POST['answer7']),int(request.POST['answer8']),int(request.POST['answer9'])]

    ans = []
    for qa_val, qb_val in zip(qa,qb):
        ans.append(int(qa_val) + int(qb_val))

    anscheck = []
    for ans_val, inp_ans in zip(ans, input_answers):
        if ans_val == inp_ans:
            anscheck.append('正解!')
        else:
            anscheck.append('間違い...')

    params['qa'] = qa
    params['qb'] = qb
    params['input_answers'] = input_answers
    params['anscheck'] = anscheck
    params['ans'] = ans

    return render(request, 'tashizan1/answercheck.html', params)

def pdf(request):
    params = definitions.readjson()
    qa = request.POST.getlist('qa')
    qb = request.POST.getlist('qb')

    ans = []
    for qa_val, qb_val in zip(qa,qb):
        ans.append(int(qa_val) + int(qb_val))

    response = HttpResponse(content_type='application/pdf')
    pdf_name = 'tashizan1.pdf'
    response['Content-Disposition'] = 'attachment; filename=' + pdf_name

    font_url = r'./tashizan1/static/tashizan1/fonts/Shippori_Mincho/ShipporiMincho-Regular.ttf'
    pdfmetrics.registerFont(TTFont('ShipporiMincho', font_url))

    pdf_size = portrait(A4)

    pdf_file = canvas.Canvas(response, pagesize=pdf_size, bottomup=False)

    pdf_file.setFont('ShipporiMincho', 25)

    pdf_file.drawString(25*mm, 20*mm, "日付:          /          /          名前:")
    
    for i, val in enumerate(zip(qa, qb)):
        vertical = 20+20*(i+1)
        horizontal = 25
        pdf_file.drawString(horizontal*mm, vertical*mm, f"{i+1}.  {val[0]} + {val[1]} =")
    
    pdf_file.setFont('ShipporiMincho', 10)
    pdf_file.drawString(125*mm, 250*mm, '3PySci: https://3pysci.com')
    pdf_file.drawString(125*mm, 290*mm, f'1.{ans[0]} 2.{ans[1]} 3.{ans[2]} 4.{ans[3]} 5.{ans[4]} 6.{ans[5]} 7.{ans[6]} 8.{ans[7]} 9.{ans[8]} 10.{ans[9]}')

    pdf_file.save()

    return response

途中、日付と名前のところを日本語にしてあります。

これでサーバーを起動し、ダウンロードしてみるとこうなります。

フォントが「しっぽり明朝」に変わって、日本語の表示もできるようになりました。

これで「足し算テストアプリ」はとりあえず完成です。

まだまだ色々なアプリを作成していきますが、メインを少し変えて、当分は新たなデバイスを色々といじっていきたいなと思います。

ではでは今回はこんな感じで。

よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次