- Create a "reports" directory inside your app directory.
- Add it to your Rails load path by adding this inside the Rails::Initializer.run block in your environment.rb:
config.load_paths += %W( #{RAILS_ROOT}/app/reports )
- For the next step, we assume to have class that looks something like this:
class MyReport < ActiveRecord::Base validates_presence_of :report_title, :report_subtitle # ColumnHeader has an attribute "name" has_many :column_headers # We assume they come in the right order, and a row has_many columns. # A Column has an attribute "value" has_many :rows end
So we see our report can have n rows with n columns and two attributes: "report_title" and "report_subtitle". - Create a file called "my_report_renderer.rb" in your app/reports directory.
- Put this in the file:
require 'ruport' class MyReportRenderer < Ruport::Controller stage :report_header, :report_body finalize :report class PDF < Ruport::Formatter::PDF renders :pdf, :for => MyReportRenderer def build_report_header # data is an instance of your MyReport class add_text "My Great Report", :font_size => 20, :justification => :center add_text data.report_title, :font_size => 18 add_text data.report_subtitle, :font_size => 16 end def build_report_body # we have to build the table headers = [] # gather the column header strings in an array data.column_headers.each do |ch| headers << ch.name end table = Table(headers) do |t| data.rows.each do |row| columns = [] # gather the actual column values for each row in an array row.columns.each do |col| columns << col.value end # add the columns for the current row to the table t << columns end end # create column option that right justify all columns but the first one col_opts = {} header_index = 0 for header_index in (0..(headers.length - 1)) # we'll skip the first one, since :left is the default if header_index != 0 # the options for each column are indexed by it's name (headers array) col_opts[headers[header_index]] = {:justification => :right} end end pad (20) { draw_table(table, :column_options => col_opts) } end def finalize_report render_pdf end end end
OK, now we have a renderer (or controller) that renders our report with all columns right-justified except for the first one. - Now just add an action to your MyReport Rails controller:
def download_pdf begin @report = MyReport.find(params[:id]) send_data(MyReportRenderer.render(:pdf, :data => @report), :filename => "report#{params[:id]}.pdf", :type => "application/pdf", :disposition => 'inline') rescue ActiveRecord::RecordNotFound flash[:error] = "Report not found." redirect_to :action => :index end end
- That's it.
If this was useful for you, please take a minute and recommend me: Thank you!