python - Generate PDF from HTML using Django and Reportlab - Stack Overflow
ReportLab in Django - Stack Overflow
ReportLab and Python 3.12 with Django 5.0.6
Django, ReportLab PDF Generation attached to an email - Stack Overflow
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.
SOLVED: Does anybody use ReportLab with Django 5 and Python 3.12?
I think mainly my issue is with using 3.12 but also I think it would be strange that ReportaLab works fine in dev using the same setup, Django and Python versions.
Basically I get a ‘ModuleNotFoundError: reportlab not found. ‘ when I launch the application with wsgi and Apache. However, when in a shell I use ‘from reportlab.pdfgen import canvas ‘ and then some more stuff to print a pdf and save it, I get the test.pdf just fine. Which should mean the Python interpreter is having no issue, and maybe it’s with my wsgi.py.
I’ve rebuilt the venv last night just in case that was the issue. Right now the app is in production and usable just without the pdf functionality.
Using ReportLab
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import letter, A4
from reportlab.lib.units import inch
def createPDF(request):
x=100
y=100
buffer=StringIO()
p=canvas.Canvas(buffer,pagesize=letter)
p.drawString(x,y,"HELLOWORLD")
p.showPage()
p.save()
pdf=buffer.getvalue()
buffer.close()
return pdf
def someView(request):
EmailMsg=mail.EmailMessage(YourSubject,YourEmailBodyCopy,'[email protected]',["[email protected]"],headers={'Reply-To':'[email protected]'})
pdf=createPDF(request)
EmailMsg.attach('yourChoosenFileName.pdf',pdf,'application/pdf')
EmailMsg.send()
Works perfectly!!
OK - I figured it out based on piecing a few things together -
First off - my requirements: - I only wanted to create the PDFs in memory - I don't want the files hanging around, as they take up space, and I don't want what might be sensitive data hanging around unprotected on the server.
So - I picked ReportLab and Platypus functionality for generating my documents. I've invested enough time into it now, that's it's easy. So here's my approach that lets me use the DocTempates in ReportLab, allows me to use Django's email capabilities to send emails.
Here's how I'm doing it:
# Create the PDF object, using the buffer object as its "file."
buffer = StringIO()
doc = SimpleDocTemplate(buffer, pagesize=letter)
Document = []
# CRUFT PDF Data
doc.build(Document)
pdf = buffer.getvalue()
buffer.close()
email = EmailMessage('Hello', 'Body', '[email protected]', ['[email protected]'])
email.attach('invoicex.pdf', pdf , 'application/pdf')
email.send()
My issue from moving from web generation to email generation was getting the right object that could be "attached" to an email. Creating a buffer, then grabbing the data off the buffer did it for me...