lib/fillable-pdf.rb in fillable-pdf-0.6 vs lib/fillable-pdf.rb in fillable-pdf-0.7
- old
+ new
@@ -2,89 +2,98 @@
require_relative 'field'
require 'securerandom'
class FillablePDF
# required Java imports
- BYTE_STREAM = Rjb.import('java.io.ByteArrayOutputStream')
- FILE_READER = Rjb.import('com.itextpdf.text.pdf.PdfReader')
- PDF_STAMPER = Rjb.import('com.itextpdf.text.pdf.PdfStamper')
+ BYTE_STREAM = Rjb.import 'com.itextpdf.io.source.ByteArrayOutputStream'
+ PDF_READER = Rjb.import 'com.itextpdf.kernel.pdf.PdfReader'
+ PDF_WRITER = Rjb.import 'com.itextpdf.kernel.pdf.PdfWriter'
+ PDF_DOCUMENT = Rjb.import 'com.itextpdf.kernel.pdf.PdfDocument'
+ PDF_ACRO_FORM = Rjb.import 'com.itextpdf.forms.PdfAcroForm'
+ PDF_FORM_FIELD = Rjb.import 'com.itextpdf.forms.fields.PdfFormField'
##
- # Opens a given fillable PDF file and prepares it for modification.
+ # Opens a given fillable-pdf PDF file and prepares it for modification.
#
- # @param [String] file the name of the PDF file or file path
+ # @param [String|Symbol] file_path the name of the PDF file or file path
#
- def initialize(file)
- @file = file
+ def initialize(file_path)
+ raise IOError, "File at `#{file_path}' is not found" unless File.exist?(file_path)
+ @file_path = file_path
@byte_stream = BYTE_STREAM.new
- @pdf_stamper = PDF_STAMPER.new FILE_READER.new(@file), @byte_stream
- @acro_fields = @pdf_stamper.getAcroFields
+ @pdf_reader = PDF_READER.new @file_path
+ @pdf_writer = PDF_WRITER.new @byte_stream
+ @pdf_doc = PDF_DOCUMENT.new @pdf_reader, @pdf_writer
+ @pdf_form = PDF_ACRO_FORM.getAcroForm(@pdf_doc, true)
+ @form_fields = @pdf_form.getFormFields
end
##
# Determines whether the form has any fields.
#
# @return true if form has fields, false otherwise
#
def any_fields?
- num_fields > 0
+ num_fields.positive?
end
##
# Returns the total number of form fields.
#
# @return the number of fields
#
def num_fields
- @acro_fields.getFields.size
+ @form_fields.size
end
##
# Retrieves the value of a field given its unique field name.
#
- # @param [String] key the field name
+ # @param [String|Symbol] key the field name
#
# @return the value of the field
#
- def get_field(key)
- @acro_fields.getField key.to_s
+ def field(key)
+ pdf_field(key).getValueAsString
+ rescue NoMethodError
+ raise "unknown key name `#{key}'"
end
##
# Retrieves the numeric type of a field given its unique field name.
#
- # @param [String] key the field name
+ # @param [String|Symbol] key the field name
#
# @return the type of the field
#
- def get_field_type(key)
- @acro_fields.getFieldType key.to_s
+ def field_type(key)
+ pdf_field(key).getFormType.toString
end
##
# Retrieves a hash of all fields and their values.
#
# @return the hash of field keys and values
#
- def get_fields
- iterator = @acro_fields.getFields.keySet.iterator
+ def fields
+ iterator = @form_fields.keySet.iterator
map = {}
while iterator.hasNext
key = iterator.next.toString
- map[key.to_sym] = get_field key
+ map[key.to_sym] = field(key)
end
map
end
##
# Sets the value of a field given its unique field name and value.
#
- # @param [String] key the field name
- # @param [String] value the field value
+ # @param [String|Symbol] key the field name
+ # @param [String|Symbol] value the field value
#
def set_field(key, value)
- @acro_fields.setField key.to_s, value.to_s
+ pdf_field(key).setValue(value.to_s)
end
##
# Sets the values of multiple fields given a set of unique field names and values.
#
@@ -95,33 +104,33 @@
end
##
# Renames a field given its unique field name and the new field name.
#
- # @param [String] old_key the field name
- # @param [String] new_key the field name
+ # @param [String|Symbol] old_key the field name
+ # @param [String|Symbol] new_key the field name
#
def rename_field(old_key, new_key)
- @acro_fields.renameField old_key.to_s, new_key.to_s
+ pdf_field(old_key).setFieldName(new_key.to_s)
end
##
# Removes a field from the document given its unique field name.
#
- # @param [String] key the field name
+ # @param [String|Symbol] key the field name
#
def remove_field(key)
- @acro_fields.removeField key.to_s
+ @pdf_form.removeField(key.to_s)
end
##
# Returns a list of all field keys used in the document.
#
# @return array of field names
#
- def keys
- iterator = @acro_fields.getFields.keySet.iterator
+ def names
+ iterator = @form_fields.keySet.iterator
set = []
set << iterator.next.toString.to_sym while iterator.hasNext
set
end
@@ -129,45 +138,51 @@
# Returns a list of all field values used in the document.
#
# @return array of field values
#
def values
- iterator = @acro_fields.getFields.keySet.iterator
+ iterator = @form_fields.keySet.iterator
set = []
- set << get_field(iterator.next.toString) while iterator.hasNext
+ set << field(iterator.next.toString) while iterator.hasNext
set
end
##
# Overwrites the previously opened PDF file and flattens it if requested.
#
# @param [bool] flatten true if PDF should be flattened, false otherwise
#
- def save(flatten = false)
+ def save(flatten: false)
tmp_file = SecureRandom.uuid
- save_as(tmp_file, flatten)
- File.rename tmp_file, @file
+ save_as(tmp_file, flatten: flatten)
+ File.rename tmp_file, @file_path
end
##
# Saves the filled out PDF file with a given file and flattens it if requested.
#
- # @param [String] file the name of the PDF file or file path
- # @param [bool] flatten true if PDF should be flattened, false otherwise
+ # @param [String] file_path the name of the PDF file or file path
+ # @param [Hash] flatten: true if PDF should be flattened, false otherwise
#
- def save_as(file, flatten = false)
- File.open(file, 'wb') { |f| f.write(finalize(flatten)) && f.close }
+ def save_as(file_path, flatten: false)
+ File.open(file_path, 'wb') { |f| f.write(finalize(flatten: flatten)) && f.close }
end
private
##
# Writes the contents of the modified fields to the previously opened PDF file.
#
- # @param [bool] flatten true if PDF should be flattened, false otherwise
+ # @param [Hash] flatten: true if PDF should be flattened, false otherwise
#
- def finalize(flatten)
- @pdf_stamper.setFormFlattening flatten
- @pdf_stamper.close
+ def finalize(flatten: false)
+ @pdf_form.flattenFields if flatten
+ @pdf_doc.close
@byte_stream.toByteArray
+ end
+
+ def pdf_field(key)
+ field = @form_fields.get(key.to_s)
+ raise "unknown key name `#{key}'" if field.nil?
+ field
end
end