Javaで帳票作成(JasperReports)サマリー&コンパイル済みファイルを使用 | Hello, Stupid World!

Hello, Stupid World!

いろいろとメモ代わりに書いていきます。

JasperReportsを色々といじってみましたが、機能も多く紹介しきれないので
今回で終わりにしようと思います。

最後なので、割と本格的なものを作ってみました。



こんな感じのよくありそうな納品書です。
実際に動かすとこんな感じで出力されます。



明細行のサマリー(合計)もしっかりと出力されています。
この作り方を紹介します。

1.合計行の出力はGroupというものを作る必要があります。
iReportの左にある「Report Inspector」のトップレベルの項目を右クリックし
「Add Report Group」を選択します。



するとウィザード画面が表示されます。



「Group name」に適当なグループ名を入れ
「Group by the following report object」に何を基準にグループ化するかを
指定します。
ここではcompanyNameという項目毎にグループを作る事にしました。
グループ化の基準が複雑な式となる場合は「Group by the following expression」
を指定し、式を入力します。

「次へ」のボタンを押すと以下の画面に移ります。



ここではヘッター(header)とフッター(footer)の使う方をチェックします。
両方を使う場合は両方にチェックして下さい。
こうする事で「Report Inspector」とデザイナー画面にGroup Headerや
Group Footerが追加されます。

2.次にこの合計行に使う値を変数(Variable)として用意します。
「Report Inspector」の「Variables」を右クリックして追加します。
その後、適宜プロパテイを指定します。



合計行用なので「Calculation」には「Sum」を指定します。
また、出力したい項目は金額ですがわざわざ金額はBean内に
用意していないので、計算して出しています。
計算式の単価(deliveryUnitPrice)×数量(deliveryNumber)を
「Variable Expression」に指定します。

なお、このようにiReportではパラメータなどを直接出すだけでなく
様々な編集をして出力する事が可能です。

今回ので言うと右上の日付は「Text Field Expression」という項目に
「new Date()」とする事でシステム日付を常に出しています。
他にも住所の項目を決まった文字数で折り返せるように
substring(指定文字数を抽出)しています。
Javaの命令などで細かく値の編集が行えます。



「Pattern」の項目は出力形式を設定します。
数値でカンマ区切りとしたり、日付の書式設定をしたり。

ここまでで合計行ができたら、今まで同様にJavaを使って出力します。

今まではJava実行時にコンパイルを毎回行っていましたが、コンパイルは
時間がかかる為、iReportでコンパイルを行いJavaからはコンパイル済みの
ものを使用するようにしてみました。

コンパイルはiReportの「Designer」ビューにあるトンカチみたいなアイコンを
押すだけです。



このコンパイルで作られた拡張子がjasperのファイルを使います。

では、Javaのソースです。

[ソース]
public static void main(String[] args) {

 // ソースファイルのパス
 String sourcePath = "C:/Work/report2.jasper";
 try {
  //パラメータの生成
  List<ReportBean> fields = new ArrayList<ReportBean>();
  ReportBean row_1 = new ReportBean();
  row_1.setCompanyName("TRAP商事");
  row_1.setCompanyPerson("TRAP");
  row_1.setCompanyTelNo("090-1111-1111");

  row_1.setCustomerName("○○電気");
  row_1.setCustomerZipCode("143-0000");
  row_1.setCustomerAddress("東京都○○区○○○町1-1-1マンション○○○301号室");

  row_1.setDeliveryName("○○半導体");
  row_1.setDeliveryTypeName("FA-B10D05-CSO101B");
  row_1.setDeliveryNumber(50);
  row_1.setDeliveryUnitPrice(3150);
  fields.add(row_1);

  ReportBean row_2 = new ReportBean();
  PropertyUtils.copyProperties(row_2, row_1);
  row_2.setDeliveryName("××半導体");
  row_2.setDeliveryTypeName("FA-B10D05-CSO103B");
  row_2.setDeliveryNumber(75);
  row_2.setDeliveryUnitPrice(2400);
  fields.add(row_2);

  // データの動的バインド
  JasperPrint print = JasperFillManager.fillReport(sourcePath, null, new JRBeanCollectionDataSource(fields));

  // プリンターへ出力
  PrintServiceAttributeSet atts = new HashPrintServiceAttributeSet();

  atts.add(new PrinterName("Microsoft XPS Document Writer",Locale.getDefault()));

  JRExporter exporter = new JRPrintServiceExporter();
  exporter.setParameter(JRExporterParameter.JASPER_PRINT, print);

exporter.setParameter(JRPrintServiceExporterParameter.PRINT_SERVICE_ATTRIBUTE_SET, atts);
  exporter.exportReport();
 } catch (Exception ex) {
  ex.printStackTrace();
 }
}

[解説]
見てのとおり、前回までとほとんど同じです。
違いはコンパイルのメソッド(
JasperCompileManager.compileReport)を使わなくて
良くなったのとテンプレートファイルXML(拡張子がjrxml)のファイルの代わりに
コンパイル済みテンプレートファイル(拡張子jasper)を指定してるだけ。

あと、jasperReportsは関係ないですがApache Commonsの
PropertyUtils.copyPropertiesでBean間のコピーをしてます。
Commonsは便利ですよね。
今後、紹介していこうと思ってます。