Importing multiple pdf pages and documents into PDFlib - Part 2
This is a followup to my first post about importing multiple pages into PDFlib .
I have created a class that will allow you to import multi page PDF’s as well as importing multiple PDF documents into one generated PDF. It will also fill all of your PDFlib text blocks with the data you provide:
Please post any questions or comments about it.
Here’s the class on pastie: http://pastie.caboo.se/14052
Here’s the code:
# — HERE’S HOW TO USE THIS CLASS
# Created by Nate Constant, http://shabadeehoob.com . Please contact me if you need help using it
=begin
1. open your PDF doc in Acrobat Standard (or Pro).
2. using the PDFlib block tool draw your text blocks in your pdf where you want them
a. if you are drawing blocks for checkboxes make sure to set the font to “ZapfDingbats” —IMPORTANT: dont use “Zapf Dingbats” <- see the space in there?
b. if you are drawing blocks that are supposed to circle something (i.e. “circle your answer”) make sure to set the font size to something large to make the circle
3. use the “Save As” to save your pdf into the directory you want (probably the directory in your rails app because you can access it via #{RAILS_ROOT})
4. in this class go to the “fill_app” method and set your “searchpath”. this is the path for your pdf doc in your rails app
5. point your browser to the generate_pdf action and let er rip!
=end
end
Update: Tony Buser has modified this code by making it into a hash object. View it here
Importing multiple pages into PDFLib
So, as I’ve stated before, I’m creating an application that imports a large PDF into PDFlib so that i can populate textfields on each page from a database table.
PDFlib essentially imports one page at a time to work with. So here’s code to import a multipage PDF and populate the fields for each page.
def populate_pdf
#setup some defaults
infile = "alaska_pdflib.pdf"
searchpath = "../state_doc_originals"
#this data should pull from a database, the keys of the hash must be the same as the block names on the pdf
data = {
"last_name" => "Constant",
"first_name" => "Nate",
"middle_name" => "Andrew",
"dob_m" => "09",
"dob_y"=>"1980",
"dob_d" => "18",
"city_of_birth" => "Omaha",
"state_of_birth" => "Nebraska",
"gender_male" => "8"
}
p = PDFlib.new
if (p.begin_document("", "compatibility = 1.6") == -1)
logger.info "Error: " + p.get_errmsg()
end
# Set the search path for fonts and PDF files
p.set_parameter("SearchPath", searchpath)
p.set_parameter("pdiwarning", "true")
p.set_info("Creator", "businesscard.rb")
p.set_info("Author", "QuickDocData")
p.set_info("Title", "Alaska State License Application")
#open the document
blockcontainer = p.open_pdi(infile, "", 0)
if (blockcontainer == -1)
logger.info "Error: " + p.get_errmsg()
end
regularfont = p.load_font("Arial", "winansi", "")
checkbox_font = p.load_font("ZapfDingbats","builtin","")
#loop through all pages and put data in the blocks
number_of_pages = p.get_pdi_value("/Root/Pages/Count",blockcontainer,-1,0)
1.upto(number_of_pages){|page_num|
#get current page
page = p.open_pdi_page(blockcontainer, page_num, "")
if (page == -1)
logger.info "Error: " + p.get_errmsg()
end
#get all blocks for the page and put them in an array to use later
num_of_blocks_on_page = p.get_pdi_value("vdp/blockcount",blockcontainer,page,0)
cur_blocks = Array.new
0.upto(num_of_blocks_on_page-1){ |i|
cur_blocks.push( p.get_pdi_parameter("vdp/Blocks[#{i}]/Name", blockcontainer, page, 0))
#logger.info p.get_pdi_parameter("vdp/Blocks[#{i}]/Name", blockcontainer, page, 0)
}
#set page size
p.begin_page_ext(595, 842, "topdown")
# This will adjust the page size to the block container's size.
p.fit_pdi_page(page, 0, 842, "")
# Fill all text blocks with dynamic data
cur_blocks.each { |key, value|
use_font = p.get_pdi_parameter("vdp/Blocks/#{key}/fontname", blockcontainer, page, 0)
if use_font == "ZapfDingbats"#is this block a checkbox?
font_string = "font #{checkbox_font.to_s} embedding encoding=builtin"
else
font_string ="font #{regularfont.to_s} embedding encoding=winansi"
end
if (p.fill_textblock(page, key, data[key].to_s,font_string) == -1)
logger.info "Warning: " + p.get_errmsg
end
}
p.end_page_ext("")
p.close_pdi_page(page)
}#end looping through all of the pages
p.close_pdi(blockcontainer)
p.end_document("")
p.get_buffer()
end
Installation of PDFLib on Rails
On a large project I’m working on we need to be able to import a (rather large) PDF and populate it’s fields from a database table, essentially. I looked into a few options like the built-in Ruby PDF generator PDF::Writer. PDF::Writer is good for generating PDF’s but not so good with importing existing documents for manipulation. Enter PDFLib. Unfortunately PDFLib is fairly expensive but it has everything I’m looking for. Probably one of the greatest features is it comes with a PDFLib Block Tool which allows you to add textfields anywhere on a PDF to be populated at a later time.
One nice thing about PDFLib is (for Ruby on Rails) you can install it into the plugins folder. This makes it so much easier than worrying about installing a package on your server, especially if your hosting your site on a shared environment (like Dreamhost).
I’m a fairly newer Ruby on Rails programmer and haven’t used plugins very much so I thought it would be tough to install. This proved not the case. Here’s the simple instructions:
1. Download the Ruby bindings from the PDFLib site depending on which system you’re using.
2. Extract the compressed file
3. Place the pdflib library file into your Rails App’s plugins vendor folder. On Mac OSX the library file is pdflib.library, on Linux the library file is pdflib.so.
If you’re like me, you do development on your local Mac system and upload the site to your host, which is a Linux/Apache server. In this case make sure to put the pdflib.so library file in the Rails app which is on the server and the pdflib.library file in the Rails app on your local machine.
That’s it!
Now that the library is installed, you can test the examples that come with pdflib and start to build your own PDF application.
Recently
- 08.24 Setting up flash messages in Zend Framework
- 09.08 CakePHP default dateTime()
- 03.24 Extending CakePHP’s beforeFilter()
- 03.17 Rails-like Flash messages in CakePHP
- 03.08 CakePHP thumbnails with phpThumb
- 02.15 CakePHP model validation
- 02.10 CakePHP - saving dates in your model
- 09.19 Importing multiple pdf pages and documents into PDFlib - Part 2
- 09.18 Quick Link - Every CSS based layout you could want
- 09.04 Mongrel pid error fixed
