本日は、Djangoにて、
htmlをpdfへ変換し、ダウンロードする
方法を公開します
現時点(2021年3月29日)で試したところ、うまく行きましたので参考になれば幸いです
また、こちらのドキュメントを参考にしてますので、英語でも問題ない!という方は一緒に読み進めることをお勧めします!
はじめに
今回は簡易的な、請求書フォームのようなものを作っています
本当に簡易的なものですので、下記を読んでやり方を覚えたらカスタマイズしてください!
【views.py】
import os
from django.conf import settings
from django.http import HttpResponse
from django.template.loader import get_template
from xhtml2pdf import pisa
from django.contrib.staticfiles import finders
import datetime
def link_callback(uri, rel):
result = finders.find(uri)
if result:
if not isinstance(result, (list, tuple)):
result = [result]
result = list(os.path.realpath(path) for path in result)
path=result[0]
else:
sUrl = settings.STATIC_URL
sRoot = settings.STATIC_ROOT
mUrl = settings.MEDIA_URL
mRoot = settings.MEDIA_ROOT
if uri.startswith(mUrl):
path = os.path.join(mRoot, uri.replace(mUrl, ""))
elif uri.startswith(sUrl):
path = os.path.join(sRoot, uri.replace(sUrl, ""))
else:
return uri
if not os.path.isfile(path):
raise Exception(
'media URI must start with %s or %s' % (sUrl, mUrl)
)
return path
def render_pdf_view(request):
template_path = 'realestate/invoice.html' #ここにはテンプレートの場所を入れる
#ここがテンプレート内にレンダーされるcontextになります
context = {'title': 'Invoice',
'today': datetime.date.today(),
'amount': 39.99,
'customer_name': 'Yulikepython',
'order_id': 1233434,
}
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="report.pdf"'
template = get_template(template_path)
html = template.render(context)
pisa_status = pisa.CreatePDF(
html, dest=response, link_callback=link_callback)
if pisa_status.err:
return HttpResponse('We had some errors <pre>' + html + '</pre>')
return response
基本はコピペで大丈夫かと思います
変更すべき点は主に2箇所
- template_path
- context
になります!
【テンプレート】
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Title</title>
<style type="text/css">
body {
font-weight: 200;
font-size: 14px;
font-family: HeiseiMin-W3;
}
.header {
font-size: 20px;
font-weight: 100;
text-align: center;
color: #007cae;
}
.title {
font-size: 22px;
font-weight: 100;
/* text-align: right;*/
padding: 10px 20px 0px 20px;
}
.title span {
color: #007cae;
}
.details {
padding: 10px 20px 0px 20px;
text-align: left !important;
/*margin-left: 40%;*/
}
.hrItem {
border: none;
height: 1px;
/* Set the hr color */
color: #333; /* old IE */
background-color: #fff; /* Modern Browsers */
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='header'>
<p class='title'>Invoice #{{ order_id }} </p>
</div>
<div>
<div class='details'>
Title: {{title}}<br />
Bill to: {{ customer_name }}<br/>
Amount: {{ amount }}<br/>
Date: {{today}}
<hr class='hrItem' />
</div>
</div>
</body>
</html>
ポイントとしては、
font-familyをHeiseiMin-W3
にすることで日本語が文字化けしなくなります
また、styleを同ページで記述していること
別ファイルのcssを読み込んでもできるかどうかは試していませんので、興味のある方は試してみて下さい!
そしてできたら教えて下さい!!
【urls.py】
from .views import (
.,
.,
render_pdf_view,
)
urlspattern = [
path("generate-pdf/", render_pdf_view, name="generate_pdf"),
]
あとは、urls.pyで指定したアドレスへGO!!