fillable-pdf 0.1.2 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +143 -12
- data/fillable-pdf.gemspec +1 -3
- data/lib/field.rb +14 -0
- data/lib/fillable-pdf.rb +75 -7
- data/lib/fillable-pdf/itext.rb +4 -0
- data/lib/fillable-pdf/version.rb +1 -1
- metadata +5 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c5cc5a9b62b1f5af8cae176bd12b091b4c0b974
|
4
|
+
data.tar.gz: f5e7d046aa370c15f4e830cd09663b07cf8db78d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9eb1596cfc4cd89146237536a0391d1fd59867f5343e3181a6c09d089356c577c5da788417ab38ef8cfbb8b024284cb6732c71719ddb32eb84ba7dd487cd051c
|
7
|
+
data.tar.gz: 75eee8c3150bf8cad77af4908a7d6239f40371468379301cd1cd5568490f27ab23b6fe475dee6dceea6900e551f290158fbf52504e50151ea9c220f20acb659c
|
data/README.md
CHANGED
@@ -22,7 +22,7 @@ Or install it yourself as:
|
|
22
22
|
If you are using this gem in a script, you need to require it manually:
|
23
23
|
|
24
24
|
```ruby
|
25
|
-
require 'fillable-
|
25
|
+
require 'fillable-pdf'
|
26
26
|
```
|
27
27
|
|
28
28
|
## Usage
|
@@ -30,21 +30,67 @@ require 'fillable-xml'
|
|
30
30
|
First of all, you should open a fillable PDF file:
|
31
31
|
|
32
32
|
```ruby
|
33
|
-
pdf = FillablePDF.new
|
33
|
+
pdf = FillablePDF.new 'input.pdf'
|
34
34
|
```
|
35
35
|
|
36
36
|
An instance of `FillablePDF` has the following methods at its disposal:
|
37
37
|
|
38
38
|
```ruby
|
39
|
-
|
40
|
-
|
41
|
-
pdf.
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
pdf.
|
46
|
-
|
47
|
-
|
39
|
+
# return true if the form has any fillable fields
|
40
|
+
# output example: true
|
41
|
+
pdf.any_fields?
|
42
|
+
|
43
|
+
# get the total number of fillable form fields
|
44
|
+
# output example: 10
|
45
|
+
pdf.num_fields
|
46
|
+
|
47
|
+
# retrieve a single field value by field name
|
48
|
+
# output example: 'Richard'
|
49
|
+
pdf.get_field(:full_name)
|
50
|
+
|
51
|
+
# retrieve a numeric field type by field value
|
52
|
+
# numeric types should
|
53
|
+
# output example: 4
|
54
|
+
pdf.get_field_type(:football)
|
55
|
+
|
56
|
+
# list of all field types
|
57
|
+
Field::CHECKBOX
|
58
|
+
Field::COMBO
|
59
|
+
Field::LIST
|
60
|
+
Field::NONE
|
61
|
+
Field::PUSHBUTTON
|
62
|
+
Field::RADIOBUTTON
|
63
|
+
Field::SIGNATURE
|
64
|
+
Field::TEXT
|
65
|
+
|
66
|
+
# retrieve a hash of field name and values
|
67
|
+
# output example: {:last_name=>"Rahl", :first_name=>"Richard"}
|
68
|
+
pdf.get_fields
|
69
|
+
|
70
|
+
# set the value of a single field by field name
|
71
|
+
# result: changes the value of 'first_name' to 'Richard'
|
72
|
+
pdf.set_field(:first_name, 'Richard')
|
73
|
+
|
74
|
+
# set the values of multiple fields by field names
|
75
|
+
# result: changes the values of 'first_name' and 'last_name'
|
76
|
+
pdf.set_fields(first_name: 'Richard', last_name: 'Rahl')
|
77
|
+
|
78
|
+
# rename field (i.e. change the name of the field)
|
79
|
+
# this action also moves the field to the end of the hash
|
80
|
+
# result: renames field name 'last_name' to 'surname'
|
81
|
+
pdf.rename_field(:last_name, :surname)
|
82
|
+
|
83
|
+
# remove field (i.e. delete field and its value)
|
84
|
+
# result: physically removes field 'last_name' from document
|
85
|
+
pdf.remove_field(:last_name)
|
86
|
+
|
87
|
+
# get an array of all field names in the document
|
88
|
+
# output example: [:first_name, :last_name]
|
89
|
+
pdf.keys
|
90
|
+
|
91
|
+
# get an array of all field values in the document
|
92
|
+
# output example: ["Rahl", "Richard"]
|
93
|
+
pdf.values
|
48
94
|
```
|
49
95
|
|
50
96
|
Once the PDF is filled out you can either overwrite it or save it as another file:
|
@@ -66,7 +112,92 @@ pdf.save_as('output.pdf', true)
|
|
66
112
|
|
67
113
|
## Example
|
68
114
|
|
69
|
-
|
115
|
+
The following example [test.rb](test/test.rb) and the input file [input.pdf](test/input.pdf) are located in the `test` directory. It uses all of the methods that are described above and generates the output file [output.pdf](test/output.pdf).
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
# opening a fillable PDF
|
119
|
+
pdf = FillablePDF.new('input.pdf')
|
120
|
+
|
121
|
+
# total number of fields
|
122
|
+
if pdf.any_fields?
|
123
|
+
puts "The form has a total of #{pdf.num_fields} fields."
|
124
|
+
else
|
125
|
+
puts 'The form is not fillable.'
|
126
|
+
end
|
127
|
+
|
128
|
+
puts
|
129
|
+
|
130
|
+
# setting form fields
|
131
|
+
pdf.set_fields(first_name: 'Richard', last_name: 'Rahl')
|
132
|
+
pdf.set_fields(football: 'Yes', baseball: 'Yes',
|
133
|
+
basketball: 'Yes', nascar: 'Yes', hockey: 'Yes')
|
134
|
+
pdf.set_field(:date, Time.now.strftime('%B %e, %Y'))
|
135
|
+
|
136
|
+
# list of fields
|
137
|
+
puts "Fields hash: #{pdf.get_fields}"
|
138
|
+
|
139
|
+
puts
|
140
|
+
|
141
|
+
# list of field keys
|
142
|
+
puts "Keys: #{pdf.keys}"
|
143
|
+
|
144
|
+
puts
|
145
|
+
|
146
|
+
# list of field values
|
147
|
+
puts "Values: #{pdf.values}"
|
148
|
+
|
149
|
+
puts
|
150
|
+
|
151
|
+
# Checking field type
|
152
|
+
if pdf.get_field_type(:football) == Field::CHECKBOX
|
153
|
+
puts "Field 'football' is of type CHECKBOX"
|
154
|
+
else
|
155
|
+
puts "Field 'football' is not of type CHECKBOX"
|
156
|
+
end
|
157
|
+
|
158
|
+
puts
|
159
|
+
|
160
|
+
# Renaming field
|
161
|
+
pdf.rename_field :last_name, :surname
|
162
|
+
puts "Renamed field 'last_name' to 'surname'"
|
163
|
+
puts "New keys: #{pdf.keys}"
|
164
|
+
|
165
|
+
puts
|
166
|
+
|
167
|
+
# Removing field
|
168
|
+
pdf.remove_field :nascar
|
169
|
+
puts "Removed field 'nascar'"
|
170
|
+
puts "New keys: #{pdf.keys}"
|
171
|
+
|
172
|
+
puts
|
173
|
+
|
174
|
+
# printing the name of the person used inside the PDF
|
175
|
+
puts "Signatory: #{pdf.get_field(:first_name)} #{pdf.get_field(:last_name)}"
|
176
|
+
|
177
|
+
# saving the filled out PDF in another file and making it non-editable
|
178
|
+
pdf.save_as('output.pdf', true)
|
179
|
+
|
180
|
+
```
|
181
|
+
|
182
|
+
The example above produces the following output and also generates the output file [output.pdf](test/output.pdf).
|
183
|
+
|
184
|
+
The form has a total of 8 fields.
|
185
|
+
|
186
|
+
Fields hash: {:last_name=>"Rahl", :first_name=>"Richard", :football=>"Yes", :baseball=>"Yes", :basketball=>"Yes", :nascar=>"Yes", :hockey=>"Yes", :date=>"July 19, 2017"}
|
187
|
+
|
188
|
+
Keys: [:last_name, :first_name, :football, :baseball, :basketball, :nascar, :hockey, :date]
|
189
|
+
|
190
|
+
Values: ["Rahl", "Richard", "Yes", "Yes", "Yes", "Yes", "Yes", "July 19, 2017"]
|
191
|
+
|
192
|
+
Field 'football' is of type CHECKBOX
|
193
|
+
|
194
|
+
Renamed field 'last_name' to 'surname'
|
195
|
+
New keys: [:first_name, :football, :baseball, :basketball, :nascar, :hockey, :date, :surname]
|
196
|
+
|
197
|
+
Removed field 'nascar'
|
198
|
+
New keys: [:first_name, :football, :baseball, :basketball, :hockey, :date, :surname]
|
199
|
+
|
200
|
+
Signatory: Richard
|
70
201
|
|
71
202
|
|
72
203
|
## Contributing
|
data/fillable-pdf.gemspec
CHANGED
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
|
|
12
12
|
|
13
13
|
spec.summary = 'Fill out or extract field values from simple fillable PDF forms using iText.'
|
14
14
|
spec.description = 'FillablePDF is an extremely simple and lightweight utility that bridges iText and Ruby in order to fill out fillable PDF forms or extract field values from previously filled out PDF forms.'
|
15
|
-
spec.homepage = 'https://
|
15
|
+
spec.homepage = 'https://github.com/vkononov/fillable-pdf'
|
16
16
|
spec.license = 'MIT'
|
17
17
|
|
18
18
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
@@ -20,7 +20,5 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
21
|
spec.require_paths = %w[ext lib]
|
22
22
|
|
23
|
-
spec.add_development_dependency 'bundler', '~> 1.15'
|
24
|
-
spec.add_development_dependency 'rake', '~> 12'
|
25
23
|
spec.add_runtime_dependency 'rjb', '~> 1.5'
|
26
24
|
end
|
data/lib/field.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require_relative 'fillable-pdf/itext'
|
2
|
+
|
3
|
+
class Field
|
4
|
+
ACRO_FIELDS = Rjb.import('com.itextpdf.text.pdf.AcroFields')
|
5
|
+
|
6
|
+
CHECKBOX = ACRO_FIELDS.FIELD_TYPE_CHECKBOX
|
7
|
+
COMBO = ACRO_FIELDS.FIELD_TYPE_COMBO
|
8
|
+
LIST = ACRO_FIELDS.FIELD_TYPE_LIST
|
9
|
+
NONE = ACRO_FIELDS.FIELD_TYPE_NONE
|
10
|
+
PUSHBUTTON = ACRO_FIELDS.FIELD_TYPE_PUSHBUTTON
|
11
|
+
RADIOBUTTON = ACRO_FIELDS.FIELD_TYPE_RADIOBUTTON
|
12
|
+
SIGNATURE = ACRO_FIELDS.FIELD_TYPE_SIGNATURE
|
13
|
+
TEXT = ACRO_FIELDS.FIELD_TYPE_TEXT
|
14
|
+
end
|
data/lib/fillable-pdf.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
-
|
1
|
+
require_relative 'fillable-pdf/itext'
|
2
|
+
require_relative 'field'
|
2
3
|
require 'securerandom'
|
3
4
|
|
4
|
-
# http://github.com/itext/itextpdf/releases/latest
|
5
|
-
Rjb.load(File.expand_path('../ext/itext5-itextpdf-5.5.11.jar', __dir__))
|
6
5
|
|
7
6
|
class FillablePDF
|
8
7
|
# required Java imports
|
@@ -19,7 +18,7 @@ class FillablePDF
|
|
19
18
|
@file = file
|
20
19
|
@byte_stream = BYTE_STREAM.new
|
21
20
|
@pdf_stamper = PDF_STAMPER.new FILE_READER.new(@file), @byte_stream
|
22
|
-
@
|
21
|
+
@acro_fields = @pdf_stamper.getAcroFields
|
23
22
|
end
|
24
23
|
|
25
24
|
##
|
@@ -37,7 +36,7 @@ class FillablePDF
|
|
37
36
|
# @return the number of fields
|
38
37
|
#
|
39
38
|
def num_fields
|
40
|
-
@
|
39
|
+
@acro_fields.getFields.size
|
41
40
|
end
|
42
41
|
|
43
42
|
##
|
@@ -48,7 +47,33 @@ class FillablePDF
|
|
48
47
|
# @return the value of the field
|
49
48
|
#
|
50
49
|
def get_field(key)
|
51
|
-
@
|
50
|
+
@acro_fields.getField key.to_s
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Retrieves the numeric type of a field given its unique field name.
|
55
|
+
#
|
56
|
+
# @param [String] key the field name
|
57
|
+
#
|
58
|
+
# @return the type of the field
|
59
|
+
#
|
60
|
+
def get_field_type(key)
|
61
|
+
@acro_fields.getFieldType key.to_s
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Retrieves a hash of all fields and their values.
|
66
|
+
#
|
67
|
+
# @return the hash of field keys and values
|
68
|
+
#
|
69
|
+
def get_fields
|
70
|
+
iterator = @acro_fields.getFields.keySet.iterator
|
71
|
+
map = {}
|
72
|
+
while iterator.hasNext
|
73
|
+
key = iterator.next.toString
|
74
|
+
map[key.to_sym] = get_field key
|
75
|
+
end
|
76
|
+
map
|
52
77
|
end
|
53
78
|
|
54
79
|
##
|
@@ -58,7 +83,7 @@ class FillablePDF
|
|
58
83
|
# @param [String] value the field value
|
59
84
|
#
|
60
85
|
def set_field(key, value)
|
61
|
-
@
|
86
|
+
@acro_fields.setField key.to_s, value.to_s
|
62
87
|
end
|
63
88
|
|
64
89
|
##
|
@@ -70,6 +95,49 @@ class FillablePDF
|
|
70
95
|
fields.each { |key, value| set_field key, value }
|
71
96
|
end
|
72
97
|
|
98
|
+
##
|
99
|
+
# Renames a field given its unique field name and the new field name.
|
100
|
+
#
|
101
|
+
# @param [String] old_key the field name
|
102
|
+
# @param [String] new_key the field name
|
103
|
+
#
|
104
|
+
def rename_field(old_key, new_key)
|
105
|
+
@acro_fields.renameField old_key.to_s, new_key.to_s
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# Removes a field from the document given its unique field name.
|
110
|
+
#
|
111
|
+
# @param [String] key the field name
|
112
|
+
#
|
113
|
+
def remove_field(key)
|
114
|
+
@acro_fields.removeField key.to_s
|
115
|
+
end
|
116
|
+
|
117
|
+
##
|
118
|
+
# Returns a list of all field keys used in the document.
|
119
|
+
#
|
120
|
+
# @return array of field names
|
121
|
+
#
|
122
|
+
def keys
|
123
|
+
iterator = @acro_fields.getFields.keySet.iterator
|
124
|
+
set = []
|
125
|
+
set << iterator.next.toString.to_sym while iterator.hasNext
|
126
|
+
set
|
127
|
+
end
|
128
|
+
|
129
|
+
##
|
130
|
+
# Returns a list of all field values used in the document.
|
131
|
+
#
|
132
|
+
# @return array of field values
|
133
|
+
#
|
134
|
+
def values
|
135
|
+
iterator = @acro_fields.getFields.keySet.iterator
|
136
|
+
set = []
|
137
|
+
set << get_field(iterator.next.toString) while iterator.hasNext
|
138
|
+
set
|
139
|
+
end
|
140
|
+
|
73
141
|
##
|
74
142
|
# Overwrites the previously opened PDF file and flattens it if requested.
|
75
143
|
#
|
data/lib/fillable-pdf/version.rb
CHANGED
metadata
CHANGED
@@ -1,43 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fillable-pdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.5'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vadim Kononov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-07-
|
11
|
+
date: 2017-07-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: bundler
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.15'
|
20
|
-
type: :development
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - "~>"
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: '1.15'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '12'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '12'
|
41
13
|
- !ruby/object:Gem::Dependency
|
42
14
|
name: rjb
|
43
15
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,9 +42,11 @@ files:
|
|
70
42
|
- bin/setup
|
71
43
|
- ext/itext5-itextpdf-5.5.11.jar
|
72
44
|
- fillable-pdf.gemspec
|
45
|
+
- lib/field.rb
|
73
46
|
- lib/fillable-pdf.rb
|
47
|
+
- lib/fillable-pdf/itext.rb
|
74
48
|
- lib/fillable-pdf/version.rb
|
75
|
-
homepage: https://
|
49
|
+
homepage: https://github.com/vkononov/fillable-pdf
|
76
50
|
licenses:
|
77
51
|
- MIT
|
78
52
|
metadata: {}
|