class PdfForms::PdftkWrapper
Wraps calls to PdfTk
Constants
- ALLOWED_OPTIONS
- PDFTK
Attributes
Public Class Methods
Initializes a new wrapper instance. Pdftk will be autodetected from PATH: PdftkWrapper.new
(:flatten => true, :encrypt => true, :encrypt_options => 'allow Printing')
The pdftk binary may also be explecitly specified: PdftkWrapper.new
('/usr/bin/pdftk', :flatten => true, :encrypt => true, :encrypt_options => 'allow Printing')
Besides the options shown above, the drop_xfa or drop_xmp options are also supported.
# File lib/pdf_forms/pdftk_wrapper.rb, line 29 def initialize(*args) pdftk, options = normalize_args *args @pdftk = Cliver.detect! pdftk raise "pdftk executable #{@pdftk} not found" unless call_pdftk('-h') && $?.success? @options = options end
Public Instance Methods
returns the commands output, check general execution success with $?.success?
# File lib/pdf_forms/pdftk_wrapper.rb, line 87 def call_pdftk(*args) SafeShell.execute pdftk, *(args.flatten) end
concatenate documents, can optionally specify page ranges
args: in_file1, {in_file2 => [“1-2”, “4-10”]}, … , in_file_n, output
# File lib/pdf_forms/pdftk_wrapper.rb, line 94 def cat(*args) in_files = [] page_ranges = [] file_handle = "A" output = normalize_path args.pop args.flatten.compact.each do |in_file| if in_file.is_a? Hash path = in_file.keys.first page_ranges.push *in_file.values.first.map {|range| "#{file_handle}#{range}"} else path = in_file page_ranges.push "#{file_handle}" end in_files.push "#{file_handle}=#{normalize_path(path)}" file_handle.next! end call_pdftk in_files, 'cat', page_ranges, 'output', output end
pdftk.fill_form '/path/to/form.pdf', '/path/to/destination.pdf', :field1 => 'value 1'
# File lib/pdf_forms/pdftk_wrapper.rb, line 37 def fill_form(template, destination, data = {}, fill_options = {}) q_template = normalize_path(template) q_destination = normalize_path(destination) fdf = data_format(data) tmp = Tempfile.new('pdf_forms-fdf') tmp.close fdf.save_to tmp.path fill_options = {:tmp_path => tmp.path}.merge(fill_options) args = [ q_template, 'fill_form', normalize_path(tmp.path), 'output', q_destination ] result = call_pdftk(*(append_options(args, fill_options))) unless File.readable?(destination) && File.size(destination) > 0 fdf_path = nil begin fdf_path = File.join(File.dirname(tmp.path), "#{Time.now.strftime '%Y%m%d%H%M%S'}.fdf") fdf.save_to fdf_path rescue Exception fdf_path = "#{$!}\n#{$!.backtrace.join("\n")}" end raise PdftkError.new("failed to fill form with command\n#{pdftk} #{args.flatten.compact.join ' '}\ncommand output was:\n#{result}\nfailing form data has been saved to #{fdf_path}") end ensure tmp.unlink if tmp end
get field names for template
Initialize the object with utf8_fields: true to get utf8 encoded field names.
# File lib/pdf_forms/pdftk_wrapper.rb, line 81 def get_field_names(template) read(template).fields.map{|f| f.name} end
Get field metadata for template
Initialize the object with utf8_fields: true to get utf8 encoded field metadata.
# File lib/pdf_forms/pdftk_wrapper.rb, line 73 def get_fields(template) read(template).fields end
applies each page of the stamp PDF to the corresponding page of the input PDF args: primary_file, stamp_file, output
# File lib/pdf_forms/pdftk_wrapper.rb, line 124 def multistamp(primary_file, stamp_file, output) call_pdftk primary_file, 'multistamp', stamp_file, 'output', output end
pdftk.read '/path/to/form.pdf' returns an instance of PdfForms::Pdf
representing the given template
# File lib/pdf_forms/pdftk_wrapper.rb, line 65 def read(path) Pdf.new path, self, options end
stamp one pdf with another
args: primary_file, stamp_file, output
# File lib/pdf_forms/pdftk_wrapper.rb, line 118 def stamp(primary_file, stamp_file, output) call_pdftk primary_file, 'stamp', stamp_file, 'output', output end
Private Instance Methods
# File lib/pdf_forms/pdftk_wrapper.rb, line 146 def append_options(args, local_options = {}) return args if options.empty? && local_options.empty? args = args.dup ALLOWED_OPTIONS.each do |option| if option_or_global(option, local_options) args << option.to_s end end if option_or_global(:encrypt, local_options) encrypt_pass = option_or_global(:encrypt_password, local_options) encrypt_pass ||= SecureRandom.urlsafe_base64 encrypt_options = option_or_global(:encrypt_options, local_options) encrypt_options = encrypt_options.split if String === encrypt_options args << ['encrypt_128bit', 'owner_pw', encrypt_pass, encrypt_options] end args.flatten! args.compact! args end
# File lib/pdf_forms/pdftk_wrapper.rb, line 130 def data_format(data) data_format = options[:data_format] || 'Fdf' PdfForms.const_get(data_format).new(data) end
# File lib/pdf_forms/pdftk_wrapper.rb, line 166 def normalize_args(*args) args = args.dup pdftk = PDFTK options = {} if first_arg = args.shift case first_arg when String pdftk = first_arg options = args.shift || {} raise ArgumentError.new("expected hash, got #{options.class.name}") unless Hash === options when Hash options = first_arg else raise ArgumentError.new("expected string or hash, got #{first_arg.class.name}") end end [pdftk, options] end
# File lib/pdf_forms/pdftk_wrapper.rb, line 135 def option_or_global(attrib, local = {}) local[attrib] || options[attrib] end