Rapport allows you to create tabular reports with a DSL, which can be outputted via customizable formatters.
Include the Rapport::Report module in any object to allow it to generate reports in the pre-built formatters (csv, fake) or in a custom formatter. Use an easy DSL to write all your reports once, and all your formats once, and then mix and match as you please.
require 'rubygems'
require 'rapport'
class OrderReport
include Rapport::Report
def initialize(options)
self.options = options
end
# Add columns to the report with column(column_header, *args)
# Column Header is what appears in the report, and *args specify how to calculate the values using the model
#
# examples:
# column('column header')
# column('column header', :column_symbol)
# column('column header', :model_type => :column_symbol, ...)
#
# All equivalent:
# column 'Product ID', :map_to => lambda {|model| !model.nil? and model.respond_to?(:product_id) ? model.product_id : nil }
# column 'Product ID', :map_to => :product_id
# column 'Product ID', :product_id
column 'Product ID' # by default converts 'Product ID' to :product_id
# special calculation depending on type of model
column 'Price', :additional_charge => :amount,
:line_item => :price, # not required; defaults to :price
:special_line_item => lambda {|line_item| line_item.price - line_item.tax },
# Display price (in cents) as dollars
:format => :cents
# Navigate an object heirarchy using :through
column 'Order ID', :through -> :order, :map_to => :id
column 'Customer Name', :through => [:order, :customer], :map_to => lambda {|customer| "#{customer.first_name} #{customer.last_name}" }
# Implement each_model to specify which models belong to the report.
# The method should yield each model, and optionally specify the model type in order to customize how the value is calculated.
def each_model
AdditionalCharge.in_order_report.each do |additional_charge|
yield additional_charge # equivalent to yield additional_charge, :additional_charge
end
LineItem.in_order_report.each do |line_item|
if line_item.special?
yield line_item, :special_line_item # uses special price calculation above
else
yield line_item # equivalent to yield line_item, :line_item
end
end
end
end
order_report = OrderReport.new(:format => 'csv', :output_dir => 'my_dir')
order_report.generate # generates a csv file named 'my_dir/OrderReport_{timestamp}.csv
order_report = OrderReport.new(:format => 'my_custom')
order_report.generate # generates the same report, but in your custom format
module Rapport
class ReportGeneratorMyCustom
include ReportGenerator
generate_with do |report|
File.open(output_filename,'w') do |file|
file.puts(report.column_headers.join('|'))
report.each_row do |row|
file.puts(row.join('|'))
end
end
end
end
end
Copyright (c) 2011 Andrew Wheeler. See LICENSE.txt for further details.