renorb-pdf_filler 0.3.4
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.
- data/LICENSE +20 -0
- data/README.rdoc +117 -0
- data/Rakefile +4 -0
- data/init.rb +1 -0
- data/lib/iText-2.1.7.jar +0 -0
- data/lib/pdf_filler.rb +50 -0
- data/lib/pdf_filler/book.rb +94 -0
- data/lib/pdf_filler/page.rb +246 -0
- data/lib/pdf_filler/pdf_db_mapper.rb +74 -0
- data/lib/pdf_filler/util_methods.rb +50 -0
- data/spec/lib/pdf_book_spec.rb +74 -0
- data/spec/lib/pdf_db_mapper_spec.rb +51 -0
- data/spec/lib/pdf_page_spec.rb +89 -0
- data/spec/spec_helper.rb +111 -0
- data/spec/templates/certificate_template.pdf +0 -0
- data/tasks/build_gem.rake +60 -0
- data/tasks/documentation.rake +32 -0
- metadata +86 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Great Basin Solutions, LLC dba Great Basin Development
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
= pdf_filler
|
2
|
+
|
3
|
+
The <b>pdf_filler</b> Rails plugin makes it easy to update existing PDFs that have form fields defined.
|
4
|
+
Rather then building PDFs in Ruby using something like PDF-Writer, it is much easier to create a PDF in Acrobat,
|
5
|
+
define fields, and update those fields using pdf_filler. An example would be a First/Last name field on a PDF that is possible to update.
|
6
|
+
|
7
|
+
|
8
|
+
== Requirements
|
9
|
+
|
10
|
+
This plugin requires RJB (Ruby Java Bridge), so you will need to set your JAVA_HOME environment variable to point your installation of Java.
|
11
|
+
|
12
|
+
If your JAVA_HOME environment variable is not setup correctly you will get something like:
|
13
|
+
|
14
|
+
|
15
|
+
Building native extensions. This could take a while...
|
16
|
+
ERROR: Error installing pdf_filler-0.1.0.gem:
|
17
|
+
ERROR: Failed to build gem native extension.
|
18
|
+
|
19
|
+
/opt/local/bin/ruby extconf.rb
|
20
|
+
*** extconf.rb failed ***
|
21
|
+
Could not create Makefile due to some reason, probably lack of
|
22
|
+
necessary libraries and/or headers. Check the mkmf.log file for more
|
23
|
+
details. You may need configuration options.
|
24
|
+
|
25
|
+
Provided configuration options:
|
26
|
+
--with-opt-dir
|
27
|
+
--without-opt-dir
|
28
|
+
--with-opt-include
|
29
|
+
--without-opt-include=${opt-dir}/include
|
30
|
+
--with-opt-lib
|
31
|
+
--without-opt-lib=${opt-dir}/lib
|
32
|
+
--with-make-prog
|
33
|
+
--without-make-prog
|
34
|
+
--srcdir=.
|
35
|
+
--curdir
|
36
|
+
--ruby=/opt/local/bin/ruby
|
37
|
+
extconf.rb:45: JAVA_HOME is not set. (RuntimeError)
|
38
|
+
|
39
|
+
Gem files will remain installed in /opt/local/lib/ruby/gems/1.8/gems/rjb-1.1.7 for inspection.
|
40
|
+
Results logged to /opt/local/lib/ruby/gems/1.8/gems/rjb-1.1.7/ext/gem_make.out
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
<b>On my Mac I set JAVA_HOME to be "/System/Library/Frameworks/JavaVM.framework/Versions/1.5/Home".</b>
|
45
|
+
|
46
|
+
|
47
|
+
== Installing
|
48
|
+
|
49
|
+
The recommended method to enable pdf_filler in your project is adding the pdf_filler gem to your environment. Add the following code to your Rails configuration in <tt>config/environment.rb</tt>:
|
50
|
+
|
51
|
+
Rails::Initializer.run do |config|
|
52
|
+
...
|
53
|
+
config.gem 'gbdev-pdf_filler', :lib => 'pdf_filler', source => 'http://gems.github.com/'
|
54
|
+
end
|
55
|
+
|
56
|
+
Run <tt>sudo rake gems:install</tt> to install the gem.
|
57
|
+
|
58
|
+
Another alternative is to install pdf_filler as a Rails plugin:
|
59
|
+
|
60
|
+
script/plugin install git://github.com/gbdev/pdf_filler.git
|
61
|
+
|
62
|
+
|
63
|
+
== Usage
|
64
|
+
|
65
|
+
1. You will need a PDF that has form fields to fill.
|
66
|
+
|
67
|
+
2. A writable directory to store the generated PDFs.
|
68
|
+
|
69
|
+
3. For a single page use the Page object?
|
70
|
+
|
71
|
+
// ** Single page **
|
72
|
+
page = GBDev::PDF::Page.new('/path/to/template.pdf')
|
73
|
+
page.set_text(:full_name, 'Wes Hays')
|
74
|
+
page.save_to('/path/to/save.pdf')
|
75
|
+
|
76
|
+
4. For a collection of pages to be added to a single PDF use a Book object.
|
77
|
+
|
78
|
+
book = GBDev::PDF::Book.new
|
79
|
+
|
80
|
+
page1 = GBDev::PDF::Page.new('/path/to/template1.pdf')
|
81
|
+
page1.set_text(:full_name, 'Wes Hays')
|
82
|
+
|
83
|
+
page2 = GBDev::PDF::Page.new('/path/to/template2.pdf')
|
84
|
+
page2.set_text(:full_name, 'Darren Johnson')
|
85
|
+
|
86
|
+
book.add_page(page1)
|
87
|
+
book.add_page(page2)
|
88
|
+
|
89
|
+
book.save_to('/page/to/book.pdf')
|
90
|
+
|
91
|
+
5. Rather then setting all the fields manually a PDF can be mapped to an ActiveRecord model.
|
92
|
+
The model must use the acts_as_pdf_db_mapper module. (<b><i>See rdocs on acts_as_pdf_db_mapper for more options</i></b>)
|
93
|
+
|
94
|
+
class User < ActiveRecord::Base
|
95
|
+
...
|
96
|
+
acts_as_pdf_db_mapper
|
97
|
+
...
|
98
|
+
end
|
99
|
+
|
100
|
+
user = User.first
|
101
|
+
page = GBDev::PDF::Page.new('/path/to/template1.pdf')
|
102
|
+
page.map_to_object(user)
|
103
|
+
page.save_to('/path/to/save.pdf)
|
104
|
+
|
105
|
+
|
106
|
+
Note: You can use the shorter kernel methods PDFPage instead of GBDev::PDF::Page.new. The same goes for PDFBook instead of GBDev::PDF::Book.new.
|
107
|
+
|
108
|
+
Example:
|
109
|
+
|
110
|
+
page = PDFPage('/path/to/template.pdf')
|
111
|
+
book = PDFBook()
|
112
|
+
|
113
|
+
|
114
|
+
== License
|
115
|
+
|
116
|
+
This plugin is released under the MIT license. Please contact weshays (http://github.com/weshays)
|
117
|
+
or djohnson (http://github.com/djohnson) for any questions.
|
data/Rakefile
ADDED
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'pdf_filler'
|
data/lib/iText-2.1.7.jar
ADDED
Binary file
|
data/lib/pdf_filler.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'rjb'
|
3
|
+
|
4
|
+
load_path = File.expand_path(File.dirname(__FILE__) + '/iText-2.1.7.jar')
|
5
|
+
options = ['-Djava.awt.headless=true']
|
6
|
+
Rjb::load load_path, options
|
7
|
+
|
8
|
+
FileOutputStream = Rjb::import('java.io.FileOutputStream')
|
9
|
+
ByteArrayOutputStream = Rjb::import('java.io.ByteArrayOutputStream')
|
10
|
+
ByteArrayInputStream = Rjb::import('java.io.ByteArrayInputStream')
|
11
|
+
PdfWriter = Rjb::import('com.lowagie.text.pdf.PdfWriter')
|
12
|
+
PdfReader = Rjb::import('com.lowagie.text.pdf.PdfReader')
|
13
|
+
PdfCopy = Rjb::import('com.lowagie.text.pdf.PdfCopy')
|
14
|
+
PdfImportedPage = Rjb::import('com.lowagie.text.pdf.PdfImportedPage')
|
15
|
+
Document = Rjb::import('com.lowagie.text.Document')
|
16
|
+
Paragraph = Rjb::import('com.lowagie.text.Paragraph')
|
17
|
+
AcroFields = Rjb::import('com.lowagie.text.pdf.AcroFields')
|
18
|
+
PdfStamper = Rjb::import('com.lowagie.text.pdf.PdfStamper')
|
19
|
+
HashMap = Rjb::import('java.util.HashMap')
|
20
|
+
Iterator = Rjb::import('java.util.Iterator')
|
21
|
+
|
22
|
+
require 'pdf_filler/util_methods'
|
23
|
+
require 'pdf_filler/page'
|
24
|
+
require 'pdf_filler/book'
|
25
|
+
require 'pdf_filler/pdf_db_mapper'
|
26
|
+
|
27
|
+
|
28
|
+
module Kernel
|
29
|
+
|
30
|
+
# A shortcut kernel method for creating a new PDF Page without having to specify the full path to the page.
|
31
|
+
# Therefore,
|
32
|
+
# * PDFPage(template)
|
33
|
+
# and
|
34
|
+
# * RenoRB::PDF::Page.new(template)
|
35
|
+
# are the same thing.
|
36
|
+
def PDFPage(template)
|
37
|
+
RenoRB::PDF::Page.new(template)
|
38
|
+
end
|
39
|
+
|
40
|
+
# A shortcut kernel method for creating a new PDF Book without having to specify the full path to the book.
|
41
|
+
# Therefore,
|
42
|
+
# * PDFBook()
|
43
|
+
# and
|
44
|
+
# * RenoRB::PDF::Book.new
|
45
|
+
# are the same thing.
|
46
|
+
def PDFBook()
|
47
|
+
RenoRB::PDF::Book.new
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module RenoRB
|
2
|
+
|
3
|
+
module PDF
|
4
|
+
|
5
|
+
# A book that represents collection of PDF page.
|
6
|
+
class Book
|
7
|
+
|
8
|
+
def initialize()
|
9
|
+
@pages = []
|
10
|
+
end
|
11
|
+
|
12
|
+
# Add a page to the book
|
13
|
+
#
|
14
|
+
# * new_page - The page object of type RenoRB::PDF::Page
|
15
|
+
def add_page(new_page)
|
16
|
+
@pages << new_page
|
17
|
+
end
|
18
|
+
|
19
|
+
# Renders the PDF Book and saves it to the specified file.
|
20
|
+
#
|
21
|
+
# * filename - A path to the file to be created.
|
22
|
+
def save_to(filename)
|
23
|
+
dir = File.dirname(filename)
|
24
|
+
temp_dir = [dir, "collection_temp_#{build_random_string}"].join('/')
|
25
|
+
Dir.mkdir(temp_dir)
|
26
|
+
@pages.each_with_index do |page, indx|
|
27
|
+
page.save_to([temp_dir, "#{indx}_#{build_random_file_name}"].join('/'))
|
28
|
+
end
|
29
|
+
temp_files = Dir[[temp_dir,'*'].join('/')].sort
|
30
|
+
|
31
|
+
document = Document.new
|
32
|
+
copier = PdfCopy.new(document, FileOutputStream.new(filename))
|
33
|
+
|
34
|
+
document.open
|
35
|
+
temp_files.each do |read_target|
|
36
|
+
reader = PdfReader.new(read_target)
|
37
|
+
n_pages = reader.getNumberOfPages
|
38
|
+
n_pages.times do |i|
|
39
|
+
copier.addPage( copier.getImportedPage(reader, i+1)) if copier
|
40
|
+
end
|
41
|
+
end
|
42
|
+
document.close
|
43
|
+
|
44
|
+
FileUtils.rm_rf(temp_dir, {:secure => true})
|
45
|
+
end
|
46
|
+
|
47
|
+
# Renders the template with the given data and returns that buffer.
|
48
|
+
def to_buffer
|
49
|
+
dir = defined?(RAILS_ROOT) ? [RAILS_ROOT, 'tmp'].join('/') : File.expand_path(File.dirname(__FILE__) + '/../../spec/output')
|
50
|
+
temp_dir = [dir, "collection_temp_#{build_random_string}"].join('/')
|
51
|
+
Dir.mkdir(temp_dir)
|
52
|
+
@pages.each_with_index do |page, indx|
|
53
|
+
page.save_to([temp_dir, "#{indx}_#{build_random_file_name}"].join('/'))
|
54
|
+
end
|
55
|
+
temp_files = Dir[[temp_dir,'*'].join('/')].sort
|
56
|
+
|
57
|
+
document = Document.new
|
58
|
+
baos = ByteArrayOutputStream.new
|
59
|
+
copier = PdfCopy.new(document, baos)
|
60
|
+
|
61
|
+
document.open
|
62
|
+
|
63
|
+
# This did not work but try working on it again later.
|
64
|
+
# @pages.each do |page|
|
65
|
+
# bais = ByteArrayInputStream.new_with_sig(page.to_buffer)
|
66
|
+
# reader = PdfReader.new(bais)
|
67
|
+
# reader = page.get_pdf_reader
|
68
|
+
# n_pages = reader.getNumberOfPages
|
69
|
+
# n_pages.times do |i|
|
70
|
+
# copier.addPage( copier.getImportedPage(reader, i+1)) if copier
|
71
|
+
# end
|
72
|
+
# end
|
73
|
+
|
74
|
+
temp_files.each do |read_target|
|
75
|
+
reader = PdfReader.new(read_target)
|
76
|
+
n_pages = reader.getNumberOfPages
|
77
|
+
n_pages.times do |i|
|
78
|
+
copier.addPage( copier.getImportedPage(reader, i+1)) if copier
|
79
|
+
end
|
80
|
+
end
|
81
|
+
document.close
|
82
|
+
|
83
|
+
#FileUtils.rm_rf(temp_dir, {:secure => true})
|
84
|
+
|
85
|
+
return baos.toByteArray()
|
86
|
+
end
|
87
|
+
|
88
|
+
include RenoRB::Utils::PrivateMethods
|
89
|
+
|
90
|
+
end # End Filler
|
91
|
+
|
92
|
+
end # End PDF
|
93
|
+
|
94
|
+
end # End RenoRB
|
@@ -0,0 +1,246 @@
|
|
1
|
+
module RenoRB
|
2
|
+
|
3
|
+
module PDF
|
4
|
+
|
5
|
+
# A page that represents a PDF page.
|
6
|
+
class Page
|
7
|
+
|
8
|
+
CHECK_BOX = 'Check Box'
|
9
|
+
COMBO_BOX = 'Combo Box'
|
10
|
+
LIST = 'List'
|
11
|
+
PUSH_BUTTON = 'Push Button'
|
12
|
+
RADIO_BUTTON = 'Radio Button'
|
13
|
+
SIGNATURE = 'Signature'
|
14
|
+
TEXT_FIELD = 'Text Field'
|
15
|
+
NONE = 'None'
|
16
|
+
UNKNOWN = '?'
|
17
|
+
|
18
|
+
# String template : A path to the template file
|
19
|
+
def initialize(template)
|
20
|
+
@template = template
|
21
|
+
|
22
|
+
@pdf_fields = {}
|
23
|
+
|
24
|
+
@check_boxes = {}
|
25
|
+
@images = {}
|
26
|
+
@radio_buttons = {}
|
27
|
+
@signature_fields = {}
|
28
|
+
@text_fields = {}
|
29
|
+
|
30
|
+
@pdf_reader = nil
|
31
|
+
end
|
32
|
+
|
33
|
+
# Returns a hash where the keys are the field names in the template PDF and the values are the field types.
|
34
|
+
def get_pdf_fields
|
35
|
+
return @pdf_fields unless @pdf_fields.empty?
|
36
|
+
|
37
|
+
reader = PdfReader.new(@template)
|
38
|
+
form = reader.getAcroFields()
|
39
|
+
fields = form.getFields()
|
40
|
+
i = fields.keySet().iterator()
|
41
|
+
|
42
|
+
while(i.hasNext())
|
43
|
+
key = i.next()
|
44
|
+
|
45
|
+
case(form.getFieldType(key))
|
46
|
+
when AcroFields.FIELD_TYPE_CHECKBOX
|
47
|
+
@pdf_fields[key.to_string().to_sym] = RenoRB::PDF::Page::CHECK_BOX
|
48
|
+
when AcroFields.FIELD_TYPE_COMBO
|
49
|
+
@pdf_fields[key.to_string().to_sym] = RenoRB::PDF::Page::COMBO_BOX
|
50
|
+
when AcroFields.FIELD_TYPE_LIST
|
51
|
+
@pdf_fields[key.to_string().to_sym] = RenoRB::PDF::Page::LIST
|
52
|
+
when AcroFields.FIELD_TYPE_NONE
|
53
|
+
@pdf_fields[key.to_string().to_sym] = RenoRB::PDF::Page::NONE
|
54
|
+
when AcroFields.FIELD_TYPE_PUSHBUTTON
|
55
|
+
@pdf_fields[key.to_string().to_sym] = RenoRB::PDF::Page::PUSH_BUTTON
|
56
|
+
when AcroFields.FIELD_TYPE_RADIOBUTTON
|
57
|
+
@pdf_fields[key.to_string().to_sym] = RenoRB::PDF::Page::RADIO_BUTTON
|
58
|
+
when AcroFields.FIELD_TYPE_SIGNATURE
|
59
|
+
@pdf_fields[key.to_string().to_sym] = RenoRB::PDF::Page::SIGNATURE
|
60
|
+
when AcroFields.FIELD_TYPE_TEXT
|
61
|
+
@pdf_fields[key.to_string().to_sym] = RenoRB::PDF::Page::TEXT_FIELD
|
62
|
+
else
|
63
|
+
@pdf_fields[key.to_string().to_sym] = RenoRB::PDF::Page::UNKNOWN
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
return @pdf_fields
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns an array of field states. For example if the field type is a list an array
|
71
|
+
# with all possible choices in the list will be returned.
|
72
|
+
#
|
73
|
+
# * field_name - The field name to get all the possible states for.
|
74
|
+
def get_field_states(field_name)
|
75
|
+
reader = PdfReader.new(@template)
|
76
|
+
form = reader.getAcroFields()
|
77
|
+
form.getAppearanceStates(field_name.to_s);
|
78
|
+
end
|
79
|
+
|
80
|
+
|
81
|
+
# Sets a know checkbox in the PDF template.
|
82
|
+
#
|
83
|
+
# * key - A known checkbox in the PDF.
|
84
|
+
# * value - The checkbox to update.
|
85
|
+
def set_checkbox(key, value)
|
86
|
+
@check_boxes[key] = value
|
87
|
+
end
|
88
|
+
|
89
|
+
# Alias for the set_checkbox method
|
90
|
+
alias :checkbox :set_checkbox
|
91
|
+
|
92
|
+
# NOT WORING YET
|
93
|
+
# Sets a known image area in the PDF template.
|
94
|
+
#
|
95
|
+
# * key - A known image in the PDF.
|
96
|
+
# * value - The image to apply to the know image area.
|
97
|
+
def set_image(key, value)
|
98
|
+
raise 'Image not working yet'
|
99
|
+
@images[key] = value
|
100
|
+
end
|
101
|
+
|
102
|
+
# Alias for the set_image method
|
103
|
+
alias :image :set_image
|
104
|
+
|
105
|
+
|
106
|
+
# Sets a known radio button in the PDF template.
|
107
|
+
#
|
108
|
+
# * key - A known radio button group in the PDF.
|
109
|
+
# * value - The radio button group to update.
|
110
|
+
def set_radio_button(key, value)
|
111
|
+
@radio_buttons[key] = value
|
112
|
+
end
|
113
|
+
|
114
|
+
# Alias for the set_checkbox method
|
115
|
+
alias :radio_button :set_radio_button
|
116
|
+
|
117
|
+
|
118
|
+
# NOT WORKING YET
|
119
|
+
# Sets a known signature field in the PDF template.
|
120
|
+
#
|
121
|
+
# * key - A known signature field in the PDF.
|
122
|
+
# * value - The value to apply to the know field.
|
123
|
+
def set_signature_field(key, value)
|
124
|
+
raise 'Signature field not working yet'
|
125
|
+
@signature_fields[key] = value
|
126
|
+
end
|
127
|
+
|
128
|
+
# Alias for set_signature_field method
|
129
|
+
alias :signature_field :set_signature_field
|
130
|
+
|
131
|
+
|
132
|
+
# Sets a known text field in the PDF template.
|
133
|
+
#
|
134
|
+
# * key - A known text field in the PDF.
|
135
|
+
# * value - The value to apply to the know field.
|
136
|
+
def set_text_field(key, value)
|
137
|
+
@text_fields[key] = value
|
138
|
+
end
|
139
|
+
|
140
|
+
# Alias for set_text method
|
141
|
+
alias :text_field :set_text_field
|
142
|
+
|
143
|
+
# Maps PDF fields to an ActiveRecord object. The ActiveRecord object must use the
|
144
|
+
# acts_as_pdf_db_mapper module.
|
145
|
+
#
|
146
|
+
# * object - An ActiveRecord object that uses the acts_as_pdf_db_mapper module.
|
147
|
+
def map_to_object(object)
|
148
|
+
if object.methods.include?('mapped_fields')
|
149
|
+
fields = self.get_pdf_fields
|
150
|
+
object.mapped_fields.each do |mapped_field|
|
151
|
+
|
152
|
+
if mapped_field.class.to_s == 'Hash'
|
153
|
+
key_value_pair = mapped_field.first.to_a.flatten
|
154
|
+
key = key_value_pair[0]
|
155
|
+
value = key_value_pair[1]
|
156
|
+
else
|
157
|
+
key = mapped_field
|
158
|
+
value = mapped_field
|
159
|
+
end
|
160
|
+
|
161
|
+
case(fields[key])
|
162
|
+
when RenoRB::PDF::Page::CHECK_BOX
|
163
|
+
self.set_checkbox(key, object.send(value))
|
164
|
+
when RenoRB::PDF::Page::COMBO_BOX
|
165
|
+
#self.set_combobox(key, object.send(value))
|
166
|
+
when RenoRB::PDF::Page::LIST
|
167
|
+
#self.set_list(key, object.send(value))
|
168
|
+
when RenoRB::PDF::Page::NONE
|
169
|
+
#self.set_none(key, object.send(value))
|
170
|
+
when RenoRB::PDF::Page::PUSH_BUTTON
|
171
|
+
#self.set_push_button(key, object.send(value))
|
172
|
+
when RenoRB::PDF::Page::RADIO_BUTTON
|
173
|
+
self.set_radio_button(key, object.send(value))
|
174
|
+
when RenoRB::PDF::Page::SIGNATURE
|
175
|
+
self.set_signature_field(key, object.send(value))
|
176
|
+
when RenoRB::PDF::Page::TEXT_FIELD
|
177
|
+
self.set_text_field(key, object.send(value))
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
# Renders the template with the given data and saves to the given filename path.
|
186
|
+
#
|
187
|
+
# * filename - A path to the file to be created.
|
188
|
+
def save_to(filename)
|
189
|
+
field_cache = HashMap.new
|
190
|
+
reader = PdfReader.new(@template)
|
191
|
+
stamper = PdfStamper.new( reader, FileOutputStream.new(filename) )
|
192
|
+
form = stamper.getAcroFields()
|
193
|
+
form.setFieldCache(field_cache)
|
194
|
+
|
195
|
+
all_fields = {}
|
196
|
+
all_fields.merge!(@check_boxes)
|
197
|
+
all_fields.merge!(@radio_buttons)
|
198
|
+
all_fields.merge!(@signature_fields)
|
199
|
+
all_fields.merge!(@text_fields)
|
200
|
+
|
201
|
+
all_fields.each do |field, value|
|
202
|
+
form.setField(field.to_s, value.to_s)
|
203
|
+
end
|
204
|
+
|
205
|
+
# TODO: do something with @images
|
206
|
+
|
207
|
+
stamper.setFormFlattening(true)
|
208
|
+
stamper.close
|
209
|
+
end
|
210
|
+
|
211
|
+
|
212
|
+
# Renders the template with the given data and returns that buffer.
|
213
|
+
def to_buffer
|
214
|
+
field_cache = HashMap.new
|
215
|
+
reader = PdfReader.new(@template)
|
216
|
+
baos = ByteArrayOutputStream.new
|
217
|
+
stamper = PdfStamper.new( reader, baos )
|
218
|
+
form = stamper.getAcroFields()
|
219
|
+
form.setFieldCache(field_cache)
|
220
|
+
|
221
|
+
all_fields = {}
|
222
|
+
all_fields.merge!(@check_boxes)
|
223
|
+
all_fields.merge!(@radio_buttons)
|
224
|
+
all_fields.merge!(@signature_fields)
|
225
|
+
all_fields.merge!(@text_fields)
|
226
|
+
|
227
|
+
all_fields.each do |field, value|
|
228
|
+
form.setField(field.to_s, value.to_s)
|
229
|
+
end
|
230
|
+
|
231
|
+
# TODO: do something with @images
|
232
|
+
|
233
|
+
stamper.setFormFlattening(true)
|
234
|
+
stamper.close
|
235
|
+
|
236
|
+
return baos.toByteArray()
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
include RenoRB::Utils::PrivateMethods
|
241
|
+
|
242
|
+
end # End Page
|
243
|
+
|
244
|
+
end # End PDF
|
245
|
+
|
246
|
+
end # End RenoRB
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module RenoRB #:nodoc:
|
4
|
+
module PDF #:nodoc:
|
5
|
+
module Acts #:nodoc:
|
6
|
+
module PDFDBMapper # :nodoc:
|
7
|
+
|
8
|
+
def self.included(mod)
|
9
|
+
mod.extend(ClassMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
module ClassMethods
|
13
|
+
|
14
|
+
# Automatically maps database fields to fields found in the template PDF with the same name.
|
15
|
+
# Database fields not found in the template PDF are ignored. If no options are specified then
|
16
|
+
# by default all table fields will attempt to be mapped.
|
17
|
+
#
|
18
|
+
# Configuration options are:
|
19
|
+
#
|
20
|
+
# * :only - Only map the database fields specified. i.e :only => [:first_name, :last_name]
|
21
|
+
# * :except - Map all the table fields except those specified. i.e. :except => [:middle_name]
|
22
|
+
# * :include - Allows for a method to map to a field in the PDF. If you have a method called full_name
|
23
|
+
# that combines the first name and last name, you could map that method to a PDF text field called full_name.
|
24
|
+
# :include => [:full_name].
|
25
|
+
# You could all specify a model attribute/method to map to a different PDF field.
|
26
|
+
# i.e. :include => [{:full_name => :dog_name}]
|
27
|
+
# :include will still work with :only and :except.
|
28
|
+
# * :only_include - Will ignore :only and :except and only includes the manual mappings specified.
|
29
|
+
# i.e. :only_include => [:full_name, {:animal_name => :dog_name}]
|
30
|
+
def acts_as_pdf_db_mapper(*fields)
|
31
|
+
|
32
|
+
# Make sure that the table to be mapped actually exists
|
33
|
+
if self.table_exists?
|
34
|
+
|
35
|
+
# Get a collection of fields to be searched on.
|
36
|
+
if fields.first.class.to_s == 'Hash'
|
37
|
+
|
38
|
+
if fields.first.has_key?(:only_include)
|
39
|
+
fields_to_map = fields.first[:only_include]
|
40
|
+
else
|
41
|
+
if fields.first.has_key?(:only)
|
42
|
+
# only map on these fields.
|
43
|
+
fields_to_map = fields.first[:only]
|
44
|
+
elsif fields.first.has_key?(:except)
|
45
|
+
# Get all the fields and remove any that are in the -except- list.
|
46
|
+
fields_to_map = self.column_names.collect { |column| fields.first[:except].include?(column.to_sym) ? nil : column.to_sym }.compact
|
47
|
+
else
|
48
|
+
fields_to_map = self.column_names.collect { |column| column.to_sym }
|
49
|
+
end
|
50
|
+
|
51
|
+
if fields.first.has_key?(:include)
|
52
|
+
fields_to_map += fields.first[:include]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
else
|
56
|
+
fields_to_map = self.column_names.collect { |column| column.to_sym }
|
57
|
+
end
|
58
|
+
|
59
|
+
# Set the appropriate class attributes.
|
60
|
+
self.cattr_accessor :mapped_fields
|
61
|
+
self.mapped_fields = fields_to_map
|
62
|
+
|
63
|
+
end # End table exists check
|
64
|
+
|
65
|
+
end # acts_as_pdf_db_mapper
|
66
|
+
|
67
|
+
end # ClassMethods
|
68
|
+
|
69
|
+
end # PDFDBMapper
|
70
|
+
end # Acts
|
71
|
+
end # PDF
|
72
|
+
end # RenoRB
|
73
|
+
|
74
|
+
ActiveRecord::Base.send(:include, RenoRB::PDF::Acts::PDFDBMapper)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module RenoRB #:nodoc: all
|
2
|
+
|
3
|
+
module Utils
|
4
|
+
|
5
|
+
module PrivateMethods
|
6
|
+
|
7
|
+
def build_random_string # :nodoc:
|
8
|
+
letters_array = [('a'..'z'),('A'..'Z')].collect{|i| i.to_a}.flatten
|
9
|
+
(1..10).collect{ letters_array[ rand(letters_array.length) ] }.join
|
10
|
+
end
|
11
|
+
|
12
|
+
def build_random_file_name # :nodoc:
|
13
|
+
build_random_string << '.pdf'
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
# Include these controller methods to prompt the user to download the PDF.
|
20
|
+
#
|
21
|
+
# * include RenoRB::Utils::ControllerMethods
|
22
|
+
module ControllerMethods
|
23
|
+
|
24
|
+
# Used to display the PDF without saving it to disk.
|
25
|
+
#
|
26
|
+
# * buffer - A Page buffer or Book buffer.
|
27
|
+
# * filename - The filename to apply to the buffer when prompted to download.
|
28
|
+
def display_pdf(buffer, filename)
|
29
|
+
send_data(buffer, {:type => 'application/pdf',
|
30
|
+
:disposition => 'attachment',
|
31
|
+
:filename => filename} )
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
# From here: http://railspdfplugin.rubyforge.org/wiki/wiki.pl
|
36
|
+
# Suggested code so errors will always show in browser
|
37
|
+
def rescue_action_in_public(exception) # :nodoc:
|
38
|
+
headers.delete("Content-Disposition")
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
def rescue_action_locally(exception) # :nodoc:
|
43
|
+
headers.delete("Content-Disposition")
|
44
|
+
super
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
describe 'Book' do
|
4
|
+
|
5
|
+
it 'should create the book of pages and write to the output directory' do
|
6
|
+
book = RenoRB::PDF::Book.new
|
7
|
+
|
8
|
+
template_file = File.expand_path(File.dirname(__FILE__) + '/../templates/certificate_template.pdf')
|
9
|
+
pdf_book = File.expand_path(File.dirname(__FILE__) + '/../output/certs.pdf')
|
10
|
+
|
11
|
+
page1 = RenoRB::PDF::Page.new(template_file)
|
12
|
+
page1.set_text_field(:full_name, 'Wes Hays')
|
13
|
+
|
14
|
+
page2 = RenoRB::PDF::Page.new(template_file)
|
15
|
+
page2.set_text_field(:full_name, 'Darren Johnson')
|
16
|
+
|
17
|
+
page3 = RenoRB::PDF::Page.new(template_file)
|
18
|
+
page3.set_text_field(:full_name, 'John Dell')
|
19
|
+
|
20
|
+
book.add_page(page1)
|
21
|
+
book.add_page(page2)
|
22
|
+
book.add_page(page3)
|
23
|
+
|
24
|
+
book.save_to(pdf_book)
|
25
|
+
|
26
|
+
File.exist?(pdf_book).should be_true
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should create the book of pages and write to the output directory with Kernel method' do
|
30
|
+
book = PDFBook()
|
31
|
+
|
32
|
+
template_file = File.expand_path(File.dirname(__FILE__) + '/../templates/certificate_template.pdf')
|
33
|
+
pdf_book = File.expand_path(File.dirname(__FILE__) + '/../output/certs.pdf')
|
34
|
+
|
35
|
+
page1 = RenoRB::PDF::Page.new(template_file)
|
36
|
+
page1.set_text_field(:full_name, 'Wes Hays')
|
37
|
+
|
38
|
+
page2 = RenoRB::PDF::Page.new(template_file)
|
39
|
+
page2.set_text_field(:full_name, 'Darren Johnson')
|
40
|
+
|
41
|
+
page3 = RenoRB::PDF::Page.new(template_file)
|
42
|
+
page3.set_text_field(:full_name, 'John Dell')
|
43
|
+
|
44
|
+
book.add_page(page1)
|
45
|
+
book.add_page(page2)
|
46
|
+
book.add_page(page3)
|
47
|
+
|
48
|
+
book.save_to(pdf_book)
|
49
|
+
|
50
|
+
File.exist?(pdf_book).should be_true
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should return the buffer without writing to disk' do
|
54
|
+
book = PDFBook()
|
55
|
+
|
56
|
+
template_file = File.expand_path(File.dirname(__FILE__) + '/../templates/certificate_template.pdf')
|
57
|
+
|
58
|
+
page1 = RenoRB::PDF::Page.new(template_file)
|
59
|
+
page1.set_text_field(:full_name, 'Wes Hays')
|
60
|
+
|
61
|
+
page2 = RenoRB::PDF::Page.new(template_file)
|
62
|
+
page2.set_text_field(:full_name, 'Darren Johnson')
|
63
|
+
|
64
|
+
page3 = RenoRB::PDF::Page.new(template_file)
|
65
|
+
page3.set_text_field(:full_name, 'John Dell')
|
66
|
+
|
67
|
+
book.add_page(page1)
|
68
|
+
book.add_page(page2)
|
69
|
+
book.add_page(page3)
|
70
|
+
|
71
|
+
book.to_buffer.should_not be_blank
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
describe 'PDF_DB_Mapper' do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
Address.create_corpus!
|
7
|
+
end
|
8
|
+
|
9
|
+
after(:each) do
|
10
|
+
Address.destroy_all
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should allow all database columns to be mapped if no :only or :except is specified' do
|
14
|
+
address = Address.first
|
15
|
+
fields_array = address.mapped_fields.collect{|f| f.to_s}.sort
|
16
|
+
fields_array.should == ['id', 'address1', 'address2', 'city', 'state', 'postal_code'].sort
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should only map the fields specified by :only' do
|
20
|
+
address = ClientAddress.first
|
21
|
+
fields_array = address.mapped_fields.collect{|f| f.to_s}.sort
|
22
|
+
fields_array.should == ['city', 'state'].sort
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should map all the fields except the fields specified by :except' do
|
26
|
+
address = ContactAddress.first
|
27
|
+
fields_array = address.mapped_fields.collect{|f| f.to_s}.sort
|
28
|
+
fields_array.should == ['address2', 'city', 'state'].sort
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should include the additional mappings specified by :include' do
|
32
|
+
address = UserAddress.first
|
33
|
+
fields_array = address.mapped_fields.collect{|f| f.class.to_s == 'Hash' ? f.first.to_a.flatten.join('::') : f.to_s}.sort
|
34
|
+
fields_array.should == ['id', 'address1', 'address2', 'city', 'state', 'postal_code','full_address::address'].sort
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should only include the mappings specified by :only_include' do
|
38
|
+
address = FamilyAddress.first
|
39
|
+
fields_array = address.mapped_fields.collect{|f| f.first.to_a.flatten.join('::')}.sort
|
40
|
+
fields_array.should == ['full_address::address'].sort
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'should map the specified fields for a single record to a single page' do
|
44
|
+
page = PDFPage(File.expand_path(File.dirname(__FILE__) + '/../templates/address_template.pdf'))
|
45
|
+
address = Address.first
|
46
|
+
page.map_to_object(address)
|
47
|
+
page.save_to(File.expand_path(File.dirname(__FILE__) + '/../output/db_address.pdf'))
|
48
|
+
File.exist?(File.dirname(__FILE__) + '/../output/db_address.pdf').should be_true
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../spec_helper")
|
2
|
+
|
3
|
+
describe 'Page' do
|
4
|
+
|
5
|
+
it 'should create the page and write to the output directory' do
|
6
|
+
page = RenoRB::PDF::Page.new(File.expand_path(File.dirname(__FILE__) + '/../templates/certificate_template.pdf'))
|
7
|
+
page.set_text_field(:full_name, 'Wes Hays')
|
8
|
+
page.save_to(File.expand_path(File.dirname(__FILE__) + '/../output/wes_hays.pdf'))
|
9
|
+
File.exist?(File.dirname(__FILE__) + '/../output/wes_hays.pdf').should be_true
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should create the page and write to the output directory with Kernel method' do
|
13
|
+
page = PDFPage(File.expand_path(File.dirname(__FILE__) + '/../templates/certificate_template.pdf'))
|
14
|
+
page.set_text_field(:full_name, 'Wes Hays')
|
15
|
+
page.save_to(File.expand_path(File.dirname(__FILE__) + '/../output/wes_hays.pdf'))
|
16
|
+
File.exist?(File.dirname(__FILE__) + '/../output/wes_hays.pdf').should be_true
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should find all three fields: text field, checkbox and radio buttons' do
|
20
|
+
page = PDFPage(File.expand_path(File.dirname(__FILE__) + '/../templates/form_template.pdf'))
|
21
|
+
fields = page.get_pdf_fields
|
22
|
+
|
23
|
+
fields.has_key?(:full_name).should be_true
|
24
|
+
fields[:full_name].should == RenoRB::PDF::Page::TEXT_FIELD
|
25
|
+
|
26
|
+
fields.has_key?(:home_owner).should be_true
|
27
|
+
fields[:home_owner].should == RenoRB::PDF::Page::RADIO_BUTTON
|
28
|
+
|
29
|
+
fields.has_key?(:newsletter).should be_true
|
30
|
+
fields[:newsletter].should == RenoRB::PDF::Page::CHECK_BOX
|
31
|
+
|
32
|
+
fields.has_key?(:car_types).should be_true
|
33
|
+
fields[:car_types].should == RenoRB::PDF::Page::LIST
|
34
|
+
|
35
|
+
fields.has_key?(:sibling_count).should be_true
|
36
|
+
fields[:sibling_count].should == RenoRB::PDF::Page::COMBO_BOX
|
37
|
+
|
38
|
+
# fields.has_key?(:owner_signature).should be_true
|
39
|
+
# fields[:owner_signature].should == RenoRB::PDF::Page::SIGNATURE
|
40
|
+
#
|
41
|
+
# fields.has_key?(:submit_button).should be_true
|
42
|
+
# fields[:submit_button].should == RenoRB::PDF::Page::PUSH_BUTTON
|
43
|
+
#
|
44
|
+
# fields.has_key?(:photo).should be_true
|
45
|
+
# fields[:photo].should == RenoRB::PDF::Page::IMAGE
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should find all the valid states for the check box' do
|
49
|
+
page = PDFPage(File.expand_path(File.dirname(__FILE__) + '/../templates/form_template.pdf'))
|
50
|
+
states = page.get_field_states(:newsletter) # Checkbox
|
51
|
+
states.should == ['Yes','Off']
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should find all the valid states for the radio button' do
|
55
|
+
page = PDFPage(File.expand_path(File.dirname(__FILE__) + '/../templates/form_template.pdf'))
|
56
|
+
states = page.get_field_states(:home_owner) # radio button
|
57
|
+
states.should == ['Yes','No','Off'] # Off will not be used but AcroFields returns it anyway.
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should find all the valid states for the list' do
|
61
|
+
page = PDFPage(File.expand_path(File.dirname(__FILE__) + '/../templates/form_template.pdf'))
|
62
|
+
states = page.get_field_states(:car_types) # List
|
63
|
+
states.sort.should == ['Chevy', 'Ford', 'Honda', 'Jeep', 'Toyota'].sort
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should find all the valid states for the combo box' do
|
67
|
+
page = PDFPage(File.expand_path(File.dirname(__FILE__) + '/../templates/form_template.pdf'))
|
68
|
+
states = page.get_field_states(:sibling_count) # List
|
69
|
+
states.sort.should == ['Zero','One','Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten'].sort
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should fill all fields' do
|
73
|
+
page = PDFPage(File.expand_path(File.dirname(__FILE__) + '/../templates/form_template.pdf'))
|
74
|
+
page.set_text_field(:full_name, 'Anna Hays')
|
75
|
+
page.set_checkbox(:home_owner, 'Yes')
|
76
|
+
page.set_checkbox(:newsletter, 'Yes')
|
77
|
+
page.set_checkbox(:car_types, 'Jeep')
|
78
|
+
page.set_checkbox(:sibling_count, 'One')
|
79
|
+
page.save_to(File.expand_path(File.dirname(__FILE__) + '/../output/form_test.pdf'))
|
80
|
+
File.exist?(File.dirname(__FILE__) + '/../output/form_test.pdf').should be_true
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should return the buffer without writing to disk' do
|
84
|
+
page = PDFPage(File.expand_path(File.dirname(__FILE__) + '/../templates/certificate_template.pdf'))
|
85
|
+
page.set_text_field(:full_name, 'Wes Hays')
|
86
|
+
pdf_data = page.to_buffer
|
87
|
+
pdf_data.should_not be_blank
|
88
|
+
end
|
89
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require 'rubygems'
|
3
|
+
require 'ruby-debug'
|
4
|
+
require 'activerecord'
|
5
|
+
|
6
|
+
##################
|
7
|
+
#### <CUSTOM> ####
|
8
|
+
##################
|
9
|
+
# Aliased "lambda" with "doing" so that when checking
|
10
|
+
# whether or not something raises an exception it will
|
11
|
+
# read like other rspec operations. For example:
|
12
|
+
# instead of
|
13
|
+
# lambda { ... }.should_not raise_error
|
14
|
+
# you can have
|
15
|
+
# doing { ... }.should_not raise_error
|
16
|
+
alias :doing :lambda
|
17
|
+
###################
|
18
|
+
#### </CUSTOM> ####
|
19
|
+
###################
|
20
|
+
|
21
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
|
22
|
+
ActiveRecord::Base.configurations = true
|
23
|
+
|
24
|
+
ActiveRecord::Schema.verbose = false
|
25
|
+
ActiveRecord::Schema.define(:version => 1) do
|
26
|
+
create_table :clients do |t|
|
27
|
+
t.string :first_name
|
28
|
+
t.string :last_name
|
29
|
+
end
|
30
|
+
|
31
|
+
create_table :addresses do |t|
|
32
|
+
t.string :address1
|
33
|
+
t.string :address2
|
34
|
+
t.string :city
|
35
|
+
t.string :state
|
36
|
+
t.string :postal_code
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
41
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
42
|
+
require 'pdf_filler'
|
43
|
+
|
44
|
+
|
45
|
+
module RenoRB
|
46
|
+
module TestData
|
47
|
+
module Addresses
|
48
|
+
def create_corpus!
|
49
|
+
create!(:address1 => '111 AAA St', :address2 => 'Suite 444', :city => 'Reno', :state => 'Nevada', :postal_code => '89506')
|
50
|
+
create!(:address1 => '222 BBB St', :address2 => 'Suite 555', :city => 'Sparks', :state => 'Nevada', :postal_code => '89434')
|
51
|
+
create!(:address1 => '333 CCC St', :address2 => 'Suite 666', :city => 'Fernley', :state => 'Nevada', :postal_code => '89408')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
Spec::Runner.configure do |config|
|
59
|
+
config.before(:each) do
|
60
|
+
class Client < ActiveRecord::Base
|
61
|
+
acts_as_pdf_db_mapper :only => [:first_name, :last_name]
|
62
|
+
has_many :addresses, :dependent => :destroy
|
63
|
+
|
64
|
+
def full_name
|
65
|
+
[self.first_name, self.last_name].join(' ')
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Address < ActiveRecord::Base
|
70
|
+
acts_as_pdf_db_mapper
|
71
|
+
belongs_to :client
|
72
|
+
extend RenoRB::TestData::Addresses
|
73
|
+
end
|
74
|
+
|
75
|
+
class ClientAddress < ActiveRecord::Base
|
76
|
+
set_table_name :addresses
|
77
|
+
acts_as_pdf_db_mapper :only => [:state, :city]
|
78
|
+
end
|
79
|
+
|
80
|
+
class ContactAddress < ActiveRecord::Base
|
81
|
+
set_table_name :addresses
|
82
|
+
acts_as_pdf_db_mapper :except => [:id, :address1, :postal_code]
|
83
|
+
end
|
84
|
+
|
85
|
+
class UserAddress < ActiveRecord::Base
|
86
|
+
set_table_name :addresses
|
87
|
+
acts_as_pdf_db_mapper :include => [{:full_address => :address}]
|
88
|
+
|
89
|
+
def full_address
|
90
|
+
[self.address1, self.address2].join(', ')
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class FamilyAddress < ActiveRecord::Base
|
95
|
+
set_table_name :addresses
|
96
|
+
acts_as_pdf_db_mapper :only_include => [{:full_address => :address}]
|
97
|
+
|
98
|
+
def full_address
|
99
|
+
[self.address1, self.address2].join(', ')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
Client.destroy_all
|
104
|
+
Address.destroy_all
|
105
|
+
end
|
106
|
+
|
107
|
+
config.after(:each) do
|
108
|
+
Object.send(:remove_const, :Client)
|
109
|
+
Object.send(:remove_const, :Address)
|
110
|
+
end
|
111
|
+
end
|
Binary file
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = 'pdf_filler'
|
8
|
+
#gem.version = '0.1.1' # In version file
|
9
|
+
gem.date = '2009-08-25'
|
10
|
+
|
11
|
+
gem.summary = "A Rails plugin to fill a PDF form using RJB and iText."
|
12
|
+
gem.description = "PDF Filler makes it easy to file your PDFs."
|
13
|
+
|
14
|
+
gem.authors = ['Reno Ruby Group']
|
15
|
+
gem.email = ['renorb@renorb.org']
|
16
|
+
gem.homepage = 'http://wiki.github.com/renorb/pdf_filler'
|
17
|
+
|
18
|
+
gem.has_rdoc = true
|
19
|
+
gem.rdoc_options << '--title' << gem.name << '--main' << 'README.rdoc' << '--line-numbers' << '--inline-source'
|
20
|
+
gem.extra_rdoc_files = ['README.rdoc']
|
21
|
+
|
22
|
+
gem.files = ['LICENSE',
|
23
|
+
'README.rdoc',
|
24
|
+
'Rakefile',
|
25
|
+
'init.rb',
|
26
|
+
'lib/iText-2.1.7.jar',
|
27
|
+
'lib/pdf_filler.rb',
|
28
|
+
'lib/pdf_filler/page.rb',
|
29
|
+
'lib/pdf_filler/book.rb',
|
30
|
+
'lib/pdf_filler/pdf_db_mapper.rb',
|
31
|
+
'lib/pdf_filler/util_methods.rb',
|
32
|
+
'tasks/documentation.rake',
|
33
|
+
'tasks/build_gem.rake',
|
34
|
+
'spec/spec_helper.rb',
|
35
|
+
'spec/lib/pdf_page_spec.rb',
|
36
|
+
'spec/lib/pdf_book_spec.rb',
|
37
|
+
'spec/lib/pdf_db_mapper_spec.rb',
|
38
|
+
'spec/output',
|
39
|
+
'spec/templates/certificate_template.pdf']
|
40
|
+
|
41
|
+
gem.test_files = ['spec/lib/pdf_page_spec.rb',
|
42
|
+
'spec/lib/pdf_book_spec.rb']
|
43
|
+
|
44
|
+
gem.add_dependency 'rjb', '>= 1.1.7'
|
45
|
+
end
|
46
|
+
rescue LoadError
|
47
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
48
|
+
end
|
49
|
+
|
50
|
+
require 'spec/rake/spectask'
|
51
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
52
|
+
spec.libs << 'lib' << 'spec'
|
53
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
54
|
+
end
|
55
|
+
|
56
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
57
|
+
spec.libs << 'lib' << 'spec'
|
58
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
59
|
+
spec.rcov = true
|
60
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
|
4
|
+
desc 'Generate documentation for PDF-Filler.'
|
5
|
+
Rake::RDocTask.new do |rdoc|
|
6
|
+
rdoc.rdoc_dir = 'doc/html'
|
7
|
+
rdoc.title = 'pdf_filler'
|
8
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
9
|
+
rdoc.main = 'README.rdoc'
|
10
|
+
rdoc.rdoc_files.include('LICENSE', 'lib/')
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
begin
|
15
|
+
require 'rcov/rcovtask'
|
16
|
+
Rcov::RcovTask.new do |t|
|
17
|
+
t.test_files = Dir[ "spec/**/*_spec.rb" ]
|
18
|
+
end
|
19
|
+
rescue LoadError
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
|
23
|
+
begin
|
24
|
+
require 'rcov/rcovtask'
|
25
|
+
desc 'Runs spec:rcov and then displays the coverage/index.html file in the browser.'
|
26
|
+
task :rcov_display => [:clobber_rcov, :rcov] do
|
27
|
+
system("open coverage/index.html")
|
28
|
+
end
|
29
|
+
rescue LoadError
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: renorb-pdf_filler
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Reno Ruby Group
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-25 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rjb
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.1.7
|
24
|
+
version:
|
25
|
+
description: PDF Filler makes it easy to file your PDFs.
|
26
|
+
email:
|
27
|
+
- renorb@renorb.org
|
28
|
+
executables: []
|
29
|
+
|
30
|
+
extensions: []
|
31
|
+
|
32
|
+
extra_rdoc_files:
|
33
|
+
- README.rdoc
|
34
|
+
files:
|
35
|
+
- LICENSE
|
36
|
+
- README.rdoc
|
37
|
+
- Rakefile
|
38
|
+
- init.rb
|
39
|
+
- lib/iText-2.1.7.jar
|
40
|
+
- lib/pdf_filler.rb
|
41
|
+
- lib/pdf_filler/book.rb
|
42
|
+
- lib/pdf_filler/page.rb
|
43
|
+
- lib/pdf_filler/pdf_db_mapper.rb
|
44
|
+
- lib/pdf_filler/util_methods.rb
|
45
|
+
- spec/lib/pdf_book_spec.rb
|
46
|
+
- spec/lib/pdf_db_mapper_spec.rb
|
47
|
+
- spec/lib/pdf_page_spec.rb
|
48
|
+
- spec/spec_helper.rb
|
49
|
+
- spec/templates/certificate_template.pdf
|
50
|
+
- tasks/build_gem.rake
|
51
|
+
- tasks/documentation.rake
|
52
|
+
has_rdoc: false
|
53
|
+
homepage: http://wiki.github.com/renorb/pdf_filler
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options:
|
56
|
+
- --charset=UTF-8
|
57
|
+
- --title
|
58
|
+
- pdf_filler
|
59
|
+
- --main
|
60
|
+
- README.rdoc
|
61
|
+
- --line-numbers
|
62
|
+
- --inline-source
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "0"
|
76
|
+
version:
|
77
|
+
requirements: []
|
78
|
+
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 1.2.0
|
81
|
+
signing_key:
|
82
|
+
specification_version: 3
|
83
|
+
summary: A Rails plugin to fill a PDF form using RJB and iText.
|
84
|
+
test_files:
|
85
|
+
- spec/lib/pdf_page_spec.rb
|
86
|
+
- spec/lib/pdf_book_spec.rb
|