Class: Ruport::Formatter::PDF
- Inherits:
-
Ruport::Formatter
- Object
- Ruport::Formatter
- Ruport::Formatter::PDF
- Includes:
- DrawingHelpers
- Defined in:
- lib/ruport/formatter/pdf.rb
Overview
This class provides PDF output for Ruport's Table, Group, and Grouping controllers. It wraps Austin Ziegler's PDF::Writer to provide a higher level interface and provides a number of helpers designed to make generating PDF reports much easier. You will typically want to build subclasses of this formatter to customize it as needed.
Many methods forward options to PDF::Writer, so you may wish to consult its API docs.
Rendering Options
General:
* paper_size #=> "LETTER"
* paper_orientation #=> :portrait
Text:
* text_format (sets options to be passed to add_text by default)
Table:
* table_format (a hash that can take any of the options available
to PDF::SimpleTable)
* table_format[:maximum_width] #=> 500
Grouping:
* style (:inline,:justified,:separated,:offset)
Defined Under Namespace
Modules: DrawingHelpers, PDFWriterProxy
Instance Attribute Summary (collapse)
-
- (Object) pdf_writer
Returns the current PDF::Writer object or creates a new one if it has not been set yet.
Attributes inherited from Ruport::Formatter
Class Method Summary (collapse)
-
+ (Object) proxy_to_pdf_writer
If you use this macro in your formatter, Ruport will automatically forward calls to the underlying PDF::Writer, for any methods that are not wrapped or redefined.
Instance Method Summary (collapse)
-
- (Object) add_text(text, format_opts = {})
Call PDF::Writer#text with the given arguments, using text_format defaults, if they are defined.
-
- (Object) apply_template
Hook for setting available options using a template.
-
- (Object) build_group_body
Renders the group as a table for Controller::Group.
-
- (Object) build_group_header
Generates a header with the group name for Controller::Group.
-
- (Object) build_grouping_body
Determines which style to use and renders the main body for Controller::Grouping.
-
- (Object) build_table_body
Calls the draw_table method.
-
- (Object) center_image_in_box(path, image_opts = {})
-
If the image is bigger than the box, it will be scaled down until.
-
-
- (Object) draw_table(table_data, format_opts = {})
Draws a PDF::SimpleTable using the given data (usually a Data::Table).
-
- (Object) finalize_grouping
Calls render_pdf.
-
- (Object) finalize_table
Appends the results of PDF::Writer#render to output for your pdf_writer object.
-
- (PDF) initialize
constructor
A new instance of PDF.
-
- (Object) move_cursor(n)
Adds n to pdf_writer.y, moving the vertical drawing position in the document.
-
- (Object) move_cursor_to(n)
Moves the cursor to a specific y coordinate in the document.
- - (Object) move_down(n)
-
- (Object) move_up(n)
Moves the vertical drawing position in the document upwards by n.
-
- (Object) pad(y, &block)
Adds a specified amount of whitespace above and below the code in your block.
-
- (Object) pad_bottom(y, &block)
Adds a specified amount of whitespace below the code in your block.
-
- (Object) pad_top(y, &block)
Adds a specified amount of whitespace above the code in your block.
-
- (Object) render_pdf
Calls PDF::Writer#render and appends to output.
-
- (Object) rounded_text_box(text) {|opts| ... }
Draws some text on the canvas, surrounded by a box with rounded corners.
Methods included from DrawingHelpers
#bottom_boundary, #cursor, #draw_text, #draw_text!, #finalize, #horizontal_line, #horizontal_rule, #left_boundary, #right_boundary, #top_boundary, #vertical_line_at
Methods inherited from Ruport::Formatter
build, #clear_output, #erb, formats, #method_missing, #output, renders, save_as_binary_file, #save_output, #template
Methods included from RenderingTools
#render_group, #render_grouping, #render_inline_grouping, #render_row, #render_table
Constructor Details
- (PDF) initialize
A new instance of PDF
65 66 67 68 69 70 |
# File 'lib/ruport/formatter/pdf.rb', line 65 def initialize Ruport.quiet do require "pdf/writer" require "pdf/simpletable" end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class Ruport::Formatter
Instance Attribute Details
- (Object) pdf_writer
Returns the current PDF::Writer object or creates a new one if it has not been set yet.
86 87 88 89 90 |
# File 'lib/ruport/formatter/pdf.rb', line 86 def pdf_writer @pdf_writer ||= .formatter || ::PDF::Writer.new( :paper => .paper_size || "LETTER", :orientation => .paper_orientation || :portrait) end |
Class Method Details
+ (Object) proxy_to_pdf_writer
If you use this macro in your formatter, Ruport will automatically forward calls to the underlying PDF::Writer, for any methods that are not wrapped or redefined.
59 60 61 |
# File 'lib/ruport/formatter/pdf.rb', line 59 def self.proxy_to_pdf_writer include PDFWriterProxy end |
Instance Method Details
- (Object) add_text(text, format_opts = {})
Call PDF::Writer#text with the given arguments, using text_format defaults, if they are defined.
Example:
options.text_format { :font_size => 14 }
add_text("Hello Joe") #renders at 14pt
add_text("Hello Mike",:font_size => 16) # renders at 16pt
145 146 147 148 |
# File 'lib/ruport/formatter/pdf.rb', line 145 def add_text(text, format_opts={}) format_opts = .text_format.merge(format_opts) if .text_format pdf_writer.text(text, format_opts) end |
- (Object) apply_template
Hook for setting available options using a template. See the template documentation for the available options and their format.
74 75 76 77 78 79 80 81 |
# File 'lib/ruport/formatter/pdf.rb', line 74 def apply_template apply_page_format_template(template.page) apply_text_format_template(template.text) apply_table_format_template(template.table) apply_column_format_template(template.column) apply_heading_format_template(template.heading) apply_grouping_format_template(template.grouping) end |
- (Object) build_group_body
Renders the group as a table for Controller::Group.
111 112 113 |
# File 'lib/ruport/formatter/pdf.rb', line 111 def build_group_body render_table data, .to_hash.merge(:formatter => pdf_writer) end |
- (Object) build_group_header
Generates a header with the group name for Controller::Group.
106 107 108 |
# File 'lib/ruport/formatter/pdf.rb', line 106 def build_group_header pad(10) { add_text data.name.to_s, :justification => :center } end |
- (Object) build_grouping_body
Determines which style to use and renders the main body for Controller::Grouping.
117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/ruport/formatter/pdf.rb', line 117 def build_grouping_body case .style when :inline render_inline_grouping(.to_hash.merge(:formatter => pdf_writer, :skip_finalize_table => true)) when :justified, :separated render_justified_or_separated_grouping when :offset render_offset_grouping else raise NotImplementedError, "Unknown style" end end |
- (Object) build_table_body
Calls the draw_table method.
94 95 96 |
# File 'lib/ruport/formatter/pdf.rb', line 94 def build_table_body draw_table(data) end |
- (Object) center_image_in_box(path, image_opts = {})
-
If the image is bigger than the box, it will be scaled down until it fits.
-
If the image is smaller than the box, it won't be resized.
options:
-
:x: left bound of box
-
:y: bottom bound of box
-
:width: width of box
-
:height: height of box
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/ruport/formatter/pdf.rb', line 165 def center_image_in_box(path, image_opts={}) x = image_opts[:x] y = image_opts[:y] width = image_opts[:width] height = image_opts[:height] info = ::PDF::Writer::Graphics::ImageInfo.new(File.open(path, "rb")) # reduce the size of the image until it fits into the requested box img_width, img_height = fit_image_in_box(info.width,width,info.height,height) # if the image is smaller than the box, calculate the white space buffer x, y = add_white_space(x,y,img_width,width,img_height,height) pdf_writer.add_image_from_file(path, x, y, img_width, img_height) end |
- (Object) draw_table(table_data, format_opts = {})
Draws a PDF::SimpleTable using the given data (usually a Data::Table). Takes all the options you can set on a PDF::SimpleTable object, see the PDF::Writer API docs for details, or check our quick reference at:
stonecode.svnrepository.com/ruport/trac.cgi/wiki/PdfWriterQuickRef
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 |
# File 'lib/ruport/formatter/pdf.rb', line 278 def draw_table(table_data, format_opts={}) m = "PDF Formatter requires column_names to be defined" raise FormatterError, m if table_data.column_names.empty? table_data.rename_columns { |c| c.to_s } if .table_format format_opts = Marshal.load(Marshal.dump(.table_format.merge(format_opts))) end old = pdf_writer.font_size ::PDF::SimpleTable.new do |table| table.maximum_width = 500 table.column_order = table_data.column_names table.data = table_data table.data = [{}] if table.data.empty? apply_pdf_table_column_opts(table,table_data,format_opts) format_opts.each {|k,v| table.send("#{k}=", v) } table.render_on(pdf_writer) end pdf_writer.font_size = old end |
- (Object) finalize_grouping
Calls render_pdf.
132 133 134 |
# File 'lib/ruport/formatter/pdf.rb', line 132 def finalize_grouping render_pdf end |
- (Object) finalize_table
Appends the results of PDF::Writer#render to output for your pdf_writer object.
101 102 103 |
# File 'lib/ruport/formatter/pdf.rb', line 101 def finalize_table render_pdf unless .skip_finalize_table end |
- (Object) move_cursor(n)
Adds n to pdf_writer.y, moving the vertical drawing position in the document.
223 224 225 |
# File 'lib/ruport/formatter/pdf.rb', line 223 def move_cursor(n) pdf_writer.y += n end |
- (Object) move_cursor_to(n)
Moves the cursor to a specific y coordinate in the document.
228 229 230 |
# File 'lib/ruport/formatter/pdf.rb', line 228 def move_cursor_to(n) pdf_writer.y = n end |
- (Object) move_down(n)
237 238 239 |
# File 'lib/ruport/formatter/pdf.rb', line 237 def move_down(n) pdf_writer.y -= n end |
- (Object) move_up(n)
Moves the vertical drawing position in the document upwards by n.
233 234 235 |
# File 'lib/ruport/formatter/pdf.rb', line 233 def move_up(n) pdf_writer.y += n end |
- (Object) pad(y, &block)
Adds a specified amount of whitespace above and below the code in your block. For example, if you want to surround the top and bottom of a line of text with 5 pixels of whitespace:
pad(5) { add_text "This will be padded top and bottom" }
246 247 248 249 250 |
# File 'lib/ruport/formatter/pdf.rb', line 246 def pad(y,&block) move_cursor(-y) block.call move_cursor(-y) end |
- (Object) pad_bottom(y, &block)
Adds a specified amount of whitespace below the code in your block. For example, if you want to add a 10 pixel buffer to the bottom of a line of text:
pad_bottom(10) { add_text "This will be padded on bottom" }
267 268 269 270 |
# File 'lib/ruport/formatter/pdf.rb', line 267 def pad_bottom(y,&block) block.call move_cursor(-y) end |
- (Object) pad_top(y, &block)
Adds a specified amount of whitespace above the code in your block. For example, if you want to add a 10 pixel buffer to the top of a line of text:
pad_top(10) { add_text "This will be padded on top" }
257 258 259 260 |
# File 'lib/ruport/formatter/pdf.rb', line 257 def pad_top(y,&block) move_cursor(-y) block.call end |
- (Object) render_pdf
Calls PDF::Writer#render and appends to output.
151 152 153 |
# File 'lib/ruport/formatter/pdf.rb', line 151 def render_pdf output << pdf_writer.render end |
- (Object) rounded_text_box(text) {|opts| ... }
Draws some text on the canvas, surrounded by a box with rounded corners.
Yields an OpenStruct which options can be defined on.
Example:
rounded_text_box(.text) do |o|
o.radius = 5
o.width = .width || 400
o.height = .height || 130
o.font_size = .font_size || 12
o.heading = .heading
o.x = pdf_writer.absolute_x_middle - o.width/2
o.y = 300
end
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/ruport/formatter/pdf.rb', line 199 def rounded_text_box(text) opts = OpenStruct.new yield(opts) resize_text_to_box(text, opts) pdf_writer.save_state draw_box(opts.x, opts.y, opts.width, opts.height, opts.radius, opts.fill_color, opts.stroke_color) add_text_with_bottom_border(opts.heading, opts.x, opts.y, opts.width, opts.font_size) if opts.heading pdf_writer.restore_state start_position = opts.heading ? opts.y - 20 : opts.y draw_text(text, :y => start_position, :left => opts.x, :right => opts.x + opts.width, :justification => opts.justification || :center, :font_size => opts.font_size) move_cursor_to(opts.y - opts.height) end |