Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inserting external PDF into Prawn generated document

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)

like image 312
Lee Avatar asked Mar 22 '15 19:03

Lee


1 Answers

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"
like image 164
element119 Avatar answered Sep 22 '22 18:09

element119