lib/combine_pdf.rb in combine_pdf-0.1.1 vs lib/combine_pdf.rb in combine_pdf-0.1.2
- old
+ new
@@ -182,9 +182,117 @@
# if the page is PDFWriter object as a stamp, the final size will be that of the original page.
def create_page(mediabox = [0.0, 0.0, 612.0, 792.0])
PDFWriter.new mediabox
end
+ # makes a PDF object containing a table
+ #
+ # all the pages in this PDF object are PDFWriter objects and are
+ # writable using the texbox function (should you wish to add a title, or more info)
+ #
+ # the main intended use of this method is to create indexes (a table of contents) for merged data.
+ #
+ # example:
+ # pdf = CombinePDF.new_table headers: ["header 1", "another header"], table_data: [ ["this is one row", "with two columns"] , ["this is another row", "also two columns", "the third will be ignored"] ]
+ # pdf.save "table_file.pdf"
+ #
+ # accepts a Hash with any of the following keys as well as any of the PDFWriter#textbox options:
+ # headers:: an Array of strings with the headers (will be repeated every page).
+ # table_data:: as Array of Arrays, each containing a string for each column. the first row sets the number of columns. extra columns will be ignored.
+ # font:: a registered or standard font name (see PDFWriter). defaults to nil (:Helvetica).
+ # header_font:: a registered or standard font name for the headers (see PDFWriter). defaults to nil (the font for all the table rows).
+ # max_font_size:: the maximum font size. if the string doesn't fit, it will be resized. defaults to 14.
+ # column_widths:: an array of relative column widths ([1,2] will display only the first two columns, the second twice as big as the first). defaults to nil (even widths).
+ # header_color:: the header color. defaults to [0.8, 0.8, 0.8] (light gray).
+ # main_color:: main row color. defaults to nil (transparent / white).
+ # alternate_color: alternate row color. defaults to [0.95, 0.95, 0.95] (very light gray).
+ # font_color: font color. defaults to [0,0,0] (black).
+ # border_color: border color. defaults to [0,0,0] (black).
+ # border_width: border width in PDF units. defaults to 1.
+ # header_align: the header text alignment within each column (:right, :left, :center). defaults to :center.
+ # row_align:: the row text alignment within each column. defaults to :left (:right for RTL table).
+ # direction: the table's writing direction (:ltr or :rtl). this reffers to the direction of the columns and doesn't effect text (rtl text is automatically recognized). defaults to :ltr.
+ # rows_per_page: the number of rows per page, INCLUDING the header row. deafults to 25.
+ # page_size: the size of the page in PDF points. defaults to [0, 0, 595.3, 841.9] (A4).
+ def new_table (options = {})
+ defaults = {
+ headers: nil,
+ table_data: [[]],
+ font: nil,
+ header_font: nil,
+ max_font_size: 14,
+ column_widths: nil,
+ header_color: [0.8, 0.8, 0.8],
+ main_color: nil,
+ alternate_color: [0.95, 0.95, 0.95],
+ font_color: [0,0,0],
+ border_color: [0,0,0],
+ border_width: 1,
+ header_align: :center,
+ row_align: nil,
+ direction: :ltr,
+ rows_per_page: 25,
+ page_size: [0, 0, 595.3, 841.9] #A4
+ }
+ options = defaults.merge options
+ options[:header_font] = options[:font] unless options[:header_font]
+ options[:row_align] ||= ( (options[:direction] == :rtl) ? :right : :left )
+ # assert table_data is an array of arrays
+ return false unless (options[:table_data].select {|r| !r.is_a?(Array) }).empty?
+ # compute sizes
+ page_size = options[:page_size]
+ top = page_size[3] * 0.9
+ height = page_size[3] * 0.8 / options[:rows_per_page]
+ from_side = page_size[2] * 0.1
+ width = page_size[2] * 0.8
+ columns = options[:table_data][0].length
+ column_widths = []
+ columns.times {|i| column_widths << (width/columns) }
+ if options[:column_widths]
+ scale = 0
+ options[:column_widths].each {|w| scale += w}
+ column_widths = []
+ options[:column_widths].each { |w| column_widths << (width*w/scale) }
+ end
+ column_widths = column_widths.reverse if options[:direction] == :rtl
+ # set pdf object and start writing the data
+ table = PDF.new()
+ page = nil
+ rows_per_page = options[:rows_per_page]
+ row_number = rows_per_page + 1
+
+ options[:table_data].each do |row_data|
+ if row_number > rows_per_page
+ page = create_page page_size
+ table << page
+ row_number = 1
+ # add headers
+ if options[:headers]
+ x = from_side
+ headers = options[:headers]
+ headers = headers.reverse if options[:direction] == :rtl
+ column_widths.each_index do |i|
+ text = headers[i].to_s
+ page.textbox text, {x: x, y: (top - (height*row_number)), width: column_widths[i], height: height, box_color: options[:header_color], text_align: options[:header_align] }.merge(options).merge({font: options[:header_font]})
+ x += column_widths[i]
+ end
+ row_number += 1
+ end
+ end
+ x = from_side
+ row_data = row_data.reverse if options[:direction] == :rtl
+ column_widths.each_index do |i|
+ text = row_data[i].to_s
+ box_color = options[:main_color]
+ box_color = options[:alternate_color] if options[:alternate_color] && row_number.odd?
+ page.textbox text, {x: x, y: (top - (height*row_number)), width: column_widths[i], height: height, box_color: box_color, text_align: options[:row_align]}.merge(options)
+ x += column_widths[i]
+ end
+ row_number += 1
+ end
+ table
+ end
+
# adds a correctly formatted font object to the font library.
#
# registered fonts will remain in the library and will only be embeded in
# PDF objects when they are used by PDFWriter objects (for example, for numbering pages).
#