millisami-pdf-stamper 0.0.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.
- data/lib/pdf/stamper.rb +104 -0
- data/lib/pdf/stamper/rjb.rb +108 -0
- data/spec/pdf_stamper_spec.rb +21 -0
- metadata +65 -0
data/lib/pdf/stamper.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# = pdf/stamper.rb -- PDF template stamping.
|
2
|
+
#
|
3
|
+
# Copyright (c) 2007 Jason Yates
|
4
|
+
|
5
|
+
require 'fileutils'
|
6
|
+
require 'java'
|
7
|
+
require 'tmpdir'
|
8
|
+
|
9
|
+
include FileUtils
|
10
|
+
|
11
|
+
include_class 'java.io.FileOutputStream'
|
12
|
+
include_class 'java.io.ByteArrayOutputStream'
|
13
|
+
include_class 'com.lowagie.text.pdf.AcroFields'
|
14
|
+
include_class 'com.lowagie.text.pdf.PdfReader'
|
15
|
+
include_class 'com.lowagie.text.pdf.PdfStamper'
|
16
|
+
include_class 'com.lowagie.text.Image'
|
17
|
+
include_class 'com.lowagie.text.Rectangle'
|
18
|
+
|
19
|
+
# PDF::Stamper provides an interface into iText's PdfStamper allowing for
|
20
|
+
# the editing of existing PDF's as templates. Unlike the available PDF
|
21
|
+
# generators, PDF::Stamper, via RJB and iText, allows you to edit
|
22
|
+
# existing PDF's and use them as templates.
|
23
|
+
#
|
24
|
+
# == Creation of templates
|
25
|
+
#
|
26
|
+
# Templates currently can only be created using Adobe LiveCycle
|
27
|
+
# Designer which comes with the lastest versions of Adobe Acrobat
|
28
|
+
# Professional. Using LiveCycle Designer you can create a form and
|
29
|
+
# add textfield's for text and button's for images.
|
30
|
+
#
|
31
|
+
module PDF
|
32
|
+
# PDF::Stamper
|
33
|
+
#
|
34
|
+
# == Example
|
35
|
+
#
|
36
|
+
# pdf = PDF::Stamper.new("my_template.pdf")
|
37
|
+
# pdf.text :first_name, "Jason"
|
38
|
+
# pdf.text :last_name, "Yates"
|
39
|
+
# pdf.image :photo, "photo.jpg"
|
40
|
+
# pdf.save_as "my_output"
|
41
|
+
class Stamper
|
42
|
+
|
43
|
+
def initialize(pdf = nil)
|
44
|
+
template(pdf) if ! pdf.nil?
|
45
|
+
end
|
46
|
+
|
47
|
+
def template(template)
|
48
|
+
# NOTE I'd rather use a ByteArrayOutputStream. However I
|
49
|
+
# couldn't get it working. Patches welcome.
|
50
|
+
#@tmp_path = File.join(Dir::tmpdir, 'pdf-stamper-' + rand(10000).to_s + '.pdf')
|
51
|
+
reader = PdfReader.new(template)
|
52
|
+
@baos = ByteArrayOutputStream.new
|
53
|
+
@stamp = PdfStamper.new(reader, @baos)#FileOutputStream.new(@tmp_path))
|
54
|
+
@form = @stamp.getAcroFields()
|
55
|
+
end
|
56
|
+
|
57
|
+
# Set a textfield defined by key and text to value.
|
58
|
+
def text(key, value)
|
59
|
+
@form.setField(key.to_s, value.to_s) # Value must be a string or itext will error.
|
60
|
+
end
|
61
|
+
|
62
|
+
# Set a button field defined by key and replaces with an image.
|
63
|
+
def image(key, image_path)
|
64
|
+
# Idea from here http://itext.ugent.be/library/question.php?id=31
|
65
|
+
# Thanks Bruno for letting me know about it.
|
66
|
+
img = Image.getInstance(image_path)
|
67
|
+
img_field = @form.getFieldPositions(key.to_s)
|
68
|
+
|
69
|
+
rect = Rectangle.new(img_field[1], img_field[2], img_field[3], img_field[4])
|
70
|
+
img.scaleToFit(rect.width, rect.height)
|
71
|
+
img.setAbsolutePosition(
|
72
|
+
img_field[1] + (rect.width - img.scaledWidth) / 2,
|
73
|
+
img_field[2] + (rect.height - img.scaledHeight) /2
|
74
|
+
)
|
75
|
+
|
76
|
+
cb = @stamp.getOverContent(img_field[0].to_i)
|
77
|
+
cb.addImage(img)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Takes the PDF output and sends as a string. Basically it's sole
|
81
|
+
# purpose is to be used with send_data in rails.
|
82
|
+
def to_s
|
83
|
+
fill
|
84
|
+
String.from_java_bytes(@baos.toByteArray)
|
85
|
+
#File.open(@tmp_path).read
|
86
|
+
end
|
87
|
+
|
88
|
+
# Saves the PDF into a file defined by path given.
|
89
|
+
def save_as(file)
|
90
|
+
f = File.new(file, "w")
|
91
|
+
f.syswrite to_s
|
92
|
+
#fill
|
93
|
+
#mv(@tmp_path, file) # NOTE what if someone tries to duplicate the file by saving twice?
|
94
|
+
#@tmp_path = file # Just in case you decide to do "to_s" also.
|
95
|
+
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def fill
|
100
|
+
@stamp.setFormFlattening(true)
|
101
|
+
@stamp.close
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# = pdf/stamper.rb -- PDF template stamping.
|
2
|
+
#
|
3
|
+
# Copyright (c) 2007 Jason Yates
|
4
|
+
|
5
|
+
require 'fileutils'
|
6
|
+
require 'rubygems'
|
7
|
+
require 'rjb'
|
8
|
+
require 'tmpdir'
|
9
|
+
|
10
|
+
include FileUtils
|
11
|
+
|
12
|
+
Rjb::load(File.join(File.dirname(__FILE__), '..', '..', '..', 'ext', 'itext-2.0.6.jar'))
|
13
|
+
|
14
|
+
# PDF::Stamper provides an interface into iText's PdfStamper allowing for
|
15
|
+
# the editing of existing PDF's as templates. Unlike the available PDF
|
16
|
+
# generators, PDF::Stamper, via RJB and iText, allows you to edit
|
17
|
+
# existing PDF's and use them as templates.
|
18
|
+
#
|
19
|
+
# == Creation of templates
|
20
|
+
#
|
21
|
+
# Templates currently can only be created using Adobe LiveCycle
|
22
|
+
# Designer which comes with the lastest versions of Adobe Acrobat
|
23
|
+
# Professional. Using LiveCycle Designer you can create a form and
|
24
|
+
# add textfield's for text and button's for images.
|
25
|
+
#
|
26
|
+
# == Caveats
|
27
|
+
#
|
28
|
+
# RJB needs the LD_LIBRARY_PATH and JAVA_HOME environment set for it
|
29
|
+
# to work correctly. For example on my system:
|
30
|
+
#
|
31
|
+
# export LD_LIBRARY_PATH=/usr/java/jdk1.6.0/jre/lib/i386/:/usr/java/jdk1.6.0/jre/lib/i386/client/:./
|
32
|
+
# export JAVA_HOME=/usr/java/jdk1.6.0/
|
33
|
+
#
|
34
|
+
# Check the RJB documentation if you are having issues with this.
|
35
|
+
module PDF
|
36
|
+
# PDF::Stamper
|
37
|
+
#
|
38
|
+
# == Example
|
39
|
+
#
|
40
|
+
# pdf = PDF::Stamper.new("my_template.pdf")
|
41
|
+
# pdf.text :first_name, "Jason"
|
42
|
+
# pdf.text :last_name, "Yates"
|
43
|
+
# pdf.image :photo, "photo.jpg"
|
44
|
+
# pdf.save_as "my_output"
|
45
|
+
class Stamper
|
46
|
+
def initialize(pdf = nil, options = {})
|
47
|
+
@bytearray = Rjb::import('java.io.ByteArrayOutputStream')
|
48
|
+
@filestream = Rjb::import('java.io.FileOutputStream')
|
49
|
+
@acrofields = Rjb::import('com.lowagie.text.pdf.AcroFields')
|
50
|
+
@pdfreader = Rjb::import('com.lowagie.text.pdf.PdfReader')
|
51
|
+
@pdfstamper = Rjb::import('com.lowagie.text.pdf.PdfStamper')
|
52
|
+
|
53
|
+
template(pdf) if ! pdf.nil?
|
54
|
+
end
|
55
|
+
|
56
|
+
def template(template)
|
57
|
+
reader = @pdfreader.new(template)
|
58
|
+
@baos = @bytearray.new
|
59
|
+
@stamp = @pdfstamper.new(reader, @baos)
|
60
|
+
@form = @stamp.getAcroFields()
|
61
|
+
end
|
62
|
+
|
63
|
+
# Set a textfield defined by key and text to value.
|
64
|
+
def text(key, value)
|
65
|
+
@form.setField(key.to_s, value.to_s) # Value must be a string or itext will error.
|
66
|
+
end
|
67
|
+
|
68
|
+
# Set a button field defined by key and replaces with an image.
|
69
|
+
def image(key, image_path)
|
70
|
+
# Idea from here http://itext.ugent.be/library/question.php?id=31
|
71
|
+
# Thanks Bruno for letting me know about it.
|
72
|
+
image = Rjb::import('com.lowagie.text.Image')
|
73
|
+
img = image.getInstance(image_path)
|
74
|
+
img_field = @form.getFieldPositions(key.to_s)
|
75
|
+
|
76
|
+
rectangle = Rjb::import('com.lowagie.text.Rectangle')
|
77
|
+
rect = rectangle.new(img_field[1], img_field[2], img_field[3], img_field[4])
|
78
|
+
img.scaleToFit(rect.width, rect.height)
|
79
|
+
img.setAbsolutePosition(
|
80
|
+
img_field[1] + (rect.width - img.scaledWidth) / 2,
|
81
|
+
img_field[2] + (rect.height - img.scaledHeight) /2
|
82
|
+
)
|
83
|
+
|
84
|
+
cb = @stamp.getOverContent(img_field[0].to_i)
|
85
|
+
cb.addImage(img)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Takes the PDF output and sends as a string. Basically it's sole
|
89
|
+
# purpose is to be used with send_data in rails.
|
90
|
+
def to_s
|
91
|
+
fill
|
92
|
+
@baos.toByteArray
|
93
|
+
end
|
94
|
+
|
95
|
+
# Saves the PDF into a file defined by path given.
|
96
|
+
def save_as(file)
|
97
|
+
f = File.new(file, "w")
|
98
|
+
f.syswrite to_s
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
|
103
|
+
def fill
|
104
|
+
@stamp.setFormFlattening(true)
|
105
|
+
@stamp.close
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
require 'pdf/stamper'
|
3
|
+
|
4
|
+
describe PDF::Stamper do
|
5
|
+
before(:each) do
|
6
|
+
@pdf = PDF::Stamper.new(File.join(File.dirname(__FILE__), "test_template.pdf"))
|
7
|
+
@pdf.text :text_field01, "test"
|
8
|
+
@pdf.text :text_field02, "test2"
|
9
|
+
@pdf.image :button_field01, File.join(File.dirname(__FILE__), "logo.gif")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should create PDF document" do
|
13
|
+
@pdf.to_s.should_not be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should save PDF document" do
|
17
|
+
@pdf.save_as "test_output.pdf"
|
18
|
+
File.exist?("test_output.pdf").should be_true
|
19
|
+
#File.delete("test_output.pdf") # Comment this out to view the output
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: millisami-pdf-stamper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Millisami
|
8
|
+
- Jason Yates
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2009-02-05 00:00:00 -08:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: rjb
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.0.4
|
24
|
+
version:
|
25
|
+
description: PDF::Stamper provides an interface into iText's PdfStamper allowing for the editing of existing PDF's as templates.
|
26
|
+
email: millisami@gmail.com
|
27
|
+
executables: []
|
28
|
+
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files: []
|
32
|
+
|
33
|
+
files:
|
34
|
+
- lib/pdf/stamper/rjb.rb
|
35
|
+
- lib/pdf/stamper.rb
|
36
|
+
- spec/pdf_stamper_spec.rb
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: http://github.com/millisami/pdf-stamper
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options:
|
41
|
+
- --inline-source
|
42
|
+
- --charset=UTF-8
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 1.2.0
|
61
|
+
signing_key:
|
62
|
+
specification_version: 2
|
63
|
+
summary: PDF::Stamper provides an interface into iText's PdfStamper allowing for the editing of existing PDF's as templates.
|
64
|
+
test_files:
|
65
|
+
- spec/pdf_stamper_spec.rb
|