Class: FillablePDFTH

Inherits:
Object
  • Object
show all
Defined in:
lib/fillable-pdf-th.rb,
lib/fillable-pdf-th/version.rb

Constant Summary collapse

BYTE_STREAM =

required Java imports

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'
PDF_FONT_ENCODE =
Rjb.import 'com.itextpdf.io.font.PdfEncodings'
PDF_FONT =
Rjb.import 'com.itextpdf.kernel.font.PdfFont'
PDF_FONT_FACTORY =
Rjb.import 'com.itextpdf.kernel.font.PdfFontFactory'
FONT =
File.join(File.dirname(__FILE__), "default-font/angsana_new.ttf")
VERSION =
'1.0.5.1'

Instance Method Summary collapse

Constructor Details

#initialize(file_path) ⇒ FillablePDFTH

Opens a given fillable-pdf PDF file and prepares it for modification.

@param [String|Symbol] file_path the name of the PDF file or file path

Raises:

  • (IOError)


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/fillable-pdf-th.rb', line 22

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_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)
  @size = 12.00
  set_font
  @form_fields = @pdf_form.getFormFields
  
  @checkbox_style = {
    'check' => PDF_FORM_FIELD.TYPE_CHECK,
    'circle' => PDF_FORM_FIELD.TYPE_CIRCLE,
    'cross' => PDF_FORM_FIELD.TYPE_CROSS,
    'diamond' => PDF_FORM_FIELD.TYPE_DIAMOND,
    'square' => PDF_FORM_FIELD.TYPE_SQUARE,
    'star' => PDF_FORM_FIELD.TYPE_STAR
  }
  set_checkbox_style
end

Instance Method Details

#any_fields?Boolean

Determines whether the form has any fields.

@return true if form has fields, false otherwise

Returns:

  • (Boolean)


90
91
92
# File 'lib/fillable-pdf-th.rb', line 90

def any_fields?
  num_fields.positive?
end

#field(key) ⇒ Object

Retrieves the value of a field given its unique field name.

@param [String|Symbol] key the field name

@return the value of the field


110
111
112
113
114
# File 'lib/fillable-pdf-th.rb', line 110

def field(key)
  pdf_field(key).getValueAsString
rescue NoMethodError
  raise "unknown key name `#{key}'"
end

#field_type(key) ⇒ Object

Retrieves the numeric type of a field given its unique field name.

@param [String|Symbol] key the field name

@return the type of the field


123
124
125
# File 'lib/fillable-pdf-th.rb', line 123

def field_type(key)
  pdf_field(key).getFormType.toString
end

#fieldsObject

Retrieves a hash of all fields and their values.

@return the hash of field keys and values


132
133
134
135
136
137
138
139
140
# File 'lib/fillable-pdf-th.rb', line 132

def fields
  iterator = @form_fields.keySet.iterator
  map = {}
  while iterator.hasNext
    key = iterator.next.toString
    map[key.to_sym] = field(key)
  end
  map
end

#get_dimention(key) ⇒ Object

get dimention form field



61
62
63
64
65
66
# File 'lib/fillable-pdf-th.rb', line 61

def get_dimention(key)
  position = pdf_field(key).getWidgets().get(0).getRectangle()
  width =  position.getAsNumber(2).getValue() - position.getAsNumber(0).getValue();
  height = position.getAsNumber(3).getValue() - position.getAsNumber(1).getValue();
  return width, height
end

#get_position(key) ⇒ Object

get position field



48
49
50
51
52
53
54
55
56
# File 'lib/fillable-pdf-th.rb', line 48

def get_position(key)
  rectangle = pdf_field(key).getWidgets().get(0).getRectangle()
  position = []
  position << rectangle.getAsNumber(0).getValue() 
  position << rectangle.getAsNumber(1).getValue()
  position << rectangle.getAsNumber(2).getValue() 
  position << rectangle.getAsNumber(3).getValue()
  position
end

#namesObject

Returns a list of all field keys used in the document.

