ScriptDataSourceを試してみる

せっかくid:kiy0takaに教えてもらったので、BIRTの帳票をScriptベースのデータソース&データセット
表示する方法も試してみました。


まず、レポートの設定は以下のような感じ。


1. レポートを作成。
2. データソースを作成。データソースは「スクリプト記述済みのデータ・ソース」を指定。
3. データセットを作成。データソースは、2.で作成したものを指定。
  また、データセットの編集⇒出力列指定で出力したい列を作成。(※ここでは、仮にtest_codeとtest_nameを作成したこととする)
4. 画面にデータセットのカラムを配置。
  プロパティーエディターデータ⇒バインディングタブ内で3.で作成したデータセットを対応付ける。
  ※なんかよくわからないが、知らぬ間に画面に配置したテーブルとデータセットの関係がずれる場合がある?
   多分色々名称を変更したりして試していた時におかしくなっただけかな?
5. スクリプト⇒fetchのタイミングで以下のようなデータ代入処理を記述。
  ※フェッチ時は真偽値を戻り値で返さないといけない点に注意が必要。


// DB(DAO)からの戻りはListの形式で受け取っている前提。そのIteratorをレポートのスクリプト側で利用する
if (dataIterator.hasNext()) { // dataIterator(※出力対象データ)はレポートの実行エンジン側から受け取る
data = dataIterator.next();
dataSetRow["test_code"] = data.getTestCode(); // Dtoの値を4.で配置したコンポーネントの式に代入
dataSetRow["test_name"] = data.getTestName();
return true; // まだ続きのデータがある場合は真
} else {
return false; // すべてのデータを処理し終えたら偽
}
6. スクリプト⇒closeのタイミングで以下のような終了処理を記述。

dataIterator = null
  海外のサイトを見るとよく書いてあるんだけど…今ひとつ必要な理由がわからないな。。


続いてレポートへコードを渡す側は以下のような感じ。

EngineConfig config = new EngineConfig();
config.setEngineHome(レポートエンジンのパス);

ReportEngine engine = new ReportEngine(config);
IReportRunnable design = engine.openReportDesign(レポートデザインファイルへのパス);

// タスク生成
IRunAndRenderTask task = engine.createRunAndRenderTask(design);

// 内部にListを持っているオブジェクト(ダミー)を生成
TestDataSource dataSource = new TestDataSource();

// コンテキストに表示するオブジェクトを設定(※この辺りの指定方法が旧バージョンと変わっている - BIRT2.5で動作確認)
Map paramMap = task.getAppContext();
paramMap.put("dataIterator", dataSource.getDataList().iterator()); // スクリプト内で利用する変数を登録
task.setAppContext(paramMap); // なくても動きそう(笑)なコードだが、書かないとエラーになる

IRenderOption options = new RenderOption();
options.setOutputFormat("pdf");
options.setOutputFileName("E:/test.pdf");
task.setRenderOption(options);

task.run();

作ってみた感想としては、やっぱりこっちのほうがスマート。
パフォーマンス的にも優秀だろうし。
というより、今日開発現場でフィルタを動的に設定する方式を試してみたが、「SQLの結果列」に対してフィルタリングするため、
SQL内で日付なんかをフォーマットしていたりすると比較することができず、問題外な感じになってしまった。。


結局、この方式で落ち着きそうです。
id:kiy0taka、thanks!