Inserting external PDF into Prawn generated document
Asked Answered
B

1

11

How can I insert an existing PDF into a Prawn generated document? I am generating a pdf for a bill (as a view), and that bill can have many attachments (png, jpg, or pdf). How can I insert/embed/include those external pdf attachments in my generated document? I've read the manual, looked over the source code, and searched online, but no luck so far.

The closest hint I've found is to use ImageMagick or something similar to convert the pdf to another format, but since I don't need to resize/manipulate the document, that seems wasteful. The old way to do it seems to be through templates, but my understanding is that the code for templating is unstable.

Does anyone know how to include PDF pages in a Prawn generated PDF? If Prawn won't do this, do you know of any supplementary gems that will? If someone can point me towards something like prawn-templates but more reliable, that would be awesome.

Edit: I am using prawnto and prawn to render PDF views in Rails 4.2.0 with Ruby 2.2.0.


Strategies that I've found but that seem inapplicable/too messy:

  • Create a jpg preview of a PDF on upload, include that in the generated document (downsides: no text selection/searching, expensive). This is currently my favorite option, but I don't like it.

  • prawn-templates (downside: unstable, unmaintained codebase; this is a business-critical application)

  • Merge PDFs through a gem like 'combine-pdf'–I can't figure out how to make this work for rendering a view with the external PDFs inserted at specific places (the generated pdf is a collection of bills, and I need them to follow the bill they're attached to)

Bibliomania answered 22/3, 2015 at 19:43 Comment(0)
A
13

You're right about the lack of existing documentation for this - I found only this issue from 2010 which uses the outdated methods you describe. I also found this SO answer which does not work now since Prawn dropped support for templates.

However, the good news is that there is a way to do what you want with Ruby! What you will be doing is merging the PDFs together, not "inserting" PDFs into the original PDF.

I would recommend this library, combine_pdf, to do so. The documentation is good, so doing what you want would be as simple as:

my_prawn_pdf = CombinePDF.new
my_prawn_pdf << CombinePDF.new("my_bill_pdf.pdf")
my_prawn_pdf << CombinePDF.new("attachment.pdf")
my_prawn_pdf.save "combined.pdf"

Edit

In response to your questions:

I'm using Prawn to render a pdf view in Rails, which means that I don't think I get that kind of post-processing

You do! If you look at the documentation for combine_pdf, you'll see that loading from memory is the fastest way to use the gem - the documentation even explicitly says that Prawn can be used as input.

I'm not just tacking the PDFs to the end: a bill attachment must directly follow the generated page(s) for a bill

The combine_pdf gem isn't just for adding pages on the end. As the documentation shows, you can cycle through a PDF adding pages when you want to, for example:

my_pdf # previously defined
new_pdf = CombinePDF.new
my_pdf.pages.each.do |page| 
  i += 1
  new_pdf << my_pdf if i == bill_number # or however you want to handle this logic
end
new_pdf.save "new_pdf.pdf"
Aestivation answered 24/3, 2015 at 23:4 Comment(2)
I did see combine_pdf in a different StackOverflow response, but I couldn't figure out how to use it for this situation. It looks like that's only useful for static, known PDFs; is that correct? I'm using Prawn to render a pdf view in Rails, which means that I don't think I get that kind of post-processing. Also, even if I'm wrong about that, I'm not just tacking the PDFs to the end: a bill attachment must directly follow the generated page(s) for a bill, and the PDF contains an arbitrary number of bills. Am I wrong in thinking that this solution isn't applicable to rendering Rails views?Bibliomania
@Bibliomania Sorry about the delay! You can do both of those things, and combine_pdf is applicable, as shown in my edited answer.Aestivation

© 2022 - 2024 — McMap. All rights reserved.