fillable-pdf 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -4
- data/README.md +118 -85
- data/ext/font-asian-7.1.9.jar +0 -0
- data/lib/field.rb +7 -2
- data/lib/fillable-pdf.rb +29 -11
- data/lib/fillable-pdf/version.rb +1 -1
- data/lib/kernel.rb +9 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5ab7087bc8f229f961c0da0082be323be426d8ec7ab4b2393f40bc802f4d43a
|
4
|
+
data.tar.gz: bb1470fd017ec78765c4fe4885ab946bd94167e01c28b7768d0fcca7e490729a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0058f8ca36432a67568682669156536accd1da68bf345617289ac0b1defab458f6f47ab69ebc08ea872d60ad5573e8fab743904e8bbb71620eff25c4511a727a'
|
7
|
+
data.tar.gz: b77167e17b342c26e3e0003ab468016947e06567f042aef227175bfa368dc062728803347fc75565a81c871fde4a2a0807d1f3bf35e28a773477ea26022a893b
|
data/.rubocop.yml
CHANGED
@@ -8,14 +8,14 @@ AllCops:
|
|
8
8
|
Layout/EmptyLineAfterGuardClause:
|
9
9
|
Enabled: false
|
10
10
|
|
11
|
-
Layout/
|
12
|
-
Enabled: false
|
13
|
-
|
14
|
-
Metrics/LineLength:
|
11
|
+
Layout/LineLength:
|
15
12
|
Exclude:
|
16
13
|
- fillable-pdf.gemspec
|
17
14
|
Max: 120
|
18
15
|
|
16
|
+
Layout/SpaceInsideHashLiteralBraces:
|
17
|
+
Enabled: false
|
18
|
+
|
19
19
|
Naming/AccessorMethodName:
|
20
20
|
Enabled: false
|
21
21
|
|
data/README.md
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
|
1
2
|
# FillablePDF
|
2
3
|
|
3
4
|
[](https://rubygems.org/gems/fillable-pdf)
|
@@ -38,97 +39,126 @@ First of all, you should open a fillable PDF file:
|
|
38
39
|
pdf = FillablePDF.new 'input.pdf'
|
39
40
|
```
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
```ruby
|
44
|
-
fillable-pdf
|
45
|
-
# output example: true
|
46
|
-
pdf.any_fields?
|
47
|
-
```
|
48
|
-
|
49
|
-
```ruby
|
50
|
-
# get the total number of fillable form fields
|
51
|
-
# output example: 10
|
52
|
-
pdf.num_fields
|
53
|
-
```
|
54
|
-
|
55
|
-
```ruby
|
56
|
-
# retrieve a single field value by field name
|
57
|
-
# output example: 'Richard'
|
58
|
-
pdf.field(:full_name)
|
59
|
-
```
|
60
|
-
|
61
|
-
```ruby
|
62
|
-
# retrieve a field type by field name
|
63
|
-
# numeric types should
|
64
|
-
# output example: 4
|
65
|
-
pdf.field_type(:football)
|
66
|
-
|
67
|
-
# list of all field types
|
68
|
-
Field::BUTTON
|
69
|
-
Field::CHOICE
|
70
|
-
Field::SIGNATURE
|
71
|
-
Field::TEXT
|
72
|
-
```
|
73
|
-
|
74
|
-
```ruby
|
75
|
-
# retrieve a hash of field name and values
|
76
|
-
# output example: {:last_name=>"Rahl", :first_name=>"Richard"}
|
77
|
-
pdf.fields
|
78
|
-
```
|
79
|
-
|
80
|
-
```ruby
|
81
|
-
# set the value of a single field by field name
|
82
|
-
# result: changes the value of 'first_name' to 'Richard'
|
83
|
-
pdf.set_field(:first_name, 'Richard')
|
84
|
-
```
|
85
|
-
|
86
|
-
```ruby
|
87
|
-
# set the values of multiple fields by field names
|
88
|
-
# result: changes the values of 'first_name' and 'last_name'
|
89
|
-
pdf.set_fields(first_name: 'Richard', last_name: 'Rahl')
|
90
|
-
```
|
91
|
-
|
92
|
-
```ruby
|
93
|
-
# rename field (i.e. change the name of the field)
|
94
|
-
# result: renames field name 'last_name' to 'surname'
|
95
|
-
# NOTE: this action does not take effect until the document is saved
|
96
|
-
pdf.rename_field(:last_name, :surname)
|
97
|
-
```
|
42
|
+
> **Always remember to close your document once you're finished working with it in order to avoid memory leaks:**
|
98
43
|
|
99
44
|
```ruby
|
100
|
-
|
101
|
-
# result: physically removes field 'last_name' from document
|
102
|
-
pdf.remove_field(:last_name)
|
45
|
+
pdf.close
|
103
46
|
```
|
104
47
|
|
105
|
-
|
106
|
-
# get an array of all field names in the document
|
107
|
-
# output example: [:first_name, :last_name]
|
108
|
-
pdf.names
|
109
|
-
```
|
110
|
-
|
111
|
-
```ruby
|
112
|
-
# get an array of all field values in the document
|
113
|
-
# output example: ["Rahl", "Richard"]
|
114
|
-
pdf.values
|
115
|
-
```
|
48
|
+
## Instance Methods
|
116
49
|
|
117
|
-
|
118
|
-
|
119
|
-
```ruby
|
120
|
-
pdf.save
|
121
|
-
pdf.save_as('output.pdf')
|
122
|
-
```
|
123
|
-
|
124
|
-
Or if you prefer to flatten the file (i.e. make it non-editable), you can instead use:
|
125
|
-
|
126
|
-
```ruby
|
127
|
-
pdf.save(flatten: true)
|
128
|
-
pdf.save_as('output.pdf', flatten: true)
|
129
|
-
```
|
50
|
+
An instance of `FillablePDF` has the following methods at its disposal:
|
130
51
|
|
131
|
-
|
52
|
+
* `any_fields?`
|
53
|
+
*Determines whether the form has any fields.*
|
54
|
+
```ruby
|
55
|
+
pdf.any_fields?
|
56
|
+
# output example: true
|
57
|
+
```
|
58
|
+
|
59
|
+
* `num_fields`
|
60
|
+
*Returns the total number of fillable form fields.*
|
61
|
+
```ruby
|
62
|
+
# output example: 10
|
63
|
+
pdf.num_fields
|
64
|
+
```
|
65
|
+
|
66
|
+
* `field`
|
67
|
+
*Retrieves the value of a field given its unique field name.*
|
68
|
+
```ruby
|
69
|
+
pdf.field(:full_name)
|
70
|
+
# output example: 'Richard'
|
71
|
+
```
|
72
|
+
|
73
|
+
* `field_type`
|
74
|
+
*Retrieves the numeric type of a field given its unique field name.*
|
75
|
+
```ruby
|
76
|
+
pdf.field_type(:football)
|
77
|
+
# output example: 4
|
78
|
+
|
79
|
+
# list of all field types
|
80
|
+
Field::BUTTON
|
81
|
+
Field::CHOICE
|
82
|
+
Field::SIGNATURE
|
83
|
+
Field::TEXT
|
84
|
+
```
|
85
|
+
|
86
|
+
* `fields`
|
87
|
+
*Retrieves a hash of all fields and their values.*
|
88
|
+
```ruby
|
89
|
+
pdf.fields
|
90
|
+
# output example: {first_name: "Richard", last_name: "Rahl"}
|
91
|
+
```
|
92
|
+
|
93
|
+
* `set_field`
|
94
|
+
*Sets the value of a field given its unique field name and value.*
|
95
|
+
```ruby
|
96
|
+
pdf.set_field(:first_name, 'Richard')
|
97
|
+
# result: changes the value of 'first_name' to 'Richard'
|
98
|
+
```
|
99
|
+
|
100
|
+
* `set_fields`
|
101
|
+
*Sets the values of multiple fields given a set of unique field names and values.*
|
102
|
+
```ruby
|
103
|
+
pdf.set_fields(first_name: 'Richard', last_name: 'Rahl')
|
104
|
+
# result: changes the values of 'first_name' and 'last_name'
|
105
|
+
```
|
106
|
+
|
107
|
+
* `rename_field`
|
108
|
+
*Renames a field given its unique field name and the new field name.*
|
109
|
+
```ruby
|
110
|
+
pdf.rename_field(:last_name, :surname)
|
111
|
+
# result: renames field name 'last_name' to 'surname'
|
112
|
+
# NOTE: this action does not take effect until the document is saved
|
113
|
+
```
|
114
|
+
|
115
|
+
* `remove_field`
|
116
|
+
*Removes a field from the document given its unique field name.*
|
117
|
+
```ruby
|
118
|
+
pdf.remove_field(:last_name)
|
119
|
+
# result: physically removes field 'last_name' from document
|
120
|
+
```
|
121
|
+
|
122
|
+
* `names`
|
123
|
+
*Returns a list of all field keys used in the document.*
|
124
|
+
```ruby
|
125
|
+
pdf.names
|
126
|
+
# output example: [:first_name, :last_name]
|
127
|
+
```
|
128
|
+
|
129
|
+
* `values`
|
130
|
+
*Returns a list of all field values used in the document.*
|
131
|
+
```ruby
|
132
|
+
pdf.values
|
133
|
+
# output example: ["Rahl", "Richard"]
|
134
|
+
```
|
135
|
+
|
136
|
+
* `save`
|
137
|
+
*Overwrites the previously opened PDF document and flattens it if requested.*
|
138
|
+
```ruby
|
139
|
+
pdf.save
|
140
|
+
# result: document is saved without flatenning
|
141
|
+
pdf.save_as(flatten: true)
|
142
|
+
# result: document is saved with flatenning
|
143
|
+
```
|
144
|
+
|
145
|
+
* `save_as`
|
146
|
+
*Saves the filled out PDF document in a given path and flattens it if requested.*
|
147
|
+
```ruby
|
148
|
+
pdf.save_as('output.pdf')
|
149
|
+
# result: document is saved in a given path without flatenning
|
150
|
+
pdf.save_as('output.pdf', flatten: true)
|
151
|
+
# result: document is saved in a given path with flatenning
|
152
|
+
```
|
153
|
+
|
154
|
+
**NOTE:** Saving the file automatically closes the input file, so you would need to reinitialize the `FillabePDF` class before making any more changes or saving another copy.
|
155
|
+
|
156
|
+
* `close`
|
157
|
+
*Closes the PDF document discarding all unsaved changes.*
|
158
|
+
```ruby
|
159
|
+
pdf.close
|
160
|
+
# result: document is closed
|
161
|
+
```
|
132
162
|
|
133
163
|
## Example
|
134
164
|
|
@@ -199,6 +229,9 @@ pdf.save_as('output.pdf')
|
|
199
229
|
# saving another copy of the filled out PDF in another file and making it non-editable
|
200
230
|
pdf = FillablePDF.new('output.pdf')
|
201
231
|
pdf.save_as 'output.flat.pdf', flatten: true
|
232
|
+
|
233
|
+
# closing the document
|
234
|
+
pdf.close
|
202
235
|
```
|
203
236
|
|
204
237
|
The example above produces the following output and also generates the output file [output.pdf](example/output.pdf).
|
Binary file
|
data/lib/field.rb
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
require_relative 'fillable-pdf/itext'
|
2
|
+
require_relative 'kernel'
|
2
3
|
|
3
4
|
class Field
|
4
|
-
|
5
|
+
# PdfName has a constant "A" and a constant "a". Unfortunately, RJB does not differentiate
|
6
|
+
# between these constants and tries to create the same constant ("A") for both, which causes
|
7
|
+
# an annoying warning "already initialized constant Rjb::Com_itextpdf_kernel_pdf_PdfName::A".
|
8
|
+
# As long as RJB has not fixed this issue, this warning will remain suppressed.
|
9
|
+
suppress_warnings { PDF_NAME = Rjb.import('com.itextpdf.kernel.pdf.PdfName') }
|
5
10
|
|
6
11
|
BUTTON = PDF_NAME.Btn.toString
|
7
12
|
CHOICE = PDF_NAME.Ch.toString
|
8
13
|
SIGNATURE = PDF_NAME.Sig.toString
|
9
14
|
TEXT = PDF_NAME.Tx.toString
|
10
|
-
end
|
15
|
+
end
|
data/lib/fillable-pdf.rb
CHANGED
@@ -19,12 +19,16 @@ class FillablePDF
|
|
19
19
|
def initialize(file_path)
|
20
20
|
raise IOError, "File at `#{file_path}' is not found" unless File.exist?(file_path)
|
21
21
|
@file_path = file_path
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
begin
|
23
|
+
@byte_stream = BYTE_STREAM.new
|
24
|
+
@pdf_reader = PDF_READER.new @file_path
|
25
|
+
@pdf_writer = PDF_WRITER.new @byte_stream
|
26
|
+
@pdf_doc = PDF_DOCUMENT.new @pdf_reader, @pdf_writer
|
27
|
+
@pdf_form = PDF_ACRO_FORM.getAcroForm(@pdf_doc, true)
|
28
|
+
@form_fields = @pdf_form.getFormFields
|
29
|
+
rescue StandardError => ex
|
30
|
+
raise "#{ex.message} (input file may be corrupt, incompatible, or may not have any forms)"
|
31
|
+
end
|
28
32
|
end
|
29
33
|
|
30
34
|
##
|
@@ -37,7 +41,7 @@ class FillablePDF
|
|
37
41
|
end
|
38
42
|
|
39
43
|
##
|
40
|
-
# Returns the total number of form fields.
|
44
|
+
# Returns the total number of fillable form fields.
|
41
45
|
#
|
42
46
|
# @return the number of fields
|
43
47
|
#
|
@@ -147,7 +151,7 @@ class FillablePDF
|
|
147
151
|
end
|
148
152
|
|
149
153
|
##
|
150
|
-
# Overwrites the previously opened PDF
|
154
|
+
# Overwrites the previously opened PDF document and flattens it if requested.
|
151
155
|
#
|
152
156
|
# @param [bool] flatten true if PDF should be flattened, false otherwise
|
153
157
|
#
|
@@ -158,13 +162,27 @@ class FillablePDF
|
|
158
162
|
end
|
159
163
|
|
160
164
|
##
|
161
|
-
# Saves the filled out PDF
|
165
|
+
# Saves the filled out PDF document in a given path and flattens it if requested.
|
162
166
|
#
|
163
167
|
# @param [String] file_path the name of the PDF file or file path
|
164
168
|
# @param [Hash] flatten: true if PDF should be flattened, false otherwise
|
165
169
|
#
|
166
170
|
def save_as(file_path, flatten: false)
|
167
|
-
|
171
|
+
if @file_path == file_path
|
172
|
+
save(flatten: flatten)
|
173
|
+
else
|
174
|
+
File.open(file_path, 'wb') { |f| f.write(finalize(flatten: flatten)) && f.close }
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
##
|
179
|
+
# Closes the PDF document discarding all unsaved changes.
|
180
|
+
#
|
181
|
+
# @return [Boolean] true if document is closed, false otherwise
|
182
|
+
#
|
183
|
+
def close
|
184
|
+
@pdf_doc.close
|
185
|
+
@pdf_doc.isClosed
|
168
186
|
end
|
169
187
|
|
170
188
|
private
|
@@ -176,7 +194,7 @@ class FillablePDF
|
|
176
194
|
#
|
177
195
|
def finalize(flatten: false)
|
178
196
|
@pdf_form.flattenFields if flatten
|
179
|
-
|
197
|
+
close
|
180
198
|
@byte_stream.toByteArray
|
181
199
|
end
|
182
200
|
|
data/lib/fillable-pdf/version.rb
CHANGED
data/lib/kernel.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fillable-pdf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vadim Kononov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -84,6 +84,7 @@ files:
|
|
84
84
|
- Rakefile
|
85
85
|
- bin/console
|
86
86
|
- bin/setup
|
87
|
+
- ext/font-asian-7.1.9.jar
|
87
88
|
- ext/forms-7.1.9.jar
|
88
89
|
- ext/io-7.1.9.jar
|
89
90
|
- ext/kernel-7.1.9.jar
|
@@ -95,6 +96,7 @@ files:
|
|
95
96
|
- lib/fillable-pdf.rb
|
96
97
|
- lib/fillable-pdf/itext.rb
|
97
98
|
- lib/fillable-pdf/version.rb
|
99
|
+
- lib/kernel.rb
|
98
100
|
homepage: https://github.com/vkononov/fillable-pdf
|
99
101
|
licenses:
|
100
102
|
- MIT
|
@@ -115,7 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
117
|
- !ruby/object:Gem::Version
|
116
118
|
version: '0'
|
117
119
|
requirements: []
|
118
|
-
rubygems_version: 3.
|
120
|
+
rubygems_version: 3.1.2
|
119
121
|
signing_key:
|
120
122
|
specification_version: 4
|
121
123
|
summary: Fill out or extract field values from simple fillable PDF forms using iText.
|