mirror of
https://github.com/django/django.git
synced 2024-11-29 22:56:46 +01:00
4a954cfd11
This patch does not remove all occurrences of the words in question. Rather, I went through all of the occurrences of the words listed below, and judged if they a) suggested the reader had some kind of knowledge/experience, and b) if they added anything of value (including tone of voice, etc). I left most of the words alone. I looked at the following words: - simply/simple - easy/easier/easiest - obvious - just - merely - straightforward - ridiculous Thanks to Carlton Gibson for guidance on how to approach this issue, and to Tim Bell for providing the idea. But the enormous lion's share of thanks go to Adam Johnson for his patient and helpful review.
121 lines
4.2 KiB
Plaintext
121 lines
4.2 KiB
Plaintext
===========================
|
|
Outputting PDFs with Django
|
|
===========================
|
|
|
|
This document explains how to output PDF files dynamically using Django views.
|
|
This is made possible by the excellent, open-source ReportLab_ Python PDF
|
|
library.
|
|
|
|
The advantage of generating PDF files dynamically is that you can create
|
|
customized PDFs for different purposes -- say, for different users or different
|
|
pieces of content.
|
|
|
|
For example, Django was used at kusports.com_ to generate customized,
|
|
printer-friendly NCAA tournament brackets, as PDF files, for people
|
|
participating in a March Madness contest.
|
|
|
|
.. _ReportLab: https://www.reportlab.com/opensource/
|
|
.. _kusports.com: http://www.kusports.com/
|
|
|
|
Install ReportLab
|
|
=================
|
|
|
|
The ReportLab library is `available on PyPI`_. A `user guide`_ (not
|
|
coincidentally, a PDF file) is also available for download.
|
|
You can install ReportLab with ``pip``:
|
|
|
|
.. console::
|
|
|
|
$ python -m pip install reportlab
|
|
|
|
Test your installation by importing it in the Python interactive interpreter::
|
|
|
|
>>> import reportlab
|
|
|
|
If that command doesn't raise any errors, the installation worked.
|
|
|
|
.. _available on PyPI: https://pypi.org/project/reportlab/
|
|
.. _user guide: https://www.reportlab.com/docs/reportlab-userguide.pdf
|
|
|
|
Write your view
|
|
===============
|
|
|
|
The key to generating PDFs dynamically with Django is that the ReportLab API
|
|
acts on file-like objects, and Django's :class:`~django.http.FileResponse`
|
|
objects accept file-like objects.
|
|
|
|
Here's a "Hello World" example::
|
|
|
|
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 code and comments should be self-explanatory, but a few things deserve a
|
|
mention:
|
|
|
|
* The response will automatically set the MIME type :mimetype:`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 to ``FileResponse``, it sets the
|
|
appropriate ``Content-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 the ``as_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 the
|
|
:class:`~django.http.FileResponse` class.
|
|
|
|
* Note that all subsequent PDF-generation methods are called on the PDF
|
|
object (in this case, ``p``) -- not on ``buffer``.
|
|
|
|
* Finally, it's important to call ``showPage()`` and ``save()`` on the PDF
|
|
file.
|
|
|
|
.. note::
|
|
|
|
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
|
|
:doc:`/howto/outputting-csv` for another example and some techniques you can use
|
|
when generated text-based formats.
|
|
|
|
.. seealso::
|
|
|
|
Django Packages provides a `comparison of packages
|
|
<https://djangopackages.org/grids/g/pdf/>`_ that help generate PDF files
|
|
from Django.
|