@return array of field names


185
186
187
188
189
190
# File 'lib/fillable-pdf-th.rb', line 185

def names
  iterator = @form_fields.keySet.iterator
  set = []
  set << iterator.next.toString.to_sym while iterator.hasNext
  set
end

#num_fieldsObject

Returns the total number of form fields.

@return the number of fields


99
100
101
# File 'lib/fillable-pdf-th.rb', line 99

def num_fields
  @form_fields.size
end

#remove_field(key) ⇒ Object

Removes a field from the document given its unique field name.

@param [String|Symbol] key the field name


176
177
178
# File 'lib/fillable-pdf-th.rb', line 176

def remove_field(key)
  @pdf_form.removeField(key.to_s)
end

#rename_field(old_key, new_key) ⇒ Object

Renames a field given its unique field name and the new field name.

@param [String|Symbol] old_key the field name
@param [String|Symbol] new_key the field name


167
168
169
# File 'lib/fillable-pdf-th.rb', line 167

def rename_field(old_key, new_key)
  pdf_field(old_key).setFieldName(new_key.to_s)
end

#save(flatten: false) ⇒ Object

Overwrites the previously opened PDF file and flattens it if requested.

@param [bool] flatten true if PDF should be flattened, false otherwise


209
210
211
212
213
# File 'lib/fillable-pdf-th.rb', line 209

def save(flatten: false)
  tmp_file = SecureRandom.uuid
  save_as(tmp_file, flatten: flatten)
  File.rename tmp_file, @file_path
end

#save_as(file_path, flatten: false) ⇒ Object

Saves the filled out PDF file with a given file and flattens it if requested.

@param [String] file_path the name of the PDF file or file path
@param [Hash] flatten: true if PDF should be flattened, false otherwise


221
222
223
# File 'lib/fillable-pdf-th.rb', line 221

def save_as(file_path, flatten: false)
  File.open(file_path, 'wb') { |f| f.write(finalize(flatten: flatten)) && f.close }
end

#set_checkbox_style(mark_style = 'check') ⇒ Object



76
77
78
79
80
# File 'lib/fillable-pdf-th.rb', line 76

def set_checkbox_style(mark_style='check')
  fields.each do |key, value|
    pdf_field(key).setCheckType(@checkbox_style[mark_style] || @checkbox_style['check'] ) if field_type(key).eql?('/Btn')
  end
end

#set_field(key, value) ⇒ Object

Sets the value of a field given its unique field name and value.

@param [String|Symbol] key the field name
@param [String|Symbol] value the field value


148
149
150
# File 'lib/fillable-pdf-th.rb', line 148

def set_field(key, value)
  pdf_field(key).setValue(value.to_s, @pdf_font, @size)
end

#set_fields(fields) ⇒ Object

Sets the values of multiple fields given a set of unique field names and values.

@param [Hash] fields the set of field names and values


157
158
159
# File 'lib/fillable-pdf-th.rb', line 157

def set_fields(fields)
  fields.each { |key, value| set_field key, value }
end

#set_font(font_path = FONT, embeded = false, cache = false, subset = false) ⇒ Object

Set font in PDF file



71
72
73
74
# File 'lib/fillable-pdf-th.rb', line 71

def set_font(font_path=FONT, embeded=false, cache=false, subset=false)
  @pdf_font = PDF_FONT_FACTORY.createFont(font_path, PDF_FONT_ENCODE.IDENTITY_H, embeded, cache)
  @pdf_font.setSubset(subset)
end

#set_size(size = @size) ⇒ Object



82
83
84
# File 'lib/fillable-pdf-th.rb', line 82

def set_size(size=@size)
  @size = size.to_f
end

#valuesObject

Returns a list of all field values used in the document.

@return array of field values


197
198
199
200
201
202
# File 'lib/fillable-pdf-th.rb', line 197

def values
  iterator = @form_fields.keySet.iterator
  set = []
  set << field(iterator.next.toString) while iterator.hasNext
  set
end