PDFファイルを作成する¶
このドキュメントでは、Django のビューを使用して PDF ファイルを動的に出力する方法を説明します。これは、優れたオープンソースの Python PDF ライブラリ ReportLab により可能になっています。
PDF ファイルを動的に生成する利点は、異なる目的のためにカスタマイズされた PDF を作成できることです。たとえば、異なるユーザーや異なるコンテンツを使用して生成できます。
たとえば、kusports.com では、March Madness コンテストに参加する人たちのために、カスタマイズされたプリンター向けの NCAA トーナメントブラケットを PDF ファイルとして生成するのに Django が使われていました。
ReportLab をインストールする¶
ReportLab ライブラリは、PyPI で利用できます。ユーザーガイド (偶然ではなく PDF で提供されています) もダウンロードして利用できます。ReportLab は pip
により次のコマンドでインストールできます。
$ python -m pip install reportlab
...\> py -m pip install reportlab
Python の対話的インタープリタ内でインポートすることでインストールをテストします。
>>> import reportlab
このコマンドが何もエラーを起こさなければ、インストールは機能しています。
ビューを書く¶
Django で PDF を動的に生成するときに重要な点は、ReportLab API がファイルライクなオブジェクトとして振る舞い、Django の FileResponse
オブジェクトがファイルライクなオブジェクトを受け取るということです。
ここに、"Hello World"の例を示します:
import io
from django.http import FileResponse
from reportlab.pdfgen import canvas
def some_view(request):
# Create a file-like buffer to receive PDF data.
buffer = io.BytesIO()
# Create the PDF object, using the buffer as its "file."
p = canvas.Canvas(buffer)
# Draw things on the PDF. Here's where the PDF generation happens.
# See the ReportLab documentation for the full list of functionality.
p.drawString(100, 100, "Hello world.")
# Close the PDF object cleanly, and we're done.
p.showPage()
p.save()
# FileResponse sets the Content-Disposition header so that browsers
# present the option to save the file.
buffer.seek(0)
return FileResponse(buffer, as_attachment=True, filename="hello.pdf")
コードとコメントが自分自身の意味を説明しているはずですが、いくつかの点には言及しておくべきでしょう。
- The response will automatically set the MIME type application/pdf based on the filename extension. This tells browsers that the document is a PDF file, rather than an HTML file or a generic application/octet-stream binary content.
- When
as_attachment=True
is passed toFileResponse
, it sets the appropriateContent-Disposition
header and that tells web browsers to pop-up a dialog box prompting/confirming how to handle the document even if a default is set on the machine. If theas_attachment
parameter is omitted, browsers will handle the PDF using whatever program/plugin they've been configured to use for PDFs. - You can provide an arbitrary
filename
parameter. It'll be used by browsers in the "Save as..." dialog. - You can hook into the ReportLab API: The same buffer passed as the first
argument to
canvas.Canvas
can be fed to theFileResponse
class. - Note that all subsequent PDF-generation methods are called on the PDF
object (in this case,
p
) -- not onbuffer
. - Finally, it's important to call
showPage()
andsave()
on the PDF file.
注釈
ReportLab is not thread-safe. Some of our users have reported odd issues with building PDF-generating Django views that are accessed by many people at the same time.
Other formats¶
Notice that there isn't a lot in these examples that's PDF-specific -- just the
bits using reportlab
. You can use a similar technique to generate any
arbitrary format that you can find a Python library for. Also see
CSVを出力する for another example and some techniques you can use
when generated text-based formats.
参考
Django Packages provides a comparison of packages that help generate PDF files from Django.