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
途中、日付と名前のところを日本語にしてあります。
これでサーバーを起動し、ダウンロードしてみるとこうなります。
フォントが「しっぽり明朝」に変わって、日本語の表示もできるようになりました。
これで「足し算テストアプリ」はとりあえず完成です。
まだまだ色々なアプリを作成していきますが、メインを少し変えて、当分は新たなデバイスを色々といじっていきたいなと思います。
ではでは今回はこんな感じで。
コメント