outputting-pdf.txt 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. =======================
  2. How to create PDF files
  3. =======================
  4. This document explains how to output PDF files dynamically using Django views.
  5. This is made possible by the excellent, open-source ReportLab_ Python PDF
  6. library.
  7. The advantage of generating PDF files dynamically is that you can create
  8. customized PDFs for different purposes -- say, for different users or different
  9. pieces of content.
  10. For example, Django was used at kusports.com_ to generate customized,
  11. printer-friendly NCAA tournament brackets, as PDF files, for people
  12. participating in a March Madness contest.
  13. .. _ReportLab: https://www.reportlab.com/opensource/
  14. .. _kusports.com: http://www2.kusports.com/
  15. Install ReportLab
  16. =================
  17. The ReportLab library is `available on PyPI`_. A `user guide`_ (not
  18. coincidentally, a PDF file) is also available for download.
  19. You can install ReportLab with ``pip``:
  20. .. console::
  21. $ python -m pip install reportlab
  22. Test your installation by importing it in the Python interactive interpreter:
  23. .. code-block:: pycon
  24. >>> import reportlab
  25. If that command doesn't raise any errors, the installation worked.
  26. .. _available on PyPI: https://pypi.org/project/reportlab/
  27. .. _user guide: https://www.reportlab.com/docs/reportlab-userguide.pdf
  28. Write your view
  29. ===============
  30. The key to generating PDFs dynamically with Django is that the ReportLab API
  31. acts on file-like objects, and Django's :class:`~django.http.FileResponse`
  32. objects accept file-like objects.
  33. Here's a "Hello World" example::
  34. import io
  35. from django.http import FileResponse
  36. from reportlab.pdfgen import canvas
  37. def some_view(request):
  38. # Create a file-like buffer to receive PDF data.
  39. buffer = io.BytesIO()
  40. # Create the PDF object, using the buffer as its "file."
  41. p = canvas.Canvas(buffer)
  42. # Draw things on the PDF. Here's where the PDF generation happens.
  43. # See the ReportLab documentation for the full list of functionality.
  44. p.drawString(100, 100, "Hello world.")
  45. # Close the PDF object cleanly, and we're done.
  46. p.showPage()
  47. p.save()
  48. # FileResponse sets the Content-Disposition header so that browsers
  49. # present the option to save the file.
  50. buffer.seek(0)
  51. return FileResponse(buffer, as_attachment=True, filename='hello.pdf')
  52. The code and comments should be self-explanatory, but a few things deserve a
  53. mention:
  54. * The response will automatically set the MIME type :mimetype:`application/pdf`
  55. based on the filename extension. This tells browsers that the document is a
  56. PDF file, rather than an HTML file or a generic
  57. :mimetype:`application/octet-stream` binary content.
  58. * When ``as_attachment=True`` is passed to ``FileResponse``, it sets the
  59. appropriate ``Content-Disposition`` header and that tells web browsers to
  60. pop-up a dialog box prompting/confirming how to handle the document even if a
  61. default is set on the machine. If the ``as_attachment`` parameter is omitted,
  62. browsers will handle the PDF using whatever program/plugin they've been
  63. configured to use for PDFs.
  64. * You can provide an arbitrary ``filename`` parameter. It'll be used by browsers
  65. in the "Save as..." dialog.
  66. * You can hook into the ReportLab API: The same buffer passed as the first
  67. argument to ``canvas.Canvas`` can be fed to the
  68. :class:`~django.http.FileResponse` class.
  69. * Note that all subsequent PDF-generation methods are called on the PDF
  70. object (in this case, ``p``) -- not on ``buffer``.
  71. * Finally, it's important to call ``showPage()`` and ``save()`` on the PDF
  72. file.
  73. .. note::
  74. ReportLab is not thread-safe. Some of our users have reported odd issues
  75. with building PDF-generating Django views that are accessed by many people
  76. at the same time.
  77. Other formats
  78. =============
  79. Notice that there isn't a lot in these examples that's PDF-specific -- just the
  80. bits using ``reportlab``. You can use a similar technique to generate any
  81. arbitrary format that you can find a Python library for. Also see
  82. :doc:`/howto/outputting-csv` for another example and some techniques you can use
  83. when generated text-based formats.
  84. .. seealso::
  85. Django Packages provides a `comparison of packages
  86. <https://djangopackages.org/grids/g/pdf/>`_ that help generate PDF files
  87. from Django.