8

I am coming back with a new question which I am unable to answer, having scratched my head the whole day on it.

I want to generate a PDF from a webpage by clicking on a "Download PDF" button. I tried several modules including Reportlab and XHTML2PDF but I am not able to generate any pdf nor downloading it... Here is what I did with Reportlab, following Render HTML to PDF in Django site

-- views.py --

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 index_data(request):
#Code to generate data
     return render(request, "analytics/stat.html", locals())
     return render_to_pdf(
        'analytics/stat.html',
        {
            'pagesize':'A4',
            'mylist': results,
        }
    )

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(), content_type='application/pdf')
    return HttpResponse('We had some errors<pre>%s</pre>' % escape(html))

-- urls.py --

from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^$', "analytics.views.main_page", name="main_page"),
    url(r'^portail/$', "analytics.views.index_data", name="index"),
    url(r'^generate_pdf/$', "analytics.views.GroupPDFGenerate.as_view()", name="generate_pdf")

]

-- Template analytics/stat.html --

{% extends "analytics/layout.html" %}

{% block title %}
    Audience
{% endblock title %}

{% block head %}
 # Script to generate google charts
{% endblock head %}

{% block body %}
<div class="page-header">
  <h1 align="center"> Audience </h1>
</div>
<div class="row">
  <div class="col-md-1">
      <h3 align="center"><a href="/logout/">Logout</a></h3>
      <h3 align="center"><a href="statistiques.pdf">Download pdf</a></h3>
  </div>
 </div>

{% endblock %}

Also, is there a better module to process ?

Community
  • 1
  • 1
Dr Mouse
  • 331
  • 1
  • 5
  • 19
  • `xhtml2pdf` documentation now has an [example specifically for Django](https://xhtml2pdf.readthedocs.io/en/latest/usage.html#using-xhtml2pdf-in-django). – djvg Nov 20 '20 at 09:11

3 Answers3

7

UPDATE for 2021:

Since this answer is over half a decade old, some new solutions have become available. These days, I tend to use WeasyPrint, which has the additional benefit of being BSD licensed instead of LGPL. It is a tad slower, however.

https://weasyprint.org/


ORIGINAL ANSWER:

I'd recommend using wkhtmltopdf.

The short answer? On Ubuntu, install a binary:

apt-get install wkhtmltopdf

On CentOS / RedHat:

yum install wkhtmltox-0.12.2.1_linux-centos6-amd64.rpm

Then pip install a Python package:

pip install pdfkit

Then the code:

import pdfkit
 
input_filename = 'README.html'
output_filename = 'README.pdf'
 
with open(input_filename, 'r') as f:
    html_text = f.read()
 
pdfkit.from_string(html_text, output_filename)

For the long answer and details, I put together a blog post:

https://www.pyphilly.org/generating-pdf-markdown-or-html/

That should take care of the PDF creation; you'll have to decide how you want to handle the download. Good luck!

FlipperPA
  • 13,607
  • 4
  • 39
  • 71
  • Many thanks ! It seems pretty straightforward to use ! How would you integrate the code with Django ? Through a view ? – Dr Mouse Jul 22 '15 at 08:15
  • That would depend on what you're doing, but yes, most likely in a view. – FlipperPA Jul 23 '15 at 09:33
  • 1
    One problem I have with wkhtmltopdf is that it requires an external binary which is problematic to deploy to services like Heroku. – metakermit Mar 29 '17 at 15:26
  • 1
    @FlipperPA ... link http://www.peregrinesalon.com/blog/2015/06/python-3-django-generating-a-pdf-from-markdown-or-html/ nolonger working. Please update. – ZF007 Oct 15 '19 at 09:42
  • @metakermit @ZF007 I've updated the link to the blog post. An alternative to `pdfkit` / `wkhtmltopdf` is `weasyprint`, although it has pre-reqs which can be tricky as well: https://weasyprint.org/ – FlipperPA Oct 15 '19 at 14:11
  • 1
    @SharanArumugam Over the past few years, I've switched to using Weasyprint, which is BSD licensed. https://weasyprint.org/ – FlipperPA Apr 24 '21 at 14:46
  • 1
    thank you @FlipperPA for the update, unfortunately, in windows, we need GTK runtime to use weasyprint, and this again ends up being a LGPL again! – Sharan Arumugam May 04 '21 at 16:20
0

If you say you are having problems even generating your PDF, I suggest you start by looking over the example I mentioned in this answer of using Reportlab, xhtml2pdf with django-easy-pdf. Get the PDF to render in the browser first and then move on to getting a link for downloading it.

Community
  • 1
  • 1
metakermit
  • 21,267
  • 15
  • 86
  • 95
-2
from easy_pdf.rendering import render_to_pdf

def pdf(request):
    with open('example.pdf', 'wb') as f2:
        f2.write(render_to_pdf('you template', {'user': request.user}, encoding=u'utf-8'))