Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pisa pdf converter is very slow with large tables

I'm using Pisa to convert HTML to PDF (in a Django project). It is very slow when handling tables that span over multiple pages:

a 200-rows table takes up to 150 seconds to be converted, while it takes 15 seconds if I split it into smaller tables.

Are there tips or best practices for building HTML tables to be handled by Pisa?

like image 972
Don Avatar asked Sep 29 '11 09:09

Don


1 Answers

I had the same problem. The document was just a front page and a huge table. PDF rendering time was increasing exponentially with the size of my content table.

I made a checklist of things to check out which might be the problem

I did simple timing on my PDF rendering function (since it could be the HTML rendering, passing it to StringIO, or creating the HTTP response), and noticed that the pisa.pisaDocument call did take 60 seconds to return. I did a checklist of things that might be the problem, and worked on them each. The checklist included Images, CSS, Markup complexity, and Frames.

Images barely affected the rendering time (I only had one per page, so YMMV). Neither did Frames.

Markup complexity was the main problem of my template. Apparently pisa will render several columns in a table very, very slowly

The table was taking too much time to render, but I noticed that if I split the table into smaller tables, the rendering time didn't increase exponentially anymore, and the time it took to render everything was cut in half. I used the below code in my Django template:

    {% if forloop.counter|divisibleby:20 %}</table><table>{% endif %}

edit: This fix does not work well with repeating table headers so if you're doing repeat="1" you have to know exactly how many rows to fit in each page.

Also, I had this monster of a selector in my CSS:

    html, body, div, span, applet, object, iframe,
    h1, h2, h3, h4, h5, h6, p, blockquote, pre,
    a, abbr, acronym, address, big, cite, code,
    del, dfn, em, img, ins, kbd, q, s, samp,
    small, strike, strong, sub, sup, tt, var,
    b, u, i, center,
    dl, dt, dd, ol, ul, li,
    fieldset, form, label, legend,
    table, caption, tbody, tfoot, thead, tr, th, td,
    article, aside, canvas, details, embed,
    figure, figcaption, footer, header, hgroup,
    menu, nav, output, ruby, section, summary,
    time, mark, audio, video{
        ...
    }

By changing it to * {...} the rendering sped up a bit. This was counter-intuitive since browsers will not render your page as fast when you use the * selector than when you are using the above monster.

Also, for some reason, merging two in-page <style> tags into one tag decreased rendering time, too.

like image 65
2 revs Avatar answered Nov 15 '22 21:11

2 revs