読者です 読者をやめる 読者になる 読者になる

railsで帳票を出力するもう一つの方法 hashed-jasper-railsを作りました

ruby rails

rubyで帳票を出力するならThinReportsでキマリです。railsならthinreports-railsね。
ただ、ThinReportsは多段のグループヘッダ/フッタを設定することができなかったり、細かい設定はちょっと苦手な感じを受けました。
以前Javaのプロジェクトで触ったJasperReportsの感触が良かったのでRubyから何とか使えないかと調べてみたところjasper-railsというものを発見。JRubyではなくRjbを使ってjvmを操作するようです。

問題点

jasper-railsは概ね良い感じなんですが次の点が気になってきます。

  • Controllerに関連するViewのテンプレートしか使えない

コレはコレで良い仕様だとは思うのですがテンプレートを一箇所に集約して、いろんなControllerから使いたい場合は不便です。好きな場所に置きたい!

内部でActiveRecord::Relation#to_xmlしてるみたいで単一のモデル情報しか渡せないみたいです。テーブルをJoinした結果をhashに入れて渡したい!

作ってみた

jasper-railsをラップしてhashed-jasper-railsというものを作ってみました。実は今年の春頃に作ってたんですがイマイチ納得出来ない作りだったのでアナウンスを控えていました。さて、詳しく使い方を説明しますね。

iReportの準備

iReportはJasperReportsで使うための帳票テンプレートをデザインするツールです。
次のURLからダウンロードして設定しましょう。
http://community.jaspersoft.com/project/ireport-designer

次に日本語を使うためにiTextAsian.jarをダウンロードします。
http://itextpdf.sourceforge.net
iTextAsian.jarはClasspathに追加しておきましょう。
Macであればダウンロードしたファイルは/Library/Java/Extensionsにコピーしておけばよいでしょう。

iReportでiTextAsian.jarを読み込みます。
メニューのiReport -> 環境設定 -> Classpathタブとたどって先ほどのiTextAsian.jarを追加しましょう。これで日本語が使えるようになります。

iReportでデザイン

iReport自体の使い方はググればたくさん出てきます。ここでは注意点だけ。

  • 全体のプロパティのQuery Textは/モデル名複数形/モデル名単数形とする。例えばSaleモデルのインスタンスであれば/sales/saleとなる。
  • The language for the dataset queryはxPathとする。
  • 日本語フォントを使用する項目は次のように設定する。

Pdf Font name はHeiseiKakuGo-W5もしくはHeiseiMin-W3を指定。
Pdf EncodingはUniJIS-UCS2-Hとする。

jasper-railsの使い方

hashed-jasper-railsはjasper-railsの機能を全て使うことができます。
ここでは売上情報が設定されたSaleモデルが存在しており、views/salesにreport.jrxmlというコンパイル済みテンプレートファイルが置かれているものとします。

Gemfile

RailsプロジェクトのGemfileに次の1行を追加してbundle updateして下さい。

gem 'hashed-jasper-rails'
Controller

次の設定を行なって下さい。

class SalesController < ApplicationController
  respond_to :html, :xml, :pdf

  def report
    sales = Sale.all
    respond_with sales
  end

  (略)
end

http://localhost:3000/sales/report.pdf
をWebブラウザで叩くとpdfが取得できるはずです。良い感じですね。

hashed-jasper-railsの使い方

datasourceをhashで渡してみる

まずはテンプレートのQuery Textを/jasper/recordに設定して下さい。この値はオプションで変更することができます。
actionは次のように設定できます。

def report
  sales = [
      {:name => "Izumi Konata", :amount => 10_000},
      {:name => "Hiiragi Tsukasa", :amount => 20_000},
      {:name => "Hiiragi Kagami", :amount => 30_000}
  ]
  jasper_pdf :resource => sales
end

http://localhost:3000/sales/report
をWebブラウザで叩くとpdfが取得できるはずです。respond_withを使ってないのでURIの最後の拡張子は不要であることに注意して下さい。

テンプレートを指定してみる

:templateオプションでviews以下のpathを指定することもできます。

jasper_pdf :resource => sales, :template => "sales/list"

まとめ

既存の機能を生かしつつラップするのに苦労しました。Railsで複雑な帳票を出力するときに使ってみて下さい。