parts/django/docs/howto/outputting-pdf.txt
changeset 69 c6bca38c1cbf
equal deleted inserted replaced
68:5ff1fc726848 69:c6bca38c1cbf
       
     1 ===========================
       
     2 Outputting PDFs with Django
       
     3 ===========================
       
     4 
       
     5 This document explains how to output PDF files dynamically using Django views.
       
     6 This is made possible by the excellent, open-source ReportLab_ Python PDF
       
     7 library.
       
     8 
       
     9 The advantage of generating PDF files dynamically is that you can create
       
    10 customized PDFs for different purposes -- say, for different users or different
       
    11 pieces of content.
       
    12 
       
    13 For example, Django was used at kusports.com_ to generate customized,
       
    14 printer-friendly NCAA tournament brackets, as PDF files, for people
       
    15 participating in a March Madness contest.
       
    16 
       
    17 .. _ReportLab: http://www.reportlab.org/oss/rl-toolkit/
       
    18 .. _kusports.com: http://www.kusports.com/
       
    19 
       
    20 Install ReportLab
       
    21 =================
       
    22 
       
    23 Download and install the ReportLab library from http://www.reportlab.org/oss/rl-toolkit/download/.
       
    24 The `user guide`_ (not coincidentally, a PDF file) explains how to install it.
       
    25 
       
    26 Test your installation by importing it in the Python interactive interpreter::
       
    27 
       
    28     >>> import reportlab
       
    29 
       
    30 If that command doesn't raise any errors, the installation worked.
       
    31 
       
    32 .. _user guide: http://www.reportlab.com/docs/reportlab-userguide.pdf
       
    33 
       
    34 Write your view
       
    35 ===============
       
    36 
       
    37 The key to generating PDFs dynamically with Django is that the ReportLab API
       
    38 acts on file-like objects, and Django's :class:`~django.http.HttpResponse`
       
    39 objects are file-like objects.
       
    40 
       
    41 Here's a "Hello World" example::
       
    42 
       
    43     from reportlab.pdfgen import canvas
       
    44     from django.http import HttpResponse
       
    45 
       
    46     def some_view(request):
       
    47         # Create the HttpResponse object with the appropriate PDF headers.
       
    48         response = HttpResponse(mimetype='application/pdf')
       
    49         response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'
       
    50 
       
    51         # Create the PDF object, using the response object as its "file."
       
    52         p = canvas.Canvas(response)
       
    53 
       
    54         # Draw things on the PDF. Here's where the PDF generation happens.
       
    55         # See the ReportLab documentation for the full list of functionality.
       
    56         p.drawString(100, 100, "Hello world.")
       
    57 
       
    58         # Close the PDF object cleanly, and we're done.
       
    59         p.showPage()
       
    60         p.save()
       
    61         return response
       
    62 
       
    63 The code and comments should be self-explanatory, but a few things deserve a
       
    64 mention:
       
    65 
       
    66     * The response gets a special MIME type, ``application/pdf``. This tells
       
    67       browsers that the document is a PDF file, rather than an HTML file. If
       
    68       you leave this off, browsers will probably interpret the output as HTML,
       
    69       which would result in ugly, scary gobbledygook in the browser window.
       
    70 
       
    71     * The response gets an additional ``Content-Disposition`` header, which
       
    72       contains the name of the PDF file. This filename is arbitrary: Call it
       
    73       whatever you want. It'll be used by browsers in the "Save as..."
       
    74       dialogue, etc.
       
    75 
       
    76     * The ``Content-Disposition`` header starts with ``'attachment; '`` in this
       
    77       example. This forces Web browsers to pop-up a dialog box
       
    78       prompting/confirming how to handle the document even if a default is set
       
    79       on the machine. If you leave off ``'attachment;'``, browsers will handle
       
    80       the PDF using whatever program/plugin they've been configured to use for
       
    81       PDFs. Here's what that code would look like::
       
    82 
       
    83           response['Content-Disposition'] = 'filename=somefilename.pdf'
       
    84 
       
    85     * Hooking into the ReportLab API is easy: Just pass ``response`` as the
       
    86       first argument to ``canvas.Canvas``. The ``Canvas`` class expects a
       
    87       file-like object, and :class:`~django.http.HttpResponse` objects fit the
       
    88       bill.
       
    89 
       
    90     * Note that all subsequent PDF-generation methods are called on the PDF
       
    91       object (in this case, ``p``) -- not on ``response``.
       
    92 
       
    93     * Finally, it's important to call ``showPage()`` and ``save()`` on the PDF
       
    94       file.
       
    95 
       
    96 Complex PDFs
       
    97 ============
       
    98 
       
    99 If you're creating a complex PDF document with ReportLab, consider using the
       
   100 cStringIO_ library as a temporary holding place for your PDF file. The cStringIO
       
   101 library provides a file-like object interface that is particularly efficient.
       
   102 Here's the above "Hello World" example rewritten to use ``cStringIO``::
       
   103 
       
   104     # Fall back to StringIO in environments where cStringIO is not available
       
   105     try:
       
   106         from cStringIO import StringIO
       
   107     except ImportError:
       
   108         from StringIO import StringIO
       
   109     from reportlab.pdfgen import canvas
       
   110     from django.http import HttpResponse
       
   111 
       
   112     def some_view(request):
       
   113         # Create the HttpResponse object with the appropriate PDF headers.
       
   114         response = HttpResponse(mimetype='application/pdf')
       
   115         response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'
       
   116 
       
   117         buffer = StringIO()
       
   118 
       
   119         # Create the PDF object, using the StringIO object as its "file."
       
   120         p = canvas.Canvas(buffer)
       
   121 
       
   122         # Draw things on the PDF. Here's where the PDF generation happens.
       
   123         # See the ReportLab documentation for the full list of functionality.
       
   124         p.drawString(100, 100, "Hello world.")
       
   125 
       
   126         # Close the PDF object cleanly.
       
   127         p.showPage()
       
   128         p.save()
       
   129 
       
   130         # Get the value of the StringIO buffer and write it to the response.
       
   131         pdf = buffer.getvalue()
       
   132         buffer.close()
       
   133         response.write(pdf)
       
   134         return response
       
   135 
       
   136 .. _cStringIO: http://docs.python.org/library/stringio.html#module-cStringIO
       
   137 
       
   138 Further resources
       
   139 =================
       
   140 
       
   141     * PDFlib_ is another PDF-generation library that has Python bindings. To
       
   142       use it with Django, just use the same concepts explained in this article.
       
   143     * `Pisa XHTML2PDF`_ is yet another PDF-generation library. Pisa ships with
       
   144       an example of how to integrate Pisa with Django.
       
   145     * HTMLdoc_ is a command-line script that can convert HTML to PDF. It
       
   146       doesn't have a Python interface, but you can escape out to the shell
       
   147       using ``system`` or ``popen`` and retrieve the output in Python.
       
   148 
       
   149 .. _PDFlib: http://www.pdflib.org/
       
   150 .. _`Pisa XHTML2PDF`: http://www.xhtml2pdf.com/
       
   151 .. _HTMLdoc: http://www.htmldoc.org/
       
   152 
       
   153 Other formats
       
   154 =============
       
   155 
       
   156 Notice that there isn't a lot in these examples that's PDF-specific -- just the
       
   157 bits using ``reportlab``. You can use a similar technique to generate any
       
   158 arbitrary format that you can find a Python library for. Also see
       
   159 :doc:`/howto/outputting-csv` for another example and some techniques you can use
       
   160 when generated text-based formats.