Sophie

Sophie

distrib > Mandriva > current > i586 > media > main-updates > by-pkgid > 57efe471f3561e70a829edf1b0e9f507 > files > 2248

python-django-1.1.4-0.1mdv2010.2.noarch.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Outputting PDFs with Django &mdash; Django v1.1 documentation</title>
    <link rel="stylesheet" href="../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '../',
        VERSION:     '1.1',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="../_static/jquery.js"></script>
    <script type="text/javascript" src="../_static/doctools.js"></script>
    <link rel="top" title="Django v1.1 documentation" href="../index.html" />
    <link rel="up" title="“How-to” guides" href="index.html" />
    <link rel="next" title="How to serve static files" href="static-files.html" />
    <link rel="prev" title="Outputting CSV with Django" href="outputting-csv.html" />
 
<script type="text/javascript" src="../templatebuiltins.js"></script>
<script type="text/javascript">
(function($) {
    if (!django_template_builtins) {
       // templatebuiltins.js missing, do nothing.
       return;
    }
    $(document).ready(function() {
        // Hyperlink Django template tags and filters
        var base = "../ref/templates/builtins.html";
        if (base == "#") {
            // Special case for builtins.html itself
            base = "";
        }
        // Tags are keywords, class '.k'
        $("div.highlight\\-html\\+django span.k").each(function(i, elem) {
             var tagname = $(elem).text();
             if ($.inArray(tagname, django_template_builtins.ttags) != -1) {
                 var fragment = tagname.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>");
             }
        });
        // Filters are functions, class '.nf'
        $("div.highlight\\-html\\+django span.nf").each(function(i, elem) {
             var filtername = $(elem).text();
             if ($.inArray(filtername, django_template_builtins.tfilters) != -1) {
                 var fragment = filtername.replace(/_/, '-');
                 $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>");
             }
        });
    });
})(jQuery);
</script>

  </head>
  <body>

    <div class="document">
  <div id="custom-doc" class="yui-t6">
    <div id="hd">
      <h1><a href="../index.html">Django v1.1 documentation</a></h1>
      <div id="global-nav">
        <a title="Home page" href="../index.html">Home</a>  |
        <a title="Table of contents" href="../contents.html">Table of contents</a>  |
        <a title="Global index" href="../genindex.html">Index</a>  |
        <a title="Module index" href="../modindex.html">Modules</a>
      </div>
      <div class="nav">
    &laquo; <a href="outputting-csv.html" title="Outputting CSV with Django">previous</a> 
     |
    <a href="index.html" title="&amp;#8220;How-to&amp;#8221; guides" accesskey="U">up</a>
   |
    <a href="static-files.html" title="How to serve static files">next</a> &raquo;</div>
    </div>
    
    <div id="bd">
      <div id="yui-main">
        <div class="yui-b">
          <div class="yui-g" id="howto-outputting-pdf">
            
  <div class="section" id="s-outputting-pdfs-with-django">
