RailsからJasperReportsを利用するための設定

  1. jaspertest/app以下に次のディレクトリを作成、ライブラリや作成したファイルを置く
    • app/jasper
    • app/jasper/bin
    • app/jasper/lib
    • app/reports

app/jasper/bin
jasperreport_on_rails.tar.gzをダウンロードして解凍して出来るbinディレクトリ内のXmlJasperInterface.classをコピーして設置

app/jasper/lib
iReportを解凍したディレクトリ内のlibディレクトリ内の全てのJARファイルを置く
いるものの所で挙げた「iTextAsian.jar」もこのディレクトリに入れる

app/reports
前の工程で生成された「custrep.jasper」ファイルをを設置

  1. HowTowに載っているコードを同じように追加
  • app/controllers/application.rbの中に以下の内容をコピー&ペースト
class Document
  include Config
  def self.generate_report(xml_data, report_design, output_type, select_criteria)
    report_design << '.jasper' if !report_design.match(/\.jasper$/)
    interface_classpath=Dir.getwd+"/app/jasper/bin" 
    case CONFIG['host']
      when /mswin32/
        mode = "w+b" #windows requires binary mode
        Dir.foreach(Dir.getwd+"/app/jasper/lib") do |file|
          interface_classpath << ";#{Dir.getwd}/app/jasper/lib/"+file if (file != '.' and file != '..' and file.match(/.jar/))
        end
      else
        mode = "w+" 
        Dir.foreach(Dir.getwd+"/app/jasper/lib") do |file|
          interface_classpath << ":#{Dir.getwd}/app/jasper/lib/"+file if (file != '.' and file != '..' and file.match(/.jar/))
        end
    end
        result=nil
        IO.popen "java -Djava.awt.headless=true -cp \"#{interface_classpath}\" XmlJasperInterface -o#{output_type} -f#{Dir.getwd}/app/reports/#{report_design} -x#{select_criteria}", mode do |pipe|
            pipe.write xml_data
            pipe.close_write
            result = pipe.read
            pipe.close
        end
    return result
  end
end

このクラスはJavaのプロセスを起動しXmlJasperInterface.classを実行する。
このクラスを実行するときにcustomre_listアクションで生成されたXMLのデータを引き渡し、
PDFへ変換してもらう。

  • app/helpersに「send_doc_helper.rb」ファイルを作成し、次の内容をコピー&ペースト
module SendDocHelper
  protected
  def cache_hack
    if request.env['HTTP_USER_AGENT'] =~ /msie/i
      headers['Pragma'] = ''
      headers['Cache-Control'] = ''
    else
      headers['Pragma'] = 'no-cache'
      headers['Cache-Control'] = 'no-cache, must-revalidate'
    end
  end

  def send_doc(xml, xml_start_path, report, filename, output_type = 'pdf')
    case output_type
    when 'rtf'
      extension = 'rtf'
      mime_type = 'application/rtf'
      jasper_type = 'rtf'
    else # pdf
      extension = 'pdf'
      mime_type = 'application/pdf'
      jasper_type = 'pdf'
    end

    cache_hack
    send_data Document.generate_report(xml, report, jasper_type, xml_start_path),
        :filename => "#{filename}.#{extension}", :type => mime_type, :disposition => 'inline'
  end
end

このクラスのsend_docメソッドでは、一つ前に作成したDocumentクラスを呼びだし、
取得したデータ(PDFかRTF形式のデータ)をレスポンスとして返す処理が書かれている。

  • app/controllers/accounting_controller.rbに以下の宣言を追加(2009/02/20 追記)
class AccountingController < ApplicationController
  # ↓この2行を追加
  helper :send_doc
  include SendDocHelper
  • app/controllers/accounting_controller.rbに以下のメソッドを追加
   def customer_report
      @customers=Customer.find(:all)
      send_doc(
            render_to_string(:template => 'accounting/customer_list', :layout => false),
            '/customer_list_result/invoice_customers/customer', 
            'custrep',
            'CustomerReport', 
            'pdf')
   end

このメソッドで指定している内容

    • :template => 'accounting/customer_list': app/views/accounting/customer_list.rxml
    • /customer_list_result/invoice_customers/customer: iReportで使われるXPath(なんだろ)
    • custrep: app/jasper内にある.jasperファイルの名前
    • CustomerReport: ダウンロードしたときのファイル名
    • pdf: PDFで出力するように指定

以上で設定完了。