Forum: Ruby on Rails pdf/writer: table.render_on best practices?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Nicolas B. (Guest)
on 2006-05-05 20:02
(Received via mailing list)
Hi All,

I generate a pdf report that contains a table. The report is 14 pages,
and
it takes 20s to be rendered. Most of these 20s are spend in the
render_on
method. I wonder if it is possible to speed up that process?

To create the report, I do the following:
1) Setup pdf layout:
# Setup pdf layout
      pdf.select_font("Helvetica", { :encoding => "WinAnsiEncoding"})
      pdf.text " ", :font_size => 12, :justification => :center
      s = 9
      t = 'Seite <PAGENUM>'
      y = pdf.absolute_bottom_margin - 5
      x = pdf.absolute_right_margin
      x -=(pdf.text_width('Seite XX', s))
      pdf.start_page_numbering(x, y, s, nil, t, nil)
      pdf.open_object do |heading|
         pdf.save_state
         pdf.stroke_color! Color::Black
         pdf.stroke_style! PDF::Writer::StrokeStyle::DEFAULT
         s = 9
         t = "My title - " + Date.today().to_s
         w = pdf.text_width(t, s) / 2.0
         x = pdf.margin_x_middle
         y = pdf.absolute_top_margin
         pdf.add_text(x - w, y, t, s)
         x = pdf.absolute_left_margin
         w = pdf.absolute_right_margin
         y -= (pdf.font_height(s) * 1.01)
         pdf.line(x, y, w, y).stroke
         y = pdf.absolute_bottom_margin + pdf.font_height(9) - 2
         pdf.line(x, y, w, y).stroke
         pdf.restore_state
         pdf.close_object
         pdf.add_object(heading, :all_pages)
      end

2) create a table:
table = PDF::SimpleTable.new

3) populate the table
table.data = dataArray

4) set which rows are displayed, and in which order:
table.column_order = rows
(Note: only some rows are displayed)

5) I set the width:
table.width = pdf.absolute_right_margin - pdf.absolute_left_margin

6) I call table.render_on(pdf):
table.render_on(pdf)

7) I send the file with send_file

Steps 1,2,3,4,5 and 7 takes less than 2 sec altogether. Step 6 takes
about
17s. I must say that the margins are not correct, and that the table
goes
over the header and footer of my document (does it matter for rendering
time?)

Any clue of what I could do to speed this up? or maybe this is normal
speed?

Regards,

Nicolas
Austin Z. (Guest)
on 2006-05-05 20:24
(Received via mailing list)
On 5/5/06, Nicolas B. <removed_email_address@domain.invalid> wrote:
> I generate a pdf report that contains a table. The report is 14 pages, and
> it takes 20s to be rendered. Most of these 20s are spend in the render_on
> method. I wonder if it is possible to speed up that process?

SimpleTable#render_on is slow. There may be ways to speed it up, but I
have not had time to investigate them yet.

-austin
Nicolas B. (Guest)
on 2006-05-05 20:42
(Received via mailing list)
OK, then I'll just live with it - and maybe show a blinking "please
wait" to
the user. There is no way to avoid a "render_on", right?

Thanks,

Nicolas
Austin Z. (Guest)
on 2006-05-05 20:49
(Received via mailing list)
On 5/5/06, Nicolas B. <removed_email_address@domain.invalid> wrote:
> OK, then I'll just live with it - and maybe show a blinking "please wait" to
> the user. There is no way to avoid a "render_on", right?

Not if you want that table. ;)

-austin
Jodi S. (Guest)
on 2006-05-05 21:01
(Received via mailing list)
Hey Austin,

I'm also generating a big table - probably 100 pages or more
(inventory report) - the client currently sets it up to print overnight.

While this is 'ok', I'd prefer to speed it up for them. I'd be
willing to take a look at the table rendering code - Do you have any
hints on where I'd focus my attention?

cheers,
Jodi
Austin Z. (Guest)
on 2006-05-05 21:04
(Received via mailing list)
On 5/5/06, Jodi S. <removed_email_address@domain.invalid> wrote:
> Hey Austin,
>
> I'm also generating a big table - probably 100 pages or more
> (inventory report) - the client currently sets it up to print overnight.
>
> While this is 'ok', I'd prefer to speed it up for them. I'd be
> willing to take a look at the table rendering code - Do you have any
> hints on where I'd focus my attention?

Transaction::Simple. Or at least the use thereof.

Transaction::Simple does its job well, but I'm not currently doing a
good job of clearing unused data and keeping too much rewind
information, I think. Reducing that should bring a performance boost.
Figuring out a way to precalculate the size of the data so that rewind
doesn't have to happen would be good, too. It would be cheaper to
simulate to set up pagination points than to recover if we do need to
paginate.

-austin
Jodi S. (Guest)
on 2006-05-06 01:13
(Received via mailing list)
On 5-May-06, at 1:03 PM, Austin Z. wrote:
>
> -austin

Ok. after much rumination and consideration about writing a
preprocessor it became clearer that the transactions were the
(slowdown) culprit(duh), and if I'm dealing with a huge number of
rows then split_rows should NEVER be set to true, as the (rewind)
rollback condition would never occur, and thus the transaction space
would fill up - 1 transaction per row.

...and \me had split_rows set to false (default value).

grin.

after using the correct setting I'm looking at a 1000% speedup.

So the only code improvement I might suggest Austin would be to set
split_rows to true if render_on detects more rows than can ever be
fit on one page - or perhaps a private that does the same thing
without changing the programmers interface.

Nicolas you might check to see if you've set split_rows correctly -
you'll get the same pdf output, but transactions won't be used to
hold row state.

cheers,
Jodi
Nicolas B. (Guest)
on 2006-05-06 18:39
(Received via mailing list)
Thanks Jodi, great advice!
This topic is locked and can not be replied to.