<span id="s-howto-outputting-pdf"></span><span id="outputting-pdfs-with-django"></span><span id="howto-outputting-pdf"></span><h1>Outputting PDFs with Django<a class="headerlink" href="#outputting-pdfs-with-django" title="Permalink to this headline">¶</a></h1>
<p>This document explains how to output PDF files dynamically using Django views.
This is made possible by the excellent, open-source <a class="reference external" href="http://www.reportlab.org/oss/rl-toolkit/">ReportLab</a> Python PDF
library.</p>
<p>The advantage of generating PDF files dynamically is that you can create
customized PDFs for different purposes &#8211; say, for different users or different
pieces of content.</p>
<p>For example, Django was used at <a class="reference external" href="http://www.kusports.com/">kusports.com</a> to generate customized,
printer-friendly NCAA tournament brackets, as PDF files, for people
participating in a March Madness contest.</p>
<div class="section" id="s-install-reportlab">
<span id="install-reportlab"></span><h2>Install ReportLab<a class="headerlink" href="#install-reportlab" title="Permalink to this headline">¶</a></h2>
<p>Download and install the ReportLab library from <a class="reference external" href="http://www.reportlab.org/oss/rl-toolkit/download/">http://www.reportlab.org/oss/rl-toolkit/download/</a>.
The <a class="reference external" href="http://www.reportlab.com/docs/reportlab-userguide.pdf">user guide</a> (not coincidentally, a PDF file) explains how to install it.</p>
<p>Test your installation by importing it in the Python interactive interpreter:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">reportlab</span>
</pre></div>
</div>
<p>If that command doesn't raise any errors, the installation worked.</p>
</div>
<div class="section" id="s-write-your-view">
<span id="write-your-view"></span><h2>Write your view<a class="headerlink" href="#write-your-view" title="Permalink to this headline">¶</a></h2>
<p>The key to generating PDFs dynamically with Django is that the ReportLab API
acts on file-like objects, and Django's <a title="django.http.HttpResponse" class="reference external" href="../ref/request-response.html#django.http.HttpResponse"><tt class="xref docutils literal"><span class="pre">HttpResponse</span></tt></a>
objects are file-like objects.</p>
<p>Here's a &quot;Hello World&quot; example:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">reportlab.pdfgen</span> <span class="kn">import</span> <span class="n">canvas</span>
<span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponse</span>

<span class="k">def</span> <span class="nf">some_view</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="c"># Create the HttpResponse object with the appropriate PDF headers.</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="n">mimetype</span><span class="o">=</span><span class="s">&#39;application/pdf&#39;</span><span class="p">)</span>
    <span class="n">response</span><span class="p">[</span><span class="s">&#39;Content-Disposition&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;attachment; filename=somefilename.pdf&#39;</span>

    <span class="c"># Create the PDF object, using the response object as its &quot;file.&quot;</span>
    <span class="n">p</span> <span class="o">=</span> <span class="n">canvas</span><span class="o">.</span><span class="n">Canvas</span><span class="p">(</span><span class="n">response</span><span class="p">)</span>

    <span class="c"># Draw things on the PDF. Here&#39;s where the PDF generation happens.</span>
    <span class="c"># See the ReportLab documentation for the full list of functionality.</span>
    <span class="n">p</span><span class="o">.</span><span class="n">drawString</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="s">&quot;Hello world.&quot;</span><span class="p">)</span>

    <span class="c"># Close the PDF object cleanly, and we&#39;re done.</span>
    <span class="n">p</span><span class="o">.</span><span class="n">showPage</span><span class="p">()</span>
    <span class="n">p</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">response</span>
