3
votes

I have a 4-page template for my PDF I would like to generate with prawn. I need to repeat this template in my pdf a number of times each time filling it with different content.

If I use:

  Prawn::Document.generate('output.pdf', template: "a_template.pdf")

I get the template once in the output.pdf, subsequent pages are empty.

If I use

  ["John", "Jane"].each do |user|
    start_new_page template: 'a_template.pdf', page: 1
    text "Content filled on page 1 for user #{user}"
    3.times { |i| start_new_page template: 'a_template.pdf', template_page: i+2 }
  end

I get the text "Content filled on page 1 for user..." repeated and overwriting one another, on every page that is the first page from the template. So for every fourth page I have content for all users rendered in the same place on the page.

Does anybody knows how to make prawn include a template a number of times, every time filling the template with different contents? I would like to avoid generating a bunch of PDF files and concatenating them together...

Even if I first concatenate together template required number of times, for each user using code below:

tmp_template = Tempfile.new ['template', '.pdf'], tmpdir

Prawn::Document.generate(tmp_template.path, skip_page_creation: true) do
  users.each do |u|
    4.times { |i| start_new_page template: card_tmpl, template_page: i+1 }
  end
end

And then do:

Prawn::Document.generate('output.pdf', template: tmp_template.path)

to fill subsequent template copies for subsequent users, it still puts the same content whenever the copy of the first page appears in the new template!

1

1 Answers

2
votes

No other appeared, so I did the following thing.

First create new PDF object without any pages:

pdf = Prawn::Document.new skip_page_creation: true

Then for each user:

  1. Create a new, complete PDF filling required template and save it to temporary file tempfile (using Tempfile).
  2. Include this temporary file in the PDF created at the beginning (the pdf object) like this (assuming that the template has two pages):
      2.times { |i| pdf.start_new_page template: tempfile, template_page: i+1 }

Finally, render the final PDF:

pdf.render 'output.pdf'

Performance is awful. But it works and PDF generated this way opens with acrobat reader.