ruby-on-railsrubypdf-generationprawnprawnto

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:


Solution

  • 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"