If you’ve ever needed to programmatically add text to a PDF in Ruby, then you know how tricky it can be. PDFs are complex, and finding tools that are both effective and up-to-date can be a challenge. Many guides rely on deprecated tools or outdated information. In this post, I'll walk through a solution I came up with using two tools:
- Prawn: The fast, nimble PDF writer for Ruby
- CombinePDF: The Ruby gem that combines PDFs
My approach looks like this:
- Create a new overlay PDF with the text I want on my existing PDF using Prawn
- Use
CombinePDF
to overlay the new PDF over the existing one so the text appears in the correct spot
This two-step approach is necessary because Prawn
excels at creating new PDFs but does not support modifying existing ones. Meanwhile, CombinePDF
makes it easy to manipulate and merge existing PDFs. By combining these tools, you get the best of both worlds—precision in adding text and flexibility in working with existing documents.
Create a New Overlay PDF Using Prawn
Using Prawn
is pretty straightforward. The Prawn manual has a bunch of helpful tips about what its PDF DSL can do. That is where you want to start to figure out how to arrange text, manipulate pages, and work with shapes.
As an example, getting things going looks like this:
document = Prawn::Document.new document.text_box "Hello, world", at: [20, 650], width: 200 document.start_new_page document.text_box "Some other words", at: [30, 500], width: 300
Overlay the New PDF Over the Existing One
To overlay the new PDF, you need to take three steps:
- Create a base PDF to hold your result: This acts as a container for the final combined document.
- Load your existing PDF and add it to the base PDF: This ensures that the original content remains intact and serves as the foundation for the overlay.
- Add your overlay PDF to the base PDF: This step places your new content in the correct position over the existing content, completing the merge.
That all comes together to look like this:
require 'combine_pdf' require 'prawn' # Let's create our base PDF to hold our result output_pdf = CombinePDF.new # Now let's read the PDF we want to write on and add it to the result existing_pdf = CombinePDF.load('/path/to/existing.pdf') existing_pdf.pages.each do |existing_pdf_page| output_pdf << existing_pdf_page end # Let's use Prawn to create our overlay overlay_document = Prawn::Document.new overlay_document.text_box "Hello, world", at: [20, 650], width: 200 # Now we'll add the pages of our overlay PDF to our base PDF overlay_pdf = CombinePDF.parse(overlay_document.render) overlay_pdf.pages.each_with_index do |overlay_pdf_page, index| if output_pdf.pages[index] output_pdf.pages[index] << overlay_pdf_page else raise "Overlay PDF has more pages than the existing PDF." end end # Finally, we'll render the result output_pdf.save('output.pdf')
Top comments (0)