fillable-pdf 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b7dc484831ca2d2e181d269d0a3edd8e267b13baf970b43edc367274a6cd8629
4
- data.tar.gz: 82a788e368997808f8c08824dbc130a0d95bfc5a1c72e439a83bb474508de82d
3
+ metadata.gz: d5ab7087bc8f229f961c0da0082be323be426d8ec7ab4b2393f40bc802f4d43a
4
+ data.tar.gz: bb1470fd017ec78765c4fe4885ab946bd94167e01c28b7768d0fcca7e490729a
5
5
  SHA512:
6
- metadata.gz: e21037070edbe7b10143798a27a0e312890c45cc82e3fda731df4657bc3b8d6b4f8d87caca17acce484e6c9b6f5e33d1da05fac6b34679c71a3b254d3d344eb5
7
- data.tar.gz: 6814dbe8c682a026fce96ffa8dc99c7f6363983d2b5667a460abab047249b65a9a7f9ad0165298b91bf38b010489e3fbea8460f84e1ca2e7ae595f8858dcd176
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/SpaceInsideHashLiteralBraces:
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
  [![Gem Version](https://badge.fury.io/rb/fillable-pdf.svg)](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
- An instance of `FillablePDF` has the following methods at its disposal:
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
- # remove field (i.e. delete field and its value)
101
- # result: physically removes field 'last_name' from document
102
- pdf.remove_field(:last_name)
45
+ pdf.close
103
46
  ```
104
47
 
105
- ```ruby
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
- Once the PDF is filled out you can either overwrite it or save it as another file:
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
- **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.
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
- PDF_NAME = Rjb.import('com.itextpdf.kernel.pdf.PdfName')
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
- @byte_stream = BYTE_STREAM.new
23
- @pdf_reader = PDF_READER.new @file_path
24
- @pdf_writer = PDF_WRITER.new @byte_stream
25
- @pdf_doc = PDF_DOCUMENT.new @pdf_reader, @pdf_writer
26
- @pdf_form = PDF_ACRO_FORM.getAcroForm(@pdf_doc, true)
27
- @form_fields = @pdf_form.getFormFields
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 file and flattens it if requested.
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 file with a given file and flattens it if requested.
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
- File.open(file_path, 'wb') { |f| f.write(finalize(flatten: flatten)) && f.close }
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
- @pdf_doc.close
197
+ close
180
198
  @byte_stream.toByteArray
181
199
  end
182
200
 
@@ -1,3 +1,3 @@
1
1
  class FillablePDF
2
- VERSION = '0.7.2'
2
+ VERSION = '0.8.0'
3
3
  end
data/lib/kernel.rb ADDED
@@ -0,0 +1,9 @@
1
+ module Kernel
2
+ def suppress_warnings
3
+ original_verbosity = $VERBOSE
4
+ $VERBOSE = nil
5
+ result = yield
6
+ $VERBOSE = original_verbosity
7
+ result
8
+ end
9
+ end
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.7.2
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: 2019-12-04 00:00:00.000000000 Z
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.0.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.