As you already know how to use ReportLab, I guess that this would do the job : https://github.com/xhtml2pdf/xhtml2pdf
xhtml2pdf
A library for converting HTML into PDFs using ReportLab
Sample code, taken from the Github :
# -*- coding: utf-8 -*-
# Copyright 2010 Dirk Holtwick, holtwick.it
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
__version__ = "$Revision: 194 $"
__author__ = "$Author: holtwick $"
__date__ = "$Date: 2008-04-18 18:59:53 +0200 (Fr, 18 Apr 2008) $"
import os
import sys
import cgi
import cStringIO
import logging
import xhtml2pdf.pisa as pisa
# Shortcut for dumping all logs to the screen
pisa.showLogging()
def dumpErrors(pdf, showLog=True):
#if showLog and pdf.log:
# for mode, line, msg, code in pdf.log:
# print "%s in line %d: %s" % (mode, line, msg)
#if pdf.warn:
# print "*** %d WARNINGS OCCURED" % pdf.warn
if pdf.err:
print "*** %d ERRORS OCCURED" % pdf.err
def testSimple(
data="""Hello <b>World</b><br/><img src="img/test.jpg"/>""",
dest="test.pdf"):
"""
Simple test showing how to create a PDF file from
PML Source String. Also shows errors and tries to start
the resulting PDF
"""
pdf = pisa.CreatePDF(
cStringIO.StringIO(data),
file(dest, "wb")
)
if pdf.err:
dumpErrors(pdf)
else:
pisa.startViewer(dest)
def testCGI(data="Hello <b>World</b>"):
"""
This one shows, how to get the resulting PDF as a
file object and then send it to STDOUT
"""
result = cStringIO.StringIO()
pdf = pisa.CreatePDF(
cStringIO.StringIO(data),
result
)
if pdf.err:
print "Content-Type: text/plain"
print
dumpErrors(pdf)
else:
print "Content-Type: application/octet-stream"
print
sys.stdout.write(result.getvalue())
def testBackgroundAndImage(
src="test-background.html",
dest="test-background.pdf"):
"""
Simple test showing how to create a PDF file from
PML Source String. Also shows errors and tries to start
the resulting PDF
"""
pdf = pisa.CreatePDF(
file(src, "r"),
file(dest, "wb"),
log_warn = 1,
log_err = 1,
path = os.path.join(os.getcwd(), src)
)
dumpErrors(pdf)
if not pdf.err:
pisa.startViewer(dest)
def testURL(
url="http://www.htmltopdf.org",
dest="test-website.pdf"):
"""
Loading from an URL. We open a file like object for the URL by
using 'urllib'. If there have to be loaded more data from the web,
the pisaLinkLoader helper is passed as 'link_callback'. The
pisaLinkLoader creates temporary files for everything it loads, because
the Reportlab Toolkit needs real filenames for images and stuff. Then
we also pass the url as 'path' for relative path calculations.
"""
import urllib
pdf = pisa.CreatePDF(
urllib.urlopen(url),
file(dest, "wb"),
log_warn = 1,
log_err = 1,
path = url,
link_callback = pisa.pisaLinkLoader(url).getFileName
)
dumpErrors(pdf)
if not pdf.err:
pisa.startViewer(dest)
if __name__=="__main__":
testSimple()
# testCGI()
#testBackgroundAndImage()
#testURL()
Or you can use pdfkit :
https://pypi.python.org/pypi/pdfkit
Before using it you need to install some things :
pip install pdfkit
sudo apt-get install wkhtmltopdf
Sample code to generate pdf :
import pdfkit
pdfkit.from_url('http://stackoverflow.com', 'out.pdf')
pdfkit.from_file('test.html', 'out2.pdf')
pdfkit.from_string('Thanks for reading!', 'out3.pdf')
Answer from CyborgForever on Stack OverflowAs you already know how to use ReportLab, I guess that this would do the job : https://github.com/xhtml2pdf/xhtml2pdf
xhtml2pdf
A library for converting HTML into PDFs using ReportLab
Sample code, taken from the Github :
# -*- coding: utf-8 -*-
# Copyright 2010 Dirk Holtwick, holtwick.it
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
__version__ = "$Revision: 194 $"
__author__ = "$Author: holtwick $"
__date__ = "$Date: 2008-04-18 18:59:53 +0200 (Fr, 18 Apr 2008) $"
import os
import sys
import cgi
import cStringIO
import logging
import xhtml2pdf.pisa as pisa
# Shortcut for dumping all logs to the screen
pisa.showLogging()
def dumpErrors(pdf, showLog=True):
#if showLog and pdf.log:
# for mode, line, msg, code in pdf.log:
# print "%s in line %d: %s" % (mode, line, msg)
#if pdf.warn:
# print "*** %d WARNINGS OCCURED" % pdf.warn
if pdf.err:
print "*** %d ERRORS OCCURED" % pdf.err
def testSimple(
data="""Hello <b>World</b><br/><img src="img/test.jpg"/>""",
dest="test.pdf"):
"""
Simple test showing how to create a PDF file from
PML Source String. Also shows errors and tries to start
the resulting PDF
"""
pdf = pisa.CreatePDF(
cStringIO.StringIO(data),
file(dest, "wb")
)
if pdf.err:
dumpErrors(pdf)
else:
pisa.startViewer(dest)
def testCGI(data="Hello <b>World</b>"):
"""
This one shows, how to get the resulting PDF as a
file object and then send it to STDOUT
"""
result = cStringIO.StringIO()
pdf = pisa.CreatePDF(
cStringIO.StringIO(data),
result
)
if pdf.err:
print "Content-Type: text/plain"
print
dumpErrors(pdf)
else:
print "Content-Type: application/octet-stream"
print
sys.stdout.write(result.getvalue())
def testBackgroundAndImage(
src="test-background.html",
dest="test-background.pdf"):
"""
Simple test showing how to create a PDF file from
PML Source String. Also shows errors and tries to start
the resulting PDF
"""
pdf = pisa.CreatePDF(
file(src, "r"),
file(dest, "wb"),
log_warn = 1,
log_err = 1,
path = os.path.join(os.getcwd(), src)
)
dumpErrors(pdf)
if not pdf.err:
pisa.startViewer(dest)
def testURL(
url="http://www.htmltopdf.org",
dest="test-website.pdf"):
"""
Loading from an URL. We open a file like object for the URL by
using 'urllib'. If there have to be loaded more data from the web,
the pisaLinkLoader helper is passed as 'link_callback'. The
pisaLinkLoader creates temporary files for everything it loads, because
the Reportlab Toolkit needs real filenames for images and stuff. Then
we also pass the url as 'path' for relative path calculations.
"""
import urllib
pdf = pisa.CreatePDF(
urllib.urlopen(url),
file(dest, "wb"),
log_warn = 1,
log_err = 1,
path = url,
link_callback = pisa.pisaLinkLoader(url).getFileName
)
dumpErrors(pdf)
if not pdf.err:
pisa.startViewer(dest)
if __name__=="__main__":
testSimple()
# testCGI()
#testBackgroundAndImage()
#testURL()
Or you can use pdfkit :
https://pypi.python.org/pypi/pdfkit
Before using it you need to install some things :
pip install pdfkit
sudo apt-get install wkhtmltopdf
Sample code to generate pdf :
import pdfkit
pdfkit.from_url('http://stackoverflow.com', 'out.pdf')
pdfkit.from_file('test.html', 'out2.pdf')
pdfkit.from_string('Thanks for reading!', 'out3.pdf')
If you use django framework you could use django-easy-pdf. I think it's the least painfull way to generate PDF from Html. Here's the template and views of my project:
#Import the easy_pdf rendering
from easy_pdf.rendering import render_to_pdf_response
#Here's the detail view function
def detail_to_pdf(request,id):
template = 'renderdetail.html'
kucing = Kucing.objects.get(id = id)
context = {'kucing' : kucing}
return render_to_pdf_response(request,template,context)
The Template is:
{% extends "base.html" %}
{% block extra_style %}
<style type="text/css">
body {
font-family: "Helvetica", "sans-serif";
color: #333333;
}
</style>
{% endblock %}
{% block content %}
<div id="content">
<div class="main">
<h1>PROFILE : {{ kucing.nama }}- ID:{{ kucing.id }}</h1>
<img src="/media/{{ kucing.foto }}"><br>
<p>Nama : {{ kucing.nama }}</p><br>
<p>Hp : {{ kucing.hp}}</p><br>
<p>Poin : {{ kucing.poin }}</p><br>
<a href="{% url 'kucing_makan' kucing.id %}">Makan</a>
<a href="{% url 'kucing_berburu' kucing.id %}">Berburu</a>
<hr>
<h5><a href="{% url 'kucing_home' %}">Back To Home</a></h5>|
<h5><a href="{% url 'kucing_list' %}">See Another Kucing</a></h5>
</div>
</div>
{% endblock %}
You also able to use Class Based Views by overriding PDFTemplateViews. You can see more on the Docs.
python - Generate PDF from HTML using Django and Reportlab - Stack Overflow
How to create a pdf report Reportlab
How to generate PDF file from an HTML file using Reportlab and Pisa in Python? - Stack Overflow
Reportlab, Weasy, Wkhtml - oh my! Which PDF/Printing plugin to use?
Videos
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!
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.
I need to generate PDF's.
While pdfkit looks very promising with its ability to render HTML with styling (Which would absolutely be the most epicness as almost no new templating would have to be made) it also depends on wkhtmltopdf and maybe even a virtual X server.
I want my tool to be deployable without the hastle to install non pythonesque tools. I want people to be able to install my package and use it after installing its requirements.txt. previously I've been using FPDF but its also not so modern..
So anyone has any hints?
I'd also be open to hints about deployment if this is not as big of an issue as I think . As this is basically a webapp which people might run on their own PC's, I'm open to good firefox/chrome hints to print a styled page aswell.