Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set dynamically height for entire Prawn PDF Document

I'm stuck with a problem when trying to generate a document using Prawn gem for Rails

What I'm trying to do is to set a variable height for my pdf, so depending on some queries in the database, the PDF height will change. I'm doing this because I need a single page PDF document.

Currently, my code looks like this:

pdf = Prawn::Document.new(page_size: [297.64, 419.53], margin: 0)

....

data = [ ["Header1", "Header2", "Header3", "Header4", "Header5", "Header6"] ]

// here is the variable data
cart.cart_products.each do |cp|
  arr = [
    cp.product_code,
    cp.product_description,
    cp.amount,
    cp.product_metric,
    cp.product_unit_value,
    cp.total_value
  ]

  data.push(arr)
end

// populating the table with data
pdf.table(data, :cell_style => {:border_width => 0}, :column_widths => [45, 80, 30, 42.36, 50, 50]) do |table|
  table.row(0).border_width = 0.1.mm
  table.row(0).font_style = :bold
  table.row(0).borders = [:bottom]
end

....

pdf.render_file("path/to/dir/document.pdf")

Can anyone help me with this? Thanks.

like image 579
thiagotonon Avatar asked Feb 10 '23 09:02

thiagotonon


2 Answers

Without knowing what exactly you're adjusting for, I'll have to makes some guesses here.

So I would establish some sort of line height for your returned data and a min document height.

line_height = 14
min_height = 419.53

Then I would run the queries and count the results. Then I would figure out what the variable height would be and add it to the min height.

variable_height = results.length * line_height
height = min_height + variable_height

Finally:

pdf = Prawn::Document.new(page_size: [297.64, height], margin: 0)

Something like this should work with tweaks for your specific needs.

like image 55
Chase Avatar answered Feb 12 '23 00:02

Chase


Thomas Leitner suggested a better option in a GitHub issue comment (https://github.com/prawnpdf/prawn/issues/974#issuecomment-239751947):

Just what I wanted to post 😄 - so here it goes:

You could probably use a a very large height for your document so that prawn doesn't automatically create a new one. And once you are finished with everything, use Prawn::Document#y to determine your current vertical position.

Then you can use Prawn::Document#page (a PDF::Core::Page object) to adjust the MediaBox for the page, something like:

require 'prawn'

Prawn::Document.generate("test.pdf", page_size: [100, 2000], margin: 10) do |doc|
  rand(100).times do
    doc.text("some text")
  end
  doc.page.dictionary.data[:MediaBox] = [0, doc.y - 10, 100, 2000]
end

Credits to Thomas Leitner (https://github.com/gettalong)

like image 36
Repolês Avatar answered Feb 11 '23 23:02

Repolês