module CombinePDF

This is a pure ruby library to combine/merge, stmap/overlay and number PDF files - as well as to create tables (ment for indexing combined files).

You can also use this library for writing basic text content into new or existing PDF files (For authoring new PDF files look at the Prawn ruby library).

here is the most basic application for the library, a one-liner that combines the PDF files and saves them:

(CombinePDF.new("file1.pdf") << CombinePDF.new("file2.pdf") << CombinePDF.new("file3.pdf")).save("combined.pdf")

Loading PDF data

Loading PDF data can be done from file system or directly from the memory.

Load data from a file:

pdf = CombinePDF.load("file.pdf")

parse PDF files from memory:

pdf = CombinePDF.parse(pdf_data)

Combine/Merge PDF files or Pages

To combine PDF files (or data):

pdf = CombinePDF.new
pdf << CombinePDF.load("file1.pdf")
pdf << CombinePDF.load("file2.pdf")
pdf.save "combined.pdf"

It is possible to add only specific pages. in this example, only even pages will be added:

pdf = CombinePDF.new
i = 0
CombinePDF.load("file.pdf").pages.each do |page|
  i += 1
  pdf << page if i.even?
end
pdf.save "even_pages.pdf"

Notice that adding the whole file is faster then adding each page seperately.

Add content to existing pages (Stamp / Watermark)

It is possible “stamp” one PDF page using another PDF page. In this example, a company logo will be stamped over each page:

company_logo = CombinePDF.load("company_logo.pdf").pages[0]
pdf = CombinePDF.load "content_file.pdf"
pdf.pages.each {|page| page << company_logo}
pdf.save "content_with_logo.pdf"

Notice the << operator is on a page and not a PDF object. The << operator acts differently on PDF objects and on Pages.

Page Numbering

It is possible to number the pages. in this example we will add very simple numbering:

pdf = CombinePDF.load "file_to_number.pdf"
pdf.number_pages
pdf.save "file_with_numbering.pdf"

numbering can be done with many different options, with different formating, with or without a box object, different locations on each page and even with opacity values.

Writing Content

page numbering actually adds content using the PDFWriter object (a very basic writer).

in this example, all the PDF pages will be stamped, along the top, with a red box, with blue text, stating “Draft, page #”. here is the easy way (we can even use “number_pages” without page numbers, if we wish):

pdf = CombinePDF.load "file_to_stamp.pdf"
pdf.number_pages number_format: " - Draft, page %d - ", number_location: [:top], font_color: [0,0,1], box_color: [0.4,0,0], opacity: 0.75, font_size:16
pdf.save "draft.pdf"

in this example we will add a first page with the word “Draft”, in red over a colored background:

pdf = CombinePDF.load "file.pdf"
pdf_first_page = pdf.pages[0]
mediabox = page[:CropBox] || page[:MediaBox] #copy page size
title_page = CombinePDF.create_page mediabox #make title page same size as first page
title_page.textbox "DRAFT", font_color: [0.8,0,0], font_size: :fit_text, box_color: [1,0.8,0.8], opacity: 1
pdf >> title_page # the >> operator adds pages at the begining
pdf.save "draft.pdf"

font support for the writer is still in the works and is limited to extracting know fonts by location of the 14 standard fonts.

Resizing pages

Using the {www.prepressure.com/library/paper-size PDF standards for page sizes}, it is now possible to resize existing PDF pages, as well as stretch and shrink their content to the new size.

pdf = CombinePDF.load "file.pdf"
a4_size = [0, 0, 595, 842]
# keep aspect ratio intact
pdf.pages.each {|p| p.resize a4_size}
pdf.save "a4.pdf"

pdf = CombinePDF.load "file.pdf"
a4_squared = [0, 0, 595, 595]
# stretch or shrink content to fit new size
pdf.pages.each {|p| p.resize a4_squared, false}
pdf.save "square.pdf"

Decryption & Filters

Some PDF files are encrypted and some are compressed (the use of filters)… not all files can be opened, merged, stamped or used and stamps.

Comments and file structure

If you want to help with the code, please be aware:

The code itself should be very straight forward, but feel free to ask whatever you want.

Credit

Caige Nichols wrote an amazing RC4 gem which I reference in my code. Credit to his wonderful is given here. Please respect his license and copyright… and mine.

License

MIT

Thoughts from reading the ISO 32000-1:2008 this file is part of the CombinePDF library and the code is subject to the same license.

Thoughts from reading the ISO 32000-1:2008 this file is part of the CombinePDF library and the code is subject to the same license.

Thoughts from reading the ISO 32000-1:2008 this file is part of the CombinePDF library and the code is subject to the same license.

Thoughts from reading the ISO 32000-1:2008 this file is part of the CombinePDF library and the code is subject to the same license.

Thoughts from reading the ISO 32000-1:2008 this file is part of the CombinePDF library and the code is subject to the same license.

Thoughts from reading the ISO 32000-1:2008 this file is part of the CombinePDF library and the code is subject to the same license.

Thoughts from reading the ISO 32000-1:2008 this file is part of the CombinePDF library and the code is subject to the same license.

frozen_string_literal: true

Thoughts from reading the ISO 32000-1:2008 this file is part of the CombinePDF library and the code is subject to the same license.