views:

1576

answers:

4

For my django powered site, I am looking for an easy solution to convert dynamic html pages (generated using django views and templates datas generated using GET forms) which also contains some graph charts from google visualisation api(it is javascript, yet including these graphs is a must for me) to pdf. Cheers

A: 

Try the command line print firefox extension.

Martin v. Löwis
the issue is not all my clients will be using firefox, also I won't be able to force them to use extension.
I did not suggest to run this on the client, but on the server.
Martin v. Löwis
+2  A: 

Django documentation is deep and covers a lot. Did you have any problems with the method suggested there?

http://docs.djangoproject.com/en/dev/howto/outputting-pdf/

monkut
This doesn't actually answer the question. That documentation is on how to render a PDF natively, not from rendered HTML.
Josh
+18  A: 

Try the solution from Reportlab.

Download it and install it as usual with python setup.py install

You will also need to install the following modules: pisa, html5lib, pypdf with easy_install.

Here is an usage example:

First define this function:

import cStringIO as StringIO
import ho.pisa as pisa
from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
from cgi import escape


def render_to_pdf(template_src, context_dict):
    template = get_template(template_src)
    context = Context(context_dict)
    html  = template.render(context)
    result = StringIO.StringIO()

    pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("ISO-8859-1")), result)
    if not pdf.err:
        return HttpResponse(result.getvalue(), mimetype='application/pdf')
    return HttpResponse('We had some errors<pre>%s</pre>' % escape(html))

Then you can use it like this:

def myview(request):
    #Retrieve data or whatever you need
    return render_to_pdf(
            'mytemplate.html',
            {
                'pagesize':'A4',
                'mylist': results,
            }
        )

The template:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;
<html>
    <head>
        <title>My Title</title>
        <style type="text/css">
            @page {
                size: {{ pagesize }};
                margin: 1cm;
                @frame footer {
                    -pdf-frame-content: footerContent;
                    bottom: 0cm;
                    margin-left: 9cm;
                    margin-right: 9cm;
                    height: 1cm;
                }
            }
        </style>
    </head>
    <body>
        <div>
            {% for item in mylist %}
                RENDER MY CONTENT
            {% endfor %}
        </div>
        <div id="footerContent">
            {%block page_foot%}
                Page <pdf:pagenumber>
            {%endblock%}
        </div>
    </body>
</html>

Hope it helps.

Guillem Gelabert
wow great answer, thanks alot Guillem!
+1 I've been using this solution for a year and its great. PISA can even create barcodes with a simple tag, plus much more. And its *easy*.
arcanum
A: 

thanks Guillem - works very nicely!

radovan