</pre></div>
</div>
<p>The code and comments should be self-explanatory, but a few things deserve a
mention:</p>
<ul>
<li><p class="first">The response gets a special MIME type, <tt class="docutils literal"><span class="pre">application/pdf</span></tt>. This tells
browsers that the document is a PDF file, rather than an HTML file. If
you leave this off, browsers will probably interpret the output as HTML,
which would result in ugly, scary gobbledygook in the browser window.</p>
</li>
<li><p class="first">The response gets an additional <tt class="docutils literal"><span class="pre">Content-Disposition</span></tt> header, which
contains the name of the PDF file. This filename is arbitrary: Call it
whatever you want. It'll be used by browsers in the &quot;Save as...&quot;
dialogue, etc.</p>
</li>
<li><p class="first">The <tt class="docutils literal"><span class="pre">Content-Disposition</span></tt> header starts with <tt class="docutils literal"><span class="pre">'attachment;</span> <span class="pre">'</span></tt> in this
example. This forces 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 you leave off <tt class="docutils literal"><span class="pre">'attachment;'</span></tt>, browsers will handle
the PDF using whatever program/plugin they've been configured to use for
PDFs. Here's what that code would look like:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">response</span><span class="p">[</span><span class="s">&#39;Content-Disposition&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;filename=somefilename.pdf&#39;</span>
</pre></div>
</div>
</li>
<li><p class="first">Hooking into the ReportLab API is easy: Just pass <tt class="docutils literal"><span class="pre">response</span></tt> as the
first argument to <tt class="docutils literal"><span class="pre">canvas.Canvas</span></tt>. The <tt class="docutils literal"><span class="pre">Canvas</span></tt> class expects a
file-like object, and <a title="django.http.HttpResponse" class="reference external" href="../ref/request-response.html#django.http.HttpResponse"><tt class="xref docutils literal"><span class="pre">HttpResponse</span></tt></a> objects fit the
bill.</p>
</li>
<li><p class="first">Note that all subsequent PDF-generation methods are called on the PDF
object (in this case, <tt class="docutils literal"><span class="pre">p</span></tt>) -- not on <tt class="docutils literal"><span class="pre">response</span></tt>.</p>
</li>
<li><p class="first">Finally, it's important to call <tt class="docutils literal"><span class="pre">showPage()</span></tt> and <tt class="docutils literal"><span class="pre">save()</span></tt> on the PDF
file.</p>
</li>
</ul>
</div>
<div class="section" id="s-complex-pdfs">
<span id="complex-pdfs"></span><h2>Complex PDFs<a class="headerlink" href="#complex-pdfs" title="Permalink to this headline">¶</a></h2>
<p>If you're creating a complex PDF document with ReportLab, consider using the
<a class="reference external" href="http://docs.python.org/library/stringio.html#module-cStringIO">cStringIO</a> library as a temporary holding place for your PDF file. The cStringIO
library provides a file-like object interface that is particularly efficient.
Here's the above &quot;Hello World&quot; example rewritten to use <tt class="docutils literal"><span class="pre">cStringIO</span></tt>:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">cStringIO</span> <span class="kn">import</span> <span class="n">StringIO</span>
<span class="kn">from</span> <span class="nn">reportlab.pdfgen</span> <span class="kn">import</span> <span class="n">canvas</span>
<span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponse</span>

