Generate PDF from HTML using Django and Reportlab

18,249

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!

Share:
18,249
Dr Mouse
Author by

Dr Mouse

DevOps #Python

Updated on June 17, 2022

Comments

  • Dr Mouse
    Dr Mouse almost 2 years

    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 ?

  • Dr Mouse
    Dr Mouse almost 9 years
    Many thanks ! It seems pretty straightforward to use ! How would you integrate the code with Django ? Through a view ?
  • FlipperPA
    FlipperPA almost 9 years
    That would depend on what you're doing, but yes, most likely in a view.
  • metakermit
    metakermit about 7 years
    One problem I have with wkhtmltopdf is that it requires an external binary which is problematic to deploy to services like Heroku.
  • ZF007
    ZF007 over 4 years
    @FlipperPA ... link peregrinesalon.com/blog/2015/06/… nolonger working. Please update.
  • FlipperPA
    FlipperPA over 4 years
    @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: weasyprint.org
  • FlipperPA
    FlipperPA about 3 years
    @SharanArumugam Over the past few years, I've switched to using Weasyprint, which is BSD licensed. weasyprint.org
  • Sharan Arumugam
    Sharan Arumugam about 3 years
    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!