開發環境
OS:WindowsXP
Ruby:Ruby1.8.7
Rails:Rails2.3.5
Mysql:Mysql5.0.9
IDE:Rubymine2.0.1
準備工作:
安裝以下gem包
gem install ruport
gem install ruport-util
gem install acts_as_reportable
本例設計的報表系統工作原理(純屬個人理解),以Products表為例:
接下來實現的例子將利用eval方法實現動態指令碼,對可能變動的地方通過資料庫儲存運行時代碼片斷
一、建立報表運行時需要的資料表
主鍵自動成長
create table report_definitions</p><p>(report_definition_id integer not null,</p><p>report_code varchar(30),</p><p>report_name varchar(240),</p><p>report_sql varchar(4000),</p><p>basic_model varchar(20),</p><p>primary key ('report_definition_id'));</p><p>create table report_templates</p><p>(report_template_id integer not null,</p><p>template_code varchar(30),</p><p>template_name varchar(240),</p><p>template_content varchar(4000),</p><p>template_type varchar(10),</p><p>primary key ('report_template_id'));</p><p>create table report_executions</p><p>(report_execute_id integer not null,</p><p>execute_code varchar(30),</p><p>execute_name varchar(240),</p><p>report_definition_id int not null,</p><p>report_template_id int not null</p><p>primary key ('report_execute_id'));</p><p>create table products</p><p>(product_id int not null,</p><p> title varchar(100),</p><p> description varchar(100),</p><p> price int,</p><p> primary key('product_id'));</p><p>
二、在RubyMine中利用Scaffold方法產生資料表對應的檔案(包括Model,View,Controller等)
三、修改envrioment.rb
在末尾添加
require "rubygems"
require "ruport"
四、修改Products.rb
在其中添加
acts_as_reportable
使其能使用acts_as_reportable中提供的方法
五、建立ReportOuptController,代碼如下:
class ReportOutputController< Ruport::Controller<br /> #Code here<br /> stage :data_sheet<br /> def setup<br /> puts "basic_model= #{options[:basicModel]}"<br /> self.data = eval(options[:basicModel]).report_table_by_sql(options[:sql])<br /> end<br />end<br />class ReportHtml < Ruport::Formatter::PDF<br /> renders :pdf, :for => ReportOutputController<br /> build :data_sheet do<br /> eval(options[:outputContent])<br /> end<br />end</p><p> class ReportPdf < Ruport::Formatter::HTML<br /> renders :html, :for => ReportOutputController<br /> build :data_sheet do<br /> eval(options[:outputContent])<br /> end<br /> end</p><p> class ReportCsv < Ruport::Formatter::CSV<br /> renders :csv, :for => ReportOutputController<br /> build :data_sheet do<br /> eval(options[:outputContent])<br /> #output << data.to_csv<br /> end<br /> end
六、修改ReportExecutionsController,添加output_report方法及:simple模板
Ruport::Formatter::Template.create(:simple) do |format|<br /> eval("format.page = {:layout => :landscape}<br /> format.grouping = {:style => :separated}<br /> format.text = {:font_size => 20,:justification => :center}<br /> format.table = {:font_size => 10,:heading_font_size => 10,:maximum_width => 720,:width => 720}<br /> format.column = {:alignment => :center}<br /> format.heading = {:alignment => :center,:bold => true,:font_size=>10}")<br /> end</p><p> def output_report<br /> #puts "Execute Code = #{params[:report_execute_code]}"<br /> report_execution = ReportExecution.find_by_execute_code(params[:report_execute_code])<br /> report_definition = ReportDefinition.find(report_execution.report_definition_id)<br /> report_template = ReportTemplate.find(report_execution.report_template_id)<br /> puts "=============Output Parameters========================"<br /> puts "execute_code = #{params[:report_execute_code]}"<br /> puts "report_name = #{report_definition.report_name}"<br /> puts "template_name = #{report_template.template_name}, template_type= #{report_template.template_type}"<br /> puts "======================================================"<br /> outputFile = ReportOutputController.render(eval(":"+report_template.template_type),:sql=>report_definition.report_sql,<br /> :outputContent=>report_template.template_content,<br /> :basicModel=>report_definition.basic_model,<br /> :template=>:simple)<br /> send_data outputFile,:type => "application/"+report_template.template_type,:filename => "reportExecution."+report_template.template_type<br /> end
七、在routes.rb中註冊output_report方法
map.resources :report_executions,:collection => { :output_report => :get }
八、修改reoprt_executions/index.html.erb,添加如下代碼
<h2>Ouput Report</h2><br /><%form_tag({:action=>'output_report' }) do%><br /> 報表執行編碼:<%= text_field_tag :report_execute_code,params[:report_execute_code],:size=>20 %><br /> <%= submit_tag "Print"%><br /><%end%>
九、準備資料庫資料
INSERT INTO report_definitions VALUES ('1', 'Product List', 'PRODUCT_LIST', 'SELECT t.title,t.price,t.description type FROM products t', 'Product');</p><p>INSERT INTO report_templates VALUES ('1', 'Product Template', 'PRODUCT_TEMPLATE', 'pad(10) { add_text /'Products/' }/r/ndraw_table data ', 'pdf');</p><p>INSERT INTO report_executions VALUES ('2', 'Product Report', 'CUXPRORT', '1', '1');<br />
示範效果:http://localhost:3000/report_executions
(註:eval方法可實現動態指令碼的運行,請參考http://ruby-doc.org/core/classes/Kernel.html#M005922)