<span class="k">def</span> <span class="nf">some_view</span><span class="p">(</span><span class="n">request</span><span class="p">):</span>
    <span class="c"># Create the HttpResponse object with the appropriate PDF headers.</span>
    <span class="n">response</span> <span class="o">=</span> <span class="n">HttpResponse</span><span class="p">(</span><span class="n">mimetype</span><span class="o">=</span><span class="s">&#39;application/pdf&#39;</span><span class="p">)</span>
    <span class="n">response</span><span class="p">[</span><span class="s">&#39;Content-Disposition&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s">&#39;attachment; filename=somefilename.pdf&#39;</span>

    <span class="nb">buffer</span> <span class="o">=</span> <span class="n">StringIO</span><span class="p">()</span>

    <span class="c"># Create the PDF object, using the StringIO object as its &quot;file.&quot;</span>
    <span class="n">p</span> <span class="o">=</span> <span class="n">canvas</span><span class="o">.</span><span class="n">Canvas</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>

    <span class="c"># Draw things on the PDF. Here&#39;s where the PDF generation happens.</span>
    <span class="c"># See the ReportLab documentation for the full list of functionality.</span>
    <span class="n">p</span><span class="o">.</span><span class="n">drawString</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="mi">100</span><span class="p">,</span> <span class="s">&quot;Hello world.&quot;</span><span class="p">)</span>

    <span class="c"># Close the PDF object cleanly.</span>
    <span class="n">p</span><span class="o">.</span><span class="n">showPage</span><span class="p">()</span>
    <span class="n">p</span><span class="o">.</span><span class="n">save</span><span class="p">()</span>

    <span class="c"># Get the value of the StringIO buffer and write it to the response.</span>
    <span class="n">pdf</span> <span class="o">=</span> <span class="nb">buffer</span><span class="o">.</span><span class="n">getvalue</span><span class="p">()</span>
    <span class="nb">buffer</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
    <span class="n">response</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">pdf</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">response</span>
</pre></div>
</div>
</div>
<div class="section" id="s-further-resources">
<span id="further-resources"></span><h2>Further resources<a class="headerlink" href="#further-resources" title="Permalink to this headline">¶</a></h2>
<ul class="simple">
<li><a class="reference external" href="http://www.pdflib.org/">PDFlib</a> is another PDF-generation library that has Python bindings. To
use it with Django, just use the same concepts explained in this article.</li>
<li><a class="reference external" href="http://www.xhtml2pdf.com/">Pisa XHTML2PDF</a> is yet another PDF-generation library. Pisa ships with
an example of how to integrate Pisa with Django.</li>
<li><a class="reference external" href="http://www.htmldoc.org/">HTMLdoc</a> is a command-line script that can convert HTML to PDF. It
doesn't have a Python interface, but you can escape out to the shell
using <tt class="docutils literal"><span class="pre">system</span></tt> or <tt class="docutils literal"><span class="pre">popen</span></tt> and retrieve the output in Python.</li>
</ul>
</div>
<div class="section" id="s-other-formats">
<span id="other-formats"></span><h2>Other formats<a class="headerlink" href="#other-formats" title="Permalink to this headline">¶</a></h2>
<p>Notice that there isn't a lot in these examples that's PDF-specific -- just the
bits using <tt class="docutils literal"><span class="pre">reportlab</span></tt>. You can use a similar technique to generate any
arbitrary format that you can find a Python library for. Also see
<a class="reference external" href="outputting-csv.html#howto-outputting-csv"><em>Outputting CSV with Django</em></a> for another example and some techniques you can use
when generated text-based formats.</p>
</div>
</div>


          </div>         
        </div>
      </div>
      
        
          <div class="yui-b" id="sidebar">
            
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <h3><a href="../contents.html">Table Of Contents</a></h3>
            <ul>
<li><a class="reference external" href="#">Outputting PDFs with Django</a><ul>
<li><a class="reference external" href="#install-reportlab">Install ReportLab</a></li>
<li><a class="reference external" href="#write-your-view">Write your view</a></li>
<li><a class="reference external" href="#complex-pdfs">Complex PDFs</a></li>
<li><a class="reference external" href="#further-resources">Further resources</a></li>
<li><a class="reference external" href="#other-formats">Other formats</a></li>
</ul>
</li>
</ul>

  <h3>Browse</h3>
  <ul>
    
      <li>Prev: <a href="outputting-csv.html">Outputting CSV with Django</a></li>
    
    
      <li>Next: <a href="static-files.html">How to serve static files</a></li>
    
  </ul>
  <h3>You are here:</h3>
  <ul>
      <li>
        <a href="../index.html">Django v1.1 documentation</a>
        
          <ul><li><a href="index.html">&#8220;How-to&#8221; guides</a>
        
        <ul><li>Outputting PDFs with Django</li></ul>
        </li></ul>
      </li>
  </ul>  

            <h3>This Page</h3>
            <ul class="this-page-menu">
              <li><a href="../_sources/howto/outputting-pdf.txt"
                     rel="nofollow">Show Source</a></li>
            </ul>
          <div id="searchbox" style="display: none">
            <h3>Quick search</h3>
              <form class="search" action="../search.html" method="get">
                <input type="text" name="q" size="18" />
                <input type="submit" value="Go" />
                <input type="hidden" name="check_keywords" value="yes" />
                <input type="hidden" name="area" value="default" />
              </form>
              <p class="searchtip" style="font-size: 90%">
              Enter search terms or a module, class or function name.
              </p>
          </div>
          <script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
              <h3>Last update:</h3>
              <p class="topless">Feb 18, 2011</p>
          </div> 
        
      
    </div>
    
    <div id="ft">
      <div class="nav">
    &laquo; <a href="outputting-csv.html" title="Outputting CSV with Django">previous</a> 
     |
    <a href="index.html" title="&amp;#8220;How-to&amp;#8221; guides" accesskey="U">up</a>
   |
    <a href="static-files.html" title="How to serve static files">next</a> &raquo;</div>
    </div>
  </div>

      <div class="clearer"></div>
    </div>
  </body>
</html>