going crazy with pyfpdf

1,066 views
Skip to first unread message

Carlos Cesar Caballero Díaz

unread,
May 21, 2014, 11:13:36 AM5/21/14
to web...@googlegroups.com
Hi, I need some help, when I call a view with ".pdf" this:

<html>
    <head>
        <title>Report</title>
    </head>
    <body>
        <table>
            <tr>
                <td width="50%">name</td>
                <td width="50%">pepe</td>
            </tr>
        </table>
    </body>
</html>

or this:

<body>
    <table>
        <tr>
            <td width="50%">name</td>
            <td width="50%">pepe</td>
        </tr>
    </table>
</body>

returns a blank one page pdf. Now if I put the content before the body tag, it is rendered, but the table allways throw a
"Table column/cell width not specified, unable to continue" error.

Carlos Costa

unread,
May 21, 2014, 11:26:23 AM5/21/14
to web...@googlegroups.com
It uses pyfpdf to convert it.
But there are some restrictions as I remember.


--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to web2py+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Att.

Carlos J. Costa
Cientista da Computação
Esp. Gestão em Telecom

EL MELECH NEEMAN!
אָמֵן

Mariano Reingart

unread,
May 21, 2014, 11:33:34 AM5/21/14
to web...@googlegroups.com
Yes, pyfpdf has a basic html parser (based on python stdlib) and needs some conventions to translate tables to PDF.

Could you make a minimal example to test and debug it?
That way it would be easy to reproduce and see how to adapt the html to be rendered.

You can look at the documented examples, using <thead> and <th> tags will help, and you need to specify the total table and cell widths:


Best regards,

Carlos Cesar Caballero Díaz

unread,
May 21, 2014, 1:04:58 PM5/21/14
to web...@googlegroups.com
Thanks Mariano and Carlos, there is a simple code:

controller default.py:

def pdf_test:
    return dict(hello="hello")

view default/pdf_test.html:

<body>
    <h1>{{=hello}}</h1>
    <p>This is a text</p>
    <table width="100%">
        <thead>
            <tr>
                <th width="40%">name</th>
                <th width="60%">lastame</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td width="40%">pepe</td>
                <td width="60%">paco</td>
            </tr>
        </tbody>
    </table>
</body>


"http://localhost:8000/myapp/default/pdf_test.pdf" shows a "Table column/cell width not specified, unable to continue" error. and removing the table, return a blank pdf


El 21/05/14 11:33, Mariano Reingart escribió:

Cliff Kachinske

unread,
May 21, 2014, 2:03:09 PM5/21/14
to web...@googlegroups.com, desar...@spicm.cfg.sld.cu
I've seen this. My leaky memory says pyfpdf doesn't like percentages. Try absolute units and I think it will work.

Mariano Reingart

unread,
May 21, 2014, 2:25:06 PM5/21/14
to web...@googlegroups.com
It seems to be a web2py issue: generic view is sanitizing the html to much, so it is removing needed attributes (align, widht, etc.).

A workaround to bypass generic html sanitization is calling pyfpdf directly:

def pdf_test():
    import os
    from gluon.contrib.fpdf import FPDF, HTMLMixin
    from gluon.sanitizer import sanitize

    filename = '%s/%s.html' % (request.controller,request.function)
    html=response.render(filename)

    def image_map(path):
        if path.startswith('/%s/static/' % request.application):
            return os.path.join(request.folder, path.split('/', 2)[2])
        return 'http%s://%s%s' % (request.is_https and 's' or '', request.env.http_host, path)

    class MyFPDF(FPDF, HTMLMixin):
        pass
    pdf = MyFPDF()
    pdf.add_page()
    # pyfpdf needs some attributes to render the table correctly:
    html = sanitize(
        html, allowed_attributes={
            'a': ['href', 'title'],
            'img': ['src', 'alt'],
            'blockquote': ['type'],
            'td': ['align', 'bgcolor', 'colspan', 'height', 'width'],
            'tr': ['bgcolor', 'height', 'width'],
            'table': ['border', 'bgcolor', 'height', 'width'],
        }, escape=False)
    pdf.write_html(html, image_map=image_map)
    return XML(pdf.output(dest='S'))

I've made a Pull Request with the fix:


Best regards

Carlos Cesar Caballero Díaz

unread,
May 22, 2014, 1:17:31 AM5/22/14
to web...@googlegroups.com
Thanks Mariano, I am working with your solution right now.

El 21/05/14 14:25, Mariano Reingart escribió:
Reply all
Reply to author
Forward
0 new messages