KeyError on pyfpdf

1,303 views
Skip to first unread message

thinkwell

unread,
Jul 14, 2012, 4:06:33 PM7/14/12
to web...@googlegroups.com
Hello everyone,

I'm experimenting with pyfpdf with HTML formatting, but it's not going so well. Is a bit buggy. For example, this code generates a KeyError: 'width'.

{from gluon.contrib.pyfpdf import FPDF, HTMLMixin
from gluon.html import *

header = HEAD('html2pdf', _align='center')

pets = TABLE(_border=1, _width="100%")
pets.append(TR(TH('Dogs'),TH("Cats"),TH('Snakes')))
pets.append(TR('Collies','Tabby','Python'))
pets.append(TR('Akitas', 'Persian', 'Garter'))

 
class MyFPDF(FPDF, HTMLMixin):
    pass

html2 = pets.xml()

print html2

pdf=MyFPDF()
#First page
pdf.add_page()
pdf.write_html(html2)
pdf.output('html2.pdf','F')}

I
{/usr/lib/python2.7/HTMLParser.pyc in goahead(self, end)
    156             if startswith('<', i):
    157                 if starttagopen.match(rawdata, i): # < + letter
--> 158                     k = self.parse_starttag(i)
    159                 elif startswith("</", i):
    160                     k = self.parse_endtag(i)

/usr/lib/python2.7/HTMLParser.pyc in parse_starttag(self, i)
    322             self.handle_startendtag(tag, attrs)
    323         else:
--> 324             self.handle_starttag(tag, attrs)
    325             if tag in self.CDATA_CONTENT_ELEMENTS:
    326                 self.set_cdata_mode(tag)

/home/dave/PythonTraining/web2py/gluon/contrib/pyfpdf/html.pyc in handle_starttag(self, tag, attrs)
    245             self.td = dict([(k.lower(), v) for k,v in attrs.items()])
    246             self.th = True
--> 247             if self.td.has_key('width'):
    248                 self.table_col_width.append(self.td['width'])
    249         if tag=='thead':

KeyError: 'width'
}

I tried changing line 247 to -
{if self.td.has_key('width'):}

But the KeyError is still getting raised. :-(

Is  generating reports from HTML not recommended? In addition to this KeyError, I've frequently gotten "list out of range" exceptions raised as well, on what seem like the most vanilla of experiments.


Alan Etkin

unread,
Jul 14, 2012, 5:54:15 PM7/14/12
to web...@googlegroups.com
Hello everyone,

I'm experimenting with pyfpdf with HTML formatting, but it's not going so well. Is a bit buggy. For example, this code generates a KeyError: 'width'.

It appears to have something to do with these project issues:

http://code.google.com/p/pyfpdf/issues/detail?id=8&q=width
http://code.google.com/p/pyfpdf/issues/detail?id=9&q=width

Also, a fix (supposedly non applied) was posted in issue 9

Mariano Reingart

unread,
Jul 15, 2012, 3:04:04 PM7/15/12
to web...@googlegroups.com
You need to restart the webservice to apply changes in gluon

> Is generating reports from HTML not recommended? In addition to this
> KeyError, I've frequently gotten "list out of range" exceptions raised as
> well, on what seem like the most vanilla of experiments.

Current html2pdf conversion will not work properly if you don't use
explicit widths for table cells.
You can see the supported tags and a working example here:

http://code.google.com/p/pyfpdf/wiki/WriteHTML

Actually, I'm working in a better html2pdf render, using helpers and
web2pyHTMLParser:

http://code.google.com/p/pyfpdf/source/browse/fpdf/html.py

Hopefully, web2py helpers will improve the rendering mechanisms

Best regards,

Mariano Reingart
http://www.sistemasagiles.com.ar
http://reingart.blogspot.com

thinkwell

unread,
Jul 16, 2012, 1:48:11 PM7/16/12
to web...@googlegroups.com
Thanks Mariano & Alan. Adding width to TD or TH tags did resolve the problem using the original html.py file without the fix implemented.(Mariano, I tried installing your script and at this point it still fails when no width is specified. Another little issue, os.startfile() seems to be a Windows-only method.)

So now, things are operational again. Looking forward to Mariano's html.py improvements.


On Sunday, July 15, 2012 3:04:04 PM UTC-4, Mariano Reingart wrote:

thinkwell

unread,
Jul 16, 2012, 4:08:13 PM7/16/12
to web...@googlegroups.com
Well, me again. I decided that I wanted to use points as measurements instead of percentages, so now it barfs with an AttributeError.



from gluon.contrib.pyfpdf import FPDF, HTMLMixin
from gluon.html import *


pets = TABLE(_width="720pt")
pets.append(TR(TH('Dogs', _width="72pt", _align="left"),TH("Cats",_width="72pt", _align="left"),TH('Snakes',_width="72pt", _align="left")))
pets.append(TR('Collies','Tabby','Python', _width="60pt"))

pets.append(TR('Akitas', 'Persian', 'Garter'))
pets.append(TR('German Shepherds', 'Alley Cats', 'Rattlesnakes'))


class MyFPDF(FPDF, HTMLMixin):
    pass

pdf=MyFPDF()
#First page
pdf.add_page()
pdf.write_html(pets.xml())

pdf.output('html2.pdf','F')


This is clearly unremarkable HTML, but no, I get tracebacks like so:

Traceback (most recent call last):
  File "pyfpdf_test.py", line 73, in <module>
    pdf.write_html(pets.xml())
  File "/home/dave/PythonTraining/web2py/gluon/contrib/pyfpdf/html.py", line 388, in write_html
    h2p.feed(text)
  File "/usr/lib/python2.7/HTMLParser.py", line 114, in feed
    self.goahead(0)
  File "/usr/lib/python2.7/HTMLParser.py", line 158, in goahead
    k = self.parse_starttag(i)
  File "/usr/lib/python2.7/HTMLParser.py", line 324, in parse_starttag
    self.handle_starttag(tag, attrs)
  File "/home/dave/PythonTraining/web2py/gluon/contrib/pyfpdf/html.py", line 241, in handle_starttag
    self.pdf.set_x(self.table_offset)
AttributeError: HTML2FPDF instance has no attribute 'table_offset'

I find this remarkable; this ordinary HTML; web2py encourages the use of HTML helpers. web2py is easy to use, requires few dependencies, etc. etc. But what a fight to create a simple table-based PDF! :-( And I'm still experimenting in the layout stage. My final report will be much larger and include nested tables (that are already rendering fine in HTML, but not in pyfpdf / html2pdf).

Should I bite the bullet and install Reportlab? It'll be harder to get started, more complicated to install & maintain (this will have to go on multiple machines). The idea of a simple web2py project was very attractive for these reasons.

Are others out there creating PDFs from HTML with pyfpdf & html2pdf??

Derek

unread,
Jul 16, 2012, 4:17:48 PM7/16/12
to web...@googlegroups.com
Try to use "em", see if you still get the same problem.

1em = 12pt

thinkwell

unread,
Jul 16, 2012, 4:34:28 PM7/16/12
to web...@googlegroups.com
No, the "em" still raises an AttributeError. In the post above, I've included all the code to duplicate the problem...

Cliff Kachinske

unread,
Jul 17, 2012, 11:22:19 AM7/17/12
to web...@googlegroups.com
Is this report to be printed?  If so, just generate a pdf.

Mariano Reingart

unread,
Jul 17, 2012, 2:46:04 PM7/17/12
to web...@googlegroups.com
Sorry, only percentage is supported.
Pt and Em and any other unit is not supported.
I'll try to add better error messages and documentation, sorry for the issue.

> I find this remarkable; this ordinary HTML; web2py encourages the use of
> HTML helpers. web2py is easy to use, requires few dependencies, etc. etc.
> But what a fight to create a simple table-based PDF! :-( And I'm still
> experimenting in the layout stage. My final report will be much larger and
> include nested tables (that are already rendering fine in HTML, but not in
> pyfpdf / html2pdf).

Sorry, but definitively your report is out of scope of html2pdf /
pyfpdf right now.
Please remember, the current implementation is a basic HTML parser to
do *basic* reports.
Nested tables are not supported and I don't think they will in the near future.
If I could get some funding maybe I could spend more time enhancing this.

> Should I bite the bullet and install Reportlab? It'll be harder to get
> started, more complicated to install & maintain (this will have to go on
> multiple machines). The idea of a simple web2py project was very attractive
> for these reasons.

AFAIK Reportlab doesn't even have a html2pdf conversor.
If you switch to reportlab, you will have to code your report using PlatyPlus.
You should consider they commercial licence that includes paid support
for this kind of issues.

As you said, the html2pdf recipe is a simple web2py project
Maybe you have to go with third-party tools like Pisa (xhtml2pdf) or
use built-in pdf conversion of chrome-browser, or pdf printers.

Akash Kakkar

unread,
Jul 18, 2012, 2:46:44 AM7/18/12
to web...@googlegroups.com
PFA Basic example pdf with nested tables using web2py-appreport plugin , Please let me know if this would work in your case.


I can test if you provide me the html of with the nested table you plan to have.

The attached report was generated using PISA (xhtmltopdf) part of the plugin.
report___20120718-120624.pdf

Massimo Di Pierro

unread,
Jul 18, 2012, 11:01:15 AM7/18/12
to web...@googlegroups.com
Nice.

thinkwell

unread,
Jul 18, 2012, 3:51:10 PM7/18/12
to web...@googlegroups.com

Thanks everybody for your assistance; I'm rethinking my approach here. I'd thought generating a PDF from html would make formatting quick & easy as well as flexible to output to a webpage. But since the PDF for printing is the primary need, perhaps using PDF cells is the way to go.

Thanks, Mariano, for your comments about nested tables. Akash, I might take you up on test HTML, or perhaps try your plugin.

Akash Kakkar

unread,
Jul 18, 2012, 4:43:47 PM7/18/12
to web...@googlegroups.com
The Web2py-Appreport plugin belongs to Lucas de Avilla :), I most probably will be using it for one of my Project.
Reply all
Reply to author
Forward
0 new messages