There is a problem when generate pdf with images using xhtml2pdf library. It took me quite some time to resolve these issues.
I’m using flask, microframework to generate the pdf. The first issues was the library dependency, it required to specified with version
html5lib==1.0b8
Next, issues
No handlers could be found for logger “xhtml2pdf”
This can be easily add the following code to find the real problem by adding this code
import logging
pisa.showLogging()
Complete example
from xhtml2pdf import pisa from StringIO import StringIO import logging pisa.showLogging() def create_pdf(pdf_data): pdf = StringIO() pisa.CreatePDF(StringIO(pdf_data.encode('utf-8')), pdf) resp = pdf.getvalue() pdf.close() return resp
After that you shall see something more useful error message like below
WARNING [xhtml2pdf] /workspace/merchant/venv/lib/python2.7/site-packages/xhtml2pdf/tags.py line 408: Need a valid file name! u'<img class="logo-center" src="/static/logo.png" style="zoom: 40%;"/>'
Next, the pdf generated contains no images. My images files was placed in /app/static/images/maillogo.png
<img src="{{ url_for('static', filename='images/maillogo.png') }}" />
The easier solution is to place the images together with the html file.
<img src="maillogo.png" height="60" width="120"/>
Run again directly compile with the command:
(venv) workspace mingch$ xhtml2pdf app/templates/mail/vourcher.html Converting app/templates/mail/vourcher.html to /workspace/app/templates/mail/vourcher.pdf...
But when you run in server mode, the problem is still persist. The root cause were suspect xhtml2pdf is not able to read the relative path. If you check on the this link, the error was cause by attr.src and (not attractive.src.notFound()):
class pisaTagIMG(pisaTag): def start(self, c): attr = self.attr if attr.src and (not attr.src.notFound()): try: align = attr.align or c.frag.vAlign or "baseline" # print "align", align, attr.align, c.frag.vAlign
Therefore, one possible solution is pass the absolute path as parameters.
Step 1: Get the absolute images path and assign into a variable
image_logo = os.path.join(os.getcwd(), 'app/static/images', 'maillogo' + '.png')
Step 2: Pass the variable into the template
vourcher = create_pdf(render_template('mail/vourcher.html', image_logo=image_logo))
IT WORKS PERFECTLY!!! THANKS A LOT!!!