Skip to content

Commit e5b8cd9

Browse files
committed
Merge pull request #8 from technicool/master
Version 0.6.0 - Adding PDF-417 barcodes & JRuby support
2 parents 730cd9b + 119f774 commit e5b8cd9

File tree

7 files changed

+185
-35
lines changed

7 files changed

+185
-35
lines changed

.gitignore

+7-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
.DS_Store
1+
.DS_Store
2+
3+
.idea
4+
5+
spec/coverage
6+
7+
spec/test_output.pdf

History.txt

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
== 0.6.0 2013-10-28
2+
* Adding PDF 417 Barcodes
3+
* Cleaning up some other changes since last official release of 0.3.3.
4+
* Checkboxes now work in JRuby (from https://github.com/paulschreiber/pdf-stamper/commit/e5098c670aa4b2b387c66411fa7b3f63c6511224)
5+
6+
17
== 0.3.3 2010-09-24
28
* iText downgraded to 4.2.0 due to license incompatibility
39

Manifest.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
History.txt
22
Manifest.txt
3-
README.rdoc
3+
README.md
44
Rakefile
55
ext/iText-4.2.0.jar
66
lib/pdf/stamper.rb

README.md

+16-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66

77
Fill out PDF forms (templates) using iText's PdfStamper.
88

9+
Features include:
10+
11+
* Text fields
12+
* Checkboxes
13+
* Circles, ellipses, rectangles
14+
* PDF-417 Barcodes
15+
16+
You have to use JRuby or RJB. You need Adobe LiveCycle Designer
17+
or Acrobat Professional to create the templates.
18+
919
## Example
1020
pdf = PDF::Stamper.new("my_template.pdf")
1121

@@ -17,7 +27,10 @@ Fill out PDF forms (templates) using iText's PdfStamper.
1727
pdf.ellipse(140, 380, 50, 13)
1828
pdf.rectangle(140, 380, 50, 13)
1929
pdf.circle(140, 380)
20-
30+
31+
# PDF-417 barcodes
32+
pdf.barcode("PDF417", "2d_barcode", "Barcode data...", AspectRatio: 0.5)
33+
2134
pdf.save_as "my_output.pdf"
2235

2336
Here is how you use it in Rails.
@@ -36,20 +49,20 @@ Here is how you use it in Rails.
3649

3750
## Code
3851

39-
4052
git clone http://github.com/jaywhy/pdf-stamper/
4153

4254
## Contributors
4355

4456
Paul Schreiber
4557
Joe Steele
4658
Ronny Hanssen
59+
Marshall Anschutz
4760

4861
## License
4962

5063
(The MIT License)
5164

52-
Copyright (c) 2007-2012 Jason Yates
65+
Copyright (c) 2007-2013 Jason Yates
5366

5467
Permission is hereby granted, free of charge, to any person obtaining
5568
a copy of this software and associated documentation files (the

lib/pdf/stamper.rb

+69-21
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,22 @@
44

55
require 'rbconfig'
66
require 'fileutils'
7-
require 'tmpdir'
7+
#require 'tmpdir'
8+
#require 'active_support/inflector/methods'
89

910
include FileUtils
1011

1112
if RUBY_PLATFORM =~ /java/ # ifdef to check if your using JRuby
12-
$:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..', 'ext'))
13-
require 'java'
14-
require 'iText-4.2.0.jar'
15-
16-
java_import 'java.io.FileOutputStream'
17-
java_import 'java.io.ByteArrayOutputStream'
18-
java_import 'com.lowagie.text.pdf.AcroFields'
19-
java_import 'com.lowagie.text.pdf.PdfReader'
20-
java_import 'com.lowagie.text.pdf.PdfStamper'
21-
java_import 'com.lowagie.text.Image'
22-
java_import 'com.lowagie.text.Rectangle'
23-
java_import 'com.lowagie.text.pdf.GrayColor'
13+
require 'pdf/stamper/jruby'
2414
else
2515
require 'pdf/stamper/rjb'
2616
end
2717

2818
module PDF
2919
class Stamper
30-
VERSION = "0.5"
20+
VERSION = "0.6.0"
21+
22+
3123
# PDF::Stamper provides an interface into iText's PdfStamper allowing for the
3224
# editing of existing PDFs as templates. PDF::Stamper is not a PDF generator,
3325
# it allows you to edit existing PDFs and use them as templates.
@@ -77,6 +69,32 @@ def image(key, image_path)
7769
cb.addImage(img)
7870
end
7971

72+
# PDF::Stamper allows setting metadata on the created PDF by passing
73+
# the parameters to the set_more_info function. Our implementation here
74+
# is slightly different from iText, in that we only receive a single key/value
75+
# pair at a time, instead of a Map<string,string> since that is slightly
76+
# more complex to bridge properly from ruby to java.
77+
#
78+
# Possible keys include "Creator". All values here are strings.
79+
#
80+
def set_metadata(key, value)
81+
params = java.util.HashMap.new()
82+
params.put(key.to_s, value)
83+
@stamp.setMoreInfo(params)
84+
end
85+
86+
# If you want to have iText reset some of the metadata, this function will
87+
# cause iText to use its default xml metadata.
88+
def reset_xmp_metadata()
89+
@stamp.setXmpMetadata("".to_java_bytes)
90+
end
91+
92+
# Set a textfield defined by key and text to value
93+
def text(key, value)
94+
@form.setField(key.to_s, value.to_s) # Value must be a string or itext will error.
95+
end
96+
97+
8098
# Takes the PDF output and sends as a string.
8199
#
82100
# Here is how to use it in rails:
@@ -92,15 +110,11 @@ def to_s
92110
String.from_java_bytes(@baos.toByteArray)
93111
end
94112

95-
# Set a textfield defined by key and text to value.
96-
def text(key, value)
97-
@form.setField(key.to_s, value.to_s) # Value must be a string or itext will error.
98-
end
99113

100114
# Set a checkbox to checked
101115
def checkbox(key)
102116
field_type = @form.getFieldType(key.to_s)
103-
return unless field_type == @acrofields.FIELD_TYPE_CHECKBOX
117+
return unless is_checkbox(field_type)
104118

105119
all_states = @form.getAppearanceStates(key.to_s)
106120
yes_state = all_states.reject{|x| x == "Off"}
@@ -112,7 +126,7 @@ def checkbox(key)
112126
# Get checkbox values
113127
def get_checkbox_values(key)
114128
field_type = @form.getFieldType(key.to_s)
115-
return unless field_type == @acrofields.FIELD_TYPE_CHECKBOX
129+
return unless is_checkbox(field_type)
116130

117131
@form.getAppearanceStates(key.to_s)
118132
end
@@ -128,8 +142,42 @@ def ellipse(x, y, width, height)
128142
def rectangle(x, y, width, height)
129143
@canvas.rectangle(x, y, width, height)
130144
end
145+
146+
# Example
147+
# barcode("PDF417", "2d_barcode", "Barcode data...", AspectRatio: 0.5)
148+
def barcode(format, key, value, opts = {})
149+
bar = create_barcode(format)
150+
bar.setText(value)
151+
opts.each do |name, opt|
152+
#bar.send("set#{name.to_s.camelize}", opt) #Camelize is not present outside of Rails by default
153+
bar.send("set#{name.to_s}", opt)
154+
end
155+
156+
coords = @form.getFieldPositions(key.to_s)
157+
rect = create_rectangle(coords)
158+
159+
barcode_img = bar.getImage
160+
barcode_img.scalePercent(100, 100 * bar.getYHeight)
161+
barcode_img.setAbsolutePosition(
162+
coords[1] + (rect.getWidth - barcode_img.getScaledWidth) / 2,
163+
coords[2] + (rect.getHeight - barcode_img.getScaledHeight) / 2
164+
)
165+
166+
cb = @stamp.getOverContent(coords[0].to_i)
167+
cb.addImage(barcode_img)
168+
end
169+
170+
# this has to be called *before* setting field values
171+
def set_font(font_name)
172+
itr = @form.getFields.keySet.iterator
173+
while itr.hasNext
174+
field = itr.next
175+
@form.setFieldProperty(field, 'textfont', create_font(font_name), nil)
176+
end
177+
end
131178

132-
# Saves the PDF into a file defined by path given.
179+
# Saves the PDF into a file defined by path given. If you want to save
180+
# to a string/buffer, just use .to_s directly.
133181
def save_as(file)
134182
File.open(file, "wb") { |f| f.write to_s }
135183
end

lib/pdf/stamper/jruby.rb

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# = pdf/stamper/rjb.rb -- PDF template stamping.
2+
#
3+
# Copyright (c) 2007-2009 Jason Yates
4+
5+
$:.unshift(File.join(File.dirname(__FILE__), '..', '..', '..', 'ext'))
6+
require 'java'
7+
require 'iText-4.2.0.jar'
8+
9+
java_import 'java.io.FileOutputStream'
10+
java_import 'java.io.ByteArrayOutputStream'
11+
java_import 'com.lowagie.text.pdf.AcroFields'
12+
java_import 'com.lowagie.text.pdf.PdfReader'
13+
java_import 'com.lowagie.text.pdf.PdfStamper'
14+
java_import 'com.lowagie.text.Image'
15+
java_import 'com.lowagie.text.Rectangle'
16+
java_import 'com.lowagie.text.pdf.GrayColor'
17+
18+
module PDF
19+
include_package 'com.lowagie.text.pdf'
20+
21+
class Stamper
22+
def initialize(pdf = nil)
23+
template(pdf) if ! pdf.nil?
24+
end
25+
26+
def template(template)
27+
# NOTE I'd rather use a ByteArrayOutputStream. However I
28+
# couldn't get it working. Patches welcome.
29+
#@tmp_path = File.join(Dir::tmpdir, 'pdf-stamper-' + rand(10000).to_s + '.pdf')
30+
@reader = PDF::PdfReader.new(template)
31+
@baos = ByteArrayOutputStream.new
32+
@stamp = PDF::PdfStamper.new(@reader, @baos)#FileOutputStream.new(@tmp_path))
33+
@form = @stamp.getAcroFields()
34+
@black = GrayColor.new(0.0)
35+
@canvas = @stamp.getOverContent(1)
36+
end
37+
38+
def is_checkbox(field_type)
39+
field_type == AcroFields::FIELD_TYPE_CHECKBOX
40+
end
41+
42+
# Set a button field defined by key and replaces with an image.
43+
def image(key, image_path)
44+
# Idea from here http://itext.ugent.be/library/question.php?id=31
45+
# Thanks Bruno for letting me know about it.
46+
img = Image.getInstance(image_path)
47+
img_field = @form.getFieldPositions(key.to_s)
48+
49+
rect = Rectangle.new(img_field[1], img_field[2], img_field[3], img_field[4])
50+
img.scaleToFit(rect.width, rect.height)
51+
img.setAbsolutePosition(
52+
img_field[1] + (rect.width - img.scaledWidth) / 2,
53+
img_field[2] + (rect.height - img.scaledHeight) /2
54+
)
55+
56+
cb = @stamp.getOverContent(img_field[0].to_i)
57+
cb.addImage(img)
58+
end
59+
60+
def create_barcode(format)
61+
PDF.const_get("Barcode#{format}").new
62+
end
63+
64+
def create_rectangle(coords)
65+
Rectangle.new(coords[1], coords[2], coords[3], coords[4])
66+
end
67+
68+
def create_font(font_name)
69+
BaseFont.createFont(font_name, BaseFont.CP1252, false)
70+
end
71+
72+
# Takes the PDF output and sends as a string. Basically it's sole
73+
# purpose is to be used with send_data in rails.
74+
def to_s
75+
fill
76+
String.from_java_bytes(@baos.toByteArray)
77+
end
78+
end
79+
end

pdf-stamper.gemspec

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
Gem::Specification.new do |s|
22
s.name = %q{pdf-stamper}
3-
s.version = "0.3.3"
3+
s.version = "0.6.0"
44

55
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6-
s.authors = ["Jason Yates"]
7-
s.date = %q{2010-09-24}
8-
s.description = %q{Fill out PDF forms (templates) using iText's PdfStamper. == EXAMPLE: pdf = PDF::Stamper.new("my_template.pdf") pdf.text :first_name, "Jason" pdf.text :last_name, "Yates" pdf.image :photo, "photo.jpg" pdf.checkbox :hungry pdf.save_as "my_output.pdf"}
6+
s.authors = ["Jason Yates", "Marshall Anschutz"]
7+
s.date = %q{2013-10-28}
8+
s.description = %q{Fill out PDF forms (templates) using iText's PdfStamper.}
99
s.email = %q{jaywhy@gmail.com}
10-
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc"]
11-
s.files = ["History.txt", "Manifest.txt", "README.rdoc", "Rakefile", "ext/iText-4.2.0.jar", "lib/pdf/stamper.rb", "lib/pdf/stamper/jruby.rb", "lib/pdf/stamper/rjb.rb", "spec/logo.gif", "spec/pdf_stamper_spec.rb", "spec/test_template.pdf"]
12-
s.has_rdoc = true
13-
s.homepage = %q{http://github.com/paulschreiber/pdf-stamper/}
14-
s.rdoc_options = ["--main", "README.rdoc"]
10+
s.extra_rdoc_files = ["History.txt", "Manifest.txt"]
11+
s.files = ["History.txt", "Manifest.txt", "README.md", "Rakefile", "ext/iText-4.2.0.jar", "lib/pdf/stamper.rb", "lib/pdf/stamper/jruby.rb", "lib/pdf/stamper/rjb.rb", "spec/logo.gif", "spec/pdf_stamper_spec.rb", "spec/test_template.pdf"]
12+
s.homepage = %q{http://github.com/jaywhy/pdf-stamper/}
1513
s.require_paths = ["lib", "ext"]
1614
s.rubyforge_project = %q{pdf-stamper}
1715
s.rubygems_version = %q{1.3.1}

0 commit comments

Comments
 (0)