Hi all,
First off, I just want to thank the authors/contributers of iText for
a great (and free!) PDF generation library.
I'm working on a Ruby on Rails reporting project with a requirement to
generate PDF versions of our reports. Below is a sample of ruby code
which illustrates iText functionality such as page footers via events
and templates, buffered table creation (for very large datasets), and
generally how to use the Ruby Java Bridge (RJB).
I hope this helps others with similar projects.
Cheers,
Mike
=====================================================
#!/usr/bin/env ruby
#
# NOTES:
# - because we import com.lowagie.text.pdf.ColumnText, we need to be
explicit about PdfPTable.addCell() calls,
# hence the _invoke you'll see later
# - the 'headless' jvm argument is specific to OS X. if we don't
specify this argument,
# we can't include any java.awt.* classes
require 'rubygems'
require 'rjb'
Rjb::load(classpath='iText-2.1.3.jar', jvmargs=['-
Djava.awt.headless=true'])
# import Java classes
FileOutputStream = Rjb::import('java.io.FileOutputStream')
Color = Rjb::import('java.awt.Color')
Element = Rjb::import('com.lowagie.text.Element')
Document = Rjb::import('com.lowagie.text.Document')
Font = Rjb::import('com.lowagie.text.Font')
FontFactory = Rjb::import('com.lowagie.text.FontFactory')
PageSize = Rjb::import('com.lowagie.text.PageSize')
Paragraph = Rjb::import('com.lowagie.text.Paragraph')
Phrase = Rjb::import('com.lowagie.text.Phrase')
BaseFont = Rjb::import('com.lowagie.text.pdf.BaseFont')
ColumnText = Rjb::import('com.lowagie.text.pdf.ColumnText')
PdfPageEvent = Rjb::import('com.lowagie.text.pdf.PdfPageEvent')
PdfPCell = Rjb::import('com.lowagie.text.pdf.PdfPCell')
PdfContentByte = Rjb::import('com.lowagie.text.pdf.PdfContentByte')
PdfPTable = Rjb::import('com.lowagie.text.pdf.PdfPTable')
PdfWriter = Rjb::import('com.lowagie.text.pdf.PdfWriter')
# some constants
WidthForTotalPageCount = 10
FooterDistanceFromBottom = 26
TotalFakeRows = 100
NumBufferedRows = 20
# we'll bind this ruby class to the Java interface 'PdfPageEvent'
# apparently, we don't need to define all methods of the interface?!
class PdfPageFooter
attr_accessor :total_pages_template, :font_page_footer
def onEndPage(writer, document)
writer_direct_content = writer.getDirectContent()
page_size = document.getPageSize()
# add "page x of" text
page_x_text = ColumnText.new(writer_direct_content)
page_x_text.setSimpleColumn(
Phrase.new("page "+document.getPageNumber().to_s+" of ",
font_page_footer),
page_size.getRight(document.rightMargin()) - 200 -
WidthForTotalPageCount,
0,
page_size.getRight(document.rightMargin()) -
WidthForTotalPageCount,
FooterDistanceFromBottom,
0, Element.ALIGN_RIGHT
)
page_x_text.go()
# add template for total pages which gets set at the very end
writer_direct_content.addTemplate(
total_pages_template,
page_size.getRight(document.rightMargin()) -
WidthForTotalPageCount,
0 # notice that we set the y value here to 0 because this
template contains a ColumnText instance whose height already
incorporates 'FooterDistanceFromBottom'
)
end
end
# init Document, PDFWriter, and PdfPageFooter
document = Document.new(PageSize.A4.rotate())
pdf_writer = PdfWriter.getInstance(document,
FileOutputStream.new("test_table.pdf"))
pdf_page_footer = PdfPageFooter.new
pdf_writer.setPageEvent(Rjb::bind(pdf_page_footer,
'com.lowagie.text.pdf.PdfPageEvent'));
document.open
# create template for total page count
total_pages_template =
pdf_writer.getDirectContent().createTemplate(100, 100);
pdf_page_footer.total_pages_template = total_pages_template
# fonts used
font_title = FontFactory.getFont("Lucida Sans", 14, Font.BOLD,
Color.BLACK)
font_table_heading = FontFactory.getFont("Lucida Sans", 9, Font.BOLD,
Color.BLACK)
font_table_cell = FontFactory.getFont("Lucida Sans", 8, Color.BLACK)
font_page_footer = FontFactory.getFont("Courier", 7, Color.BLACK)
pdf_page_footer.font_page_footer = font_page_footer
# report title
document.add(Paragraph.new('Super Awesome Table', font_title))
# init table
table = PdfPTable.new(2) # 2 columns
table.setWidthPercentage(100)
# table header row
table.setHeaderRows(1)
table._invoke('addCell', 'Lcom.lowagie.text.pdf.PdfPCell;',
PdfPCell.new(Paragraph.new("Header 1", font_table_heading)))
table._invoke('addCell', 'Lcom.lowagie.text.pdf.PdfPCell;',
PdfPCell.new(Paragraph.new("Header 2", font_table_heading)))
table.setComplete(false)
# add data rows
TotalFakeRows.times do |i|
document.add(table) if ((i + 1) % NumBufferedRows == 0)
table._invoke('addCell', 'Lcom.lowagie.text.pdf.PdfPCell;',
PdfPCell.new(Paragraph.new("row #{i} cell 1", font_table_cell)))
table._invoke('addCell', 'Lcom.lowagie.text.pdf.PdfPCell;',
PdfPCell.new(Paragraph.new("row #{i} cell 2", font_table_cell)))
end
table.setComplete(true)
document.add(table)
# populate total pages template
column_text = ColumnText.new(total_pages_template)
column_text.setSimpleColumn(Phrase.new(" " +
pdf_writer.getPageNumber().to_s, font_page_footer), 0, 0,
WidthForTotalPageCount, FooterDistanceFromBottom, 0, Element.ALIGN_LEFT)
column_text.go()
document.close
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
iText-questions mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/itext-questions
Buy the iText book: http://www.1t3xt.com/docs/book.php