The Linux Page

xhtml2pdf generating an error under 14.04+

Note: This bug is fixed in Ubuntu 16.04

Working on a website I have to convert invoices to PDF so end users have the ability to print and share the invoices from the website.

In order to do that, I generate an HTML page with the invoice which also gets displayed in the website, and then convert that HTML to PDF with xhtml2pdf. I use that tool instead of whtmltopdf because it does not require X11 to work. The other tool is said to require Qt and X11 and we do not want those things on our backend servers.

So... I upgraded to 14.04 and the tool stopped working with an ugly error:

[20665]:process.cpp:396:halk: info: Running process "xhtml2pdf --quiet - -" in mode 3
****************************************************
IMPORT ERROR!
Reportlab Version 2.1+ is needed!
****************************************************

The following Python packages are required for PISA:
- Reportlab Toolkit >= 2.2 <http://www.reportlab.com/>
- HTML5lib >= 0.11.1 <https://github.com/html5lib/>

Optional packages:
- pyPDF <http://pybrary.net/pyPdf/>
- PIL <http://www.pythonware.com/products/pil/>

No handlers could be found for logger "sx.pisa3"
Traceback (most recent call last):
  File "/usr/bin/xhtml2pdf", line 9, in <module>
    load_entry_point('pisa==3.0.32', 'console_scripts', 'xhtml2pdf')()
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 351, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 2363, in load_entry_point
    return ep.load()
  File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 2088, in load
    entry = __import__(self.module_name, globals(),globals(), ['__name__'])
  File "/usr/lib/pymodules/python2.7/sx/pisa3/__init__.py", line 31, in <module>
    from pisa import *
  File "/usr/lib/pymodules/python2.7/sx/pisa3/pisa.py", line 21, in <module>
    from pisa_document import *
  File "/usr/lib/pymodules/python2.7/sx/pisa3/pisa_document.py", line 11, in <module>
    from pisa_context import pisaContext
  File "/usr/lib/pymodules/python2.7/sx/pisa3/pisa_context.py", line 11, in <module>
    from pisa_util import *
  File "/usr/lib/pymodules/python2.7/sx/pisa3/pisa_util.py", line 44, in <module>
    raise ImportError("Reportlab Version 2.1+ is needed!")
ImportError: Reportlab Version 2.1+ is needed!
[20665]:finball.cpp:12024:halk: error: backend_process: finball invoice already exist!? skipping

As we can see it checks for a version and thinks that the corresponding import is too old and breaks. The import reports version 3.0 and xhtml2pdf needs at least 2.1, so there is definitively a bug in that test. Indeed! The current test is:

if not (reportlab.Version[0] == "2" and reportlab.Version[2] >= "1"):
    raise ImportError("Reportlab Version 2.1+ is needed!")

REPORTLAB22 = (reportlab.Version[0] == "2" and reportlab.Version[2] >= "2")

And as we can see, the programmer wrote if not == 2. Now that we are at version 3, the test breaks. If only the programmer had not used a 'not', maybe he would have gotten it right.

The solution is to fix the test as follow:

if not(reportlab.Version[:3] >= "2.1"):
    raise ImportError("Reportlab Version 2.1+ is needed!")

REPORTLAB22 = (reportlab.Version[:3] >= "2.1")

Sweater if you ask me, I would also inverse the test to < and remove the not(), but anyway... that works for now. The main problem, when they offer an upgrade, I'll have to remember to go force the installation of the upgraded file.

Note that I found the solution on Stackoverflow (see link blow), however, I the stock version file is named pisa_util.py and it is found here:

/usr/lib/pymodules/python2.7/sx/pisa3/pisa_util.py

Just use an editor such as:

sudo gvim /usr/lib/pymodules/python2.7/sx/pisa3/pisa_util.py

And go fix these two lines of code!

Source: xhtml2pdf import error