16

I want to generate pdf file from html using Python + Flask. To do this, I use xhtml2pdf. Here is my code:

def main():
    pdf = StringIO()
    pdf = create_pdf(render_template('cvTemplate.html', user=user))
    pdf_out = pdf.getvalue()
    response = make_response(pdf_out)
    return response

def create_pdf(pdf_data):
    pdf = StringIO()
    pisa.CreatePDF(StringIO(pdf_data.encode('utf-8')), pdf)
    return pdf

In this code file is generating on the fly. BUT! xhtml2pdf doesn't support many styles in CSS, because of this big problem to mark page correctly. I found another instrument(wkhtmltopdf). But when I wrote something like:

pdf = StringIO()
data = render_template('cvTemplate1.html', user=user)
WKhtmlToPdf(data.encode('utf-8'), pdf)
return pdf

Was raised error:

AttributeError: 'cStringIO.StringO' object has no attribute 'rfind'

And my question is how to convert html to pdf using wkhtmltopdf (with generating file on the fly) in Flask?

Thanks in advance for your answers.

Dmitry_Mahrachev
  • 279
  • 1
  • 2
  • 8

4 Answers4

21

The page need render, You can use pdfkit:

https://pypi.python.org/pypi/pdfkit

https://github.com/JazzCore/python-pdfkit

Example in document.

import pdfkit

pdfkit.from_url('http://google.com', 'out.pdf')
pdfkit.from_file('test.html', 'out.pdf')
pdfkit.from_string('Hello!', 'out.pdf')  # Is your requirement?
uwu
  • 1,590
  • 1
  • 11
  • 21
  • 5
    Ok. This code works fine (excludind troubles with install wkhtmltopdf): rendered_template = render_template('template.html', user=user) rendered_template = rendered_template.encode('utf-8') pdf = pdfkit.from_string(rendered_template, False, css='./static/styles.css') return make_response(pdf) Thanks! – Dmitry_Mahrachev Jan 28 '15 at 11:22
  • but it is need install wkhtmlpdf – Ganesan J Jun 23 '21 at 04:22
  • it is working in local .But not able to install in cpanel (live server).How to install wkhtmlpdf in cpanel – Ganesan J Jun 23 '21 at 04:23
11

Have you tried with Flask-WeasyPrint, which uses WeasyPrint? There are good examples in their web sites so I don't replicate them here.

chfw
  • 4,502
  • 2
  • 29
  • 32
  • The install instructions looked intimidating because of package dependencies but ````pip install weasyprint```` took care of everything. – JohnMudd Dec 23 '15 at 14:47
  • 3
    WeasyPrint cannot handle JavaScript. – Craicerjack Sep 25 '17 at 16:01
  • WeasyPrint support CSS2.1 but have no mention of js support. So if js support is needed, as of now, I would say pypuppeteer may help. – chfw Nov 18 '18 at 10:21
1

Not sure if this would assist anyone but my issue was capturing Bootstrap5 elements as a pdf. pdfkit did not do so and heres a work around on windows using html2image and PIL. This is limited and does not take a full page screenshot.

from html2image import Html2Image
from PIL import Image

try:
   hti.screenshot(html_file=C:\yourfilepath\file.html, save_as="test.png")

finally:
   image1 = Image.open(r'C:\yourfilepath\test.png')
   im1 = image1.convert('RGB')
   im1.save(r'C:\yourfilepath\newpdf.pdf')
idcabnun
  • 21
  • 3
0
    config =   pdfkit.configuration(wkhtmltopdf='C:\Program 
        Files\wkhtmltopdf\\bin\wkhtmltopdf.exe') 

    filename = "receipt.pdf"
    pdf = pdfkit.from_file('templates/receipt.html', False,configuration=config)
    response = make_response(pdf)
    response.headers['Content-Type'] = 'application/pdf'
    response.headers['Content-Disposition'] = f'attachment; filename={filename}'
    return response
  • first download wkhtml externally and setup in your system then mention the path of that. don't forget to change "\bin" to "\\bin". – Mukesh Nayal Apr 28 '23 at 14:00