HTML to PDF in Django

Install pdfkit:

pip install pdfkit

pdfkit uses wkhtmltopdf binary so we also need to install it. If you run Ubuntu do:

sudo apt-get install wkhtmltopdf

If you run Windows get binary here: http://wkhtmltopdf.org/downloads.html . You need to add path to wkhtmltopdf.exe into PATH variable. E.g. if you use default install path you have to add c:\Program Files\wkhtmltopdf\bin\. Restart programs that will run your app (e.g. IDE) to apply changes in PATH.

Now, in Django you can create the next view:

def export_to_pdf(request, tip_id):
    options = {
        'page-size': 'A4',
        'margin-top': '0.55in',
        'margin-right': '0.55in',
        'margin-bottom': '0.55in',
        'margin-left': '0.55in',
        'encoding': "UTF-8",
        # any other wkhtmltopdf options
    }
    
    content = render_to_string(
        'pdf_template.html', {
            'contents': some_your_html
        }
    )
    
    pdf = pdfkit.PDFKit(content, "string", options=options).to_pdf()
    
    response = HttpResponse(pdf)
    response['Content-Type'] = 'application/pdf'
    # change attachment to inline if you want open file in browser tab instead downloading
    response['Content-disposition'] = 'attachment;filename={}.pdf'.format(your_filename)
    
    return response

Create HTML template. Example:

<!DOCTYPE html>
<html>
<head>
    <title>Some title here</title>
    <style type="text/css">
    <!-- if you need style use: -->
    {% include  "some_your_style_that_you_need.css" %}
    
    </style>
</head>
<body>
    {{ contents | safe }}
</body>
</html>

If you want style like in example above you need add path to your some_your_style_that_you_need.css into TEMPLATES 'DIRS' setting in settings.py

If you want to add images from your server you can use path to file on server instead web URLs, e.g. <img src="/srv/www/server.jpg" >

Solving problem with required X server for version < 0.12.2.1

One drawback of this method is that Versions of wkhtmltopdf < 0.12.2.1 need X server. If you can't or don't want install newer version, but need to run headless on servers where there is no X server, you can easily emulate it with xvfb:

apt-get install xvfb

Create file named wkhtmltopdf_xfaked.sh in your Django project base dir - near manage.py (e.g. using vim or nano) and add there:

#!/bin/bash
xvfb-run -a -s "-screen 0 1024x768x24" wkhtmltopdf $*

Add executable permission to script:

chmod +x wkhtmltopdf_xfaked.sh

Then we need to force pdfkit to use our wkhtmltopdf_xfaked.sh instead of default binary:

if settings.PRODUCTION:
    # on production we have no X server, that needed for wkhtmltopdf, so we will emulate it and so we need to use custom path to wkhtmltopdf executable
    config = pdfkit.configuration(wkhtmltopdf=os.path.join(settings.BASE_DIR, 'wkhtmltopdf_xfaked.sh').encode())
    pdf = pdfkit.PDFKit(content, "string", options=options, configuration=config).to_pdf()
else:
    # on dev machine I use Windows so it is no need to emulate X sereve and redefine path
    pdf = pdfkit.PDFKit(content, "string", options=options).to_pdf()

Also if you need some extra fonts to support, e.g monospaced you can also install:

mkfontdir
sudo apt-get install xfonts-100dpi xfonts-75dpi xfonts-cyrillic
sudo apt-get install ttf-mscorefonts-installer

(Need to accept EULA in the installer)

#html #pdf
0
Ivan Borshchov profile picture
Dec 03, 2016
by Ivan Borshchov
Did it help you?
Yes !
No

Best related