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)