Jasper Reports で PDF ファイル出力

ちょっと必要がありまして、Jasper Reports というオープンソースの帳票出力ライブラリで PDF の出力を行いました。 使い方を忘れてしまいそうなのでメモがてら。 初めて使うライブラリは勝手が分からずなかなか大変です。 🙂

Jasper Reports とその帳票設計を行う iReport というアプリです。

jasperforge JasperReports Project Home

JasperReports is the world’s most popular open source reporting engine. It is entierly written in Java and it is able to use data coming from any kind of data source and produce pixel-perfect documents that can be viewed, printed or exported in a variety of document formats including HTML, PDF, Excel, OpenOffice and Word.

jasperforge iReport Project Home

iReport is the free, open source report designer for JasperReports. Create very sophisticated layouts containing charts, images, subreports, crosstabs and much more. Access your data through JDBC, TableModels, JavaBeans, XML, Hibernate, CSV, and custom sources. Then publish your reports as PDF, RTF, XML, XLS, CSV, HTML, XHTML, text, DOCX, or OpenOffice.

Jasper Report は LGPL、iReport は AGPL です。 iReport のほうは NetBeans ベースでつくられているよう。 前者がライブラリで、後者がそのライブラリで読み込む GUI 帳票設計アプリケーションとなります。

とりあえず、ファイルをダウンロード。 以下二つを利用しました。 iReport のほうは、Linux、Mac OS X 版もあります。 Jasper Reports は pure java です。

jasperreports-3.7.1-project.tar.gz

iReport-3.7.1-windows-installer.exe

また、Jasper Reports の PDF 出力は iText PDF ライブラリに依存しています。 iText 自体は上記 project.tar.gz (のlib)に同梱されいますが、日本語の出力の際に必要な iTextAsian.jar が含まれていませんので以下からダウンロードします。(下の方です)

Browse iText, a JAVA-PDF library Files on SourceForge.net

extrajars  – ExtraJars1.0  – iTextAsian.jar

これでファイルの準備は完了。 iReport のほうは適当にセットアップしておきます。

Jasper Reports はいろいろなデータソースから帳票を出力できますが、今回は Java の Bean 経由で出力してみます。 DB に直つなぎとかもできるみたいですね。

最終的に Java からだすので、先にプログラムソースの準備を。

以下のようなモジュール構成にしておきます。 Jasper Reports の依存ライブラリがよく分かりませんでしたが、今回のプログラムで class not found がでなくなった最小構成としています。 また、先の iTextAsian.jar もいっしょに入れておきます。

Jasper01

templates フォルダには Jasper Repost の定義体を入れることにしましょう。

SampleReportBean.java が帳票に出力したいレコードを表現した Bean です。 Bean の内容は以下の通り。 getter、setter は省略。

   1: package net.maple4ever.jasper;
   2:  
   3: public class SampleReportBean {
   4:  
   5:     // メーカ
   6:     private String maker;
   7:     // 機種名
   8:     private String name;
   9:     // OS
  10:     private String os;
  11:     // CPU
  12:     private String cpu;
  13:     // メモリ容量
  14:     private String memory;
  15:     // ハードディスク容量
  16:     private String hdd;
  17:  
  18:     // 以下 getter/setter (省略)
  19: }

さてさて、ここから iReport の世界に入っていきます。 iReport 起動。

とりあえずオプション設定。 iTextAsian.jar と今ほどつくった Java プロジェクトに class path を通します。

 Jasper02

Eclipse で Java プロジェクトつくった場合は、プロジェクトロケーション/bin にします。(class ファイルできるところね) で、上のスクリーンショットでは忘れてしまっていますが、Relodable にチェックを入れます。 iTextAsian.jar にはチェックいらないでしょう。(Java プログラムを修正すると読み直してくれます)

了解おして、ここで iReport を一回再起動。(しないと iTextAsian が反映されませんでした)

でもってファイル –> NEW あたりから帳票新規作成。 ファイルの置き場所を先ほどの templates フォルダにします。 種類、ここでは A4 のブランクにしました。

Jasper03

Open this Template おして、

Jasper04 

みたいな感じです。

できたら、まずは帳票プロパティの Language を Java に変更します。 Groovy が標準のようですね。 これやらないと、後で Java から呼ぶときに groovy の class ないぞってエラーになります。

Jasper04-02

帳票設計画面はこんな感じです。

Jasper05

上から Title、Page Header、Column Header、Detail 1、Column Footer、Page Footer、Summary となっています。 この中で Detail の部分が繰り返しのデータをおくところになります。 ここが重要。

でもって、Title、Summary 部分が1ページと最終ページ。 Page/Column  Header、Footer が表ごとページごととなるようです。

ふまえて、レコードとなるさきほどの Bean を Detail 1 に配置していきます。 まずはデザイナ上部、Preview の横のデータベース矢印みたいなアイコンをクリックします。

Jasper05-02

さきほどつくった Bean のパッケージを入力して Read attributes を押下します。 さすると、Bean のプロパティがでてきます。 うまく読めないときは class path の設定を確認。

Jasper06

選択して Add Selected field(s) ボタンを押下します。 するとこのフィールドがデザイナ上で配置できるようになります。

画面左ツリーの Fields 木にいま追加したフィールド出現するので、ドラッグアンドドロップで Detail 1 に置いていきます。 罫線とか必要ならパレット開いて描画していきます。 static text とかでテーブルヘッダとかタイトルとかもつける。

日本語フォントは PDF Font name を「HeiseiKakuGo-W5」に、PDF Encording を「UniJIS-UCS2-H (Japanese)」にします。 こうしないと PDF になったときに日本語が出力されません。(Adobe Reader のフォント。ちょっと詳しくないですが、iTextAsian.jar の設定値なのかもしれません。 MSP ゴシックとかは設定できない模様)

まぁまぁこんな感じです。

 Jasper09

また繰り返しリストではなく、帳票全体でひとつの埋め込み項目は「パラメータ」として配置することができます。 左ツリーのparameter で追加して名前をつけて置いていきます。

Jasper08

でもって、なんとなくできたらデータを埋め込んでみます。 iReport には任意の Java を呼び出してその帰り値の Collection を埋め込んでくれる便利な機能がありました。(Biz Stream はこれできないよね?)

とりあえずさきほどの Java のプロジェクトに SampleReportFactory.java というソースを追加しました。 createBeanCollection という static なメソッドが標準で使われるようなのでこれも用意しておきます。 こんな感じです。

   1: public class SampleReportFactory {
   2:     
   3:     public static List<SampleReportBean> createBeanCollection() {
   4:         
   5:         List<SampleReportBean> lines =
   6:             new ArrayList<SampleReportBean>();
   7:         
   8:         for(int i=1; i<100;i++) {
   9:             SampleReportBean line = new SampleReportBean();
  10:             line.setName("自作機2号");
  11:             line.setMaker("ひろまさ");
  12:             line.setOs("Ubuntu 9.10");
  13:             line.setCpu("PhenomII X4");
  14:             line.setHdd("320GByte");
  15:             line.setMemory("4GByte");
  16:             line.setColor(String.valueOf(i % 2));
  17:             lines.add(line);
  18:         }
  19:         return lines;
  20:     }
  21: }

iReport に戻って画面上部のデータソースのアイコンを押下します。

Jasper05-01

JavaBeans set datasource を選択。

 Jasper10

でもっていまつくった SampleReportFactory を指定します。

Jasper11

Test おして OK もらったら Save します。

で、デザイナの Preview を押してみると帳票につくったデータソースがバインドされた結果が表示されます。 🙂

Jasper13

ソースコードから入力をつくれるので桁数試験とか結構便利です。

さてさて、ちゃんとした帳票だと罫線の制御とかしたくなることがあります。

ちょっとマニュアル調べて簡単そうだったのが各描画オブジェクトがもつ、Print When Express というプロパティ。 フィールドとかの値を判定して表示の可否をきめることができます。

たとえば、行をしましまにしたかったら Bean にそれっぽいフラグ項目をつくって、

Jasper14

こんな感じで Print When Expression を設定してあげると true のときだけ表示になります。(Jasper への戻値は、boolean じゃなくて Boolean のようなので注意してください)

というわけで灰色ざぶとんを行の下に敷いて、しましま。 とか。

Jasper15

他にも良い方法があるとは思うですが、これさえあればあとは組み合わせ、、知恵と勇気でなんでもいけるかと。。(笑)

では最後に Java から作った帳票をだしてみます。 iReport 終了。 iReport で保存・コンパイルされたものが templates フォルダに入っているはずです。

Jasper16 

.jasper がコンパイルされた結果です。 プログラムからはこちらを使います。(動的コンパイルもできるみたいですがここでは割愛)

面倒なので先ほどの SampleReportFactory クラスに main を追加する感じで。 List はさきほどつくったもの。 また、HashMap にパラメータを設定して Jasper に渡すと PDF ができる感じです。

   1: public class SampleReportFactory {
   2:  
   3:     // さきほどの createBeanCollection メソッド省略
   4:  
   5:     public static void main(String args[]) throws JRException {
   6:         
   7:         // 出力するBean のつまった List を DataSource に設定
   8:         JRBeanCollectionDataSource ds =
   9:             new JRBeanCollectionDataSource(
  10:                 SampleReportFactory.createBeanCollection());
  11:         // パラメータの Map 作成
  12:         Map<String,String> param = new HashMap<String,String>();
  13:         param.put("now", "2010/03/11");
  14:         // これらのデータを元に PDF 作成
  15:         JasperPrint pdf = JasperFillManager.fillReport(
  16:                 "./templates/sample-report.jasper", param, ds);
  17:         // PDF をファイルとして出力
  18:         JasperExportManager.exportReportToPdfFile(pdf,
  19:                 "./templates/sample-report.pdf");
  20:         
  21:         // pdf.addPage((JRPrintPage)pdf.getPages().get(0));
  22:         
  23:     }
  24:  
  25: }

実行~。

Jasper17

おめでとうございます(笑)

最後のサンプルソースの一番下にコメントでかいてありますが、複数のテンプレートをつなげて一つの PDF にすることもできそうです。

   1: // pdf.addPage((JRPrintPage)pdf.getPages().get(0));

addPage の引数に index ありもあったので、交互差し込みとかもできるかもですね。

ここまできたら、本家のマニュアルの xml タグを調べていけばあとはなんとか。。(笑)

JasperReports 3.7.1 – Schema Reference

This document describes the structure of the JRXML report template files for the JasperReports library.

Expression 系でいろいろできそうです。

以上、参考になりましたら。

Microsoft Arc Mouse に変更です

使っていた Microsoft のでっかいマウスのラバー部分がでろでろになってきましたので、マウスを変更しました。

手が大きいのもあって、大きい重いマウスが好みだったりするのですが Microsoft Arc Mouse がなんだかかわいかったので、そちらにしてみました。 真っ向から傾向が違いますが、たまには。 🙂

Microsoft Arc Mouse ブラック ZJA-00017

全く新しい洗練された外観に、優れた携帯性と快適な操作性をあわせ持った、スタイリッシュなレーザー方式マウス

こんなのです。 Ubuntu 9.10 で動作させていますが、特に問題はなさそう。 電池は単四2本で軽い軽い。

IMG_0078

持ち運び用に折りたためます。

IMG_0080

持ち運びポシェットがついててよいですなぁ。 折りたたむと電源が切れるので、PC 起動中もお掃除もできるという特典がもれなくついてまいります(笑)

使い勝手は、最初指の置き場所に困りましたがちょっとしたら慣れました。 ホイールがちょっとかちゃかちゃうるさいかな。 引っかかりがあるホイールなので中ボタンは押しやすいです。  🙂

なお、サイドボタン(戻る)はぼくの手はうまく押せません。 ブラウザアドインとか Opera とかの右左押しで運用対処を(笑)

カラーバリエーションあり。 普通使いも携帯もできるマウスを探している方は要チェックや!

Excel ファイルの操作を Groovy から行う

あちこちの現場で、エクセルファイルから create table をつくったり Bean をつくったりするマクロをみかけます。 ぼくもつくったことありますが、こういうのってワンショットで一回つくったら大抵もう使わないプログラム。

エクセル VBA でつくりますが、ぼくら VBA ってあんまり使わないのですぐ忘れてしまい、あれ文字列の連結 & だっけ?とか、 ; つけてすまったー! とか、たくさんのファイルを処理するとぱかぱかエクセルあがったりしてうーん、とかいろいろ、、、というわけで Java からエクセルを読み込む XLSBeans を試してみました。

実は VBA も RANGE オブジェクトつくって Iterator っぽくまわせたり結構やるなって思う部分もあるのですが、やっぱり書き方的に慣れてない部分も多々あります。 で、Java って思うのですが、ワンショットにしては適当にかけない部分もあり、、ってことで今回は Groovy から XLSBeans を呼び出してみました。 🙂

XLSBeans – Project Amateras

ExcelとJavaBeansをJava 5のアノテーションでマッピングするためのライブラリです。

MYCOMジャーナルに簡単な紹介記事が掲載されています。まずはこちらをご覧いただくとXLSBeansがどのようなものかをご理解いただけるのではないかと思います。

XLSBeans – ExcelをJavaBeanに自動マッピング!

とりあえず、XLSBeans と Groovy を使えるようにしてこんな感じに・・・。

xlsbeans01

Excel をつくります。 OOo で xls 形式にしましたが問題ありませんでした。

たとえば、画面定義。 本物は 100 とか 200行オーダで、もっといろいろ書いているもんですが、とりあえず。 これの struts FormBean をつくるようなイメージで。(あくまでイメージね)

xlsbeans02

で、ソースをかきます。 Groovy なので単一モジュールで、main もなく、がりがりいけます。 試験的に漢字変数とかも使ってみました。 なんかこわい(笑)

import net.java.amateras.xlsbeans.*;
import net.java.amateras.xlsbeans.annotation.*;
 
// エクセルファイルを定義に従って読み込む
sheet = (new XLSBeans()).load(
    new FileInputStream("xls/項目定義.xls")
    , ExcelSheet.class);
 
// 定義からデータ呼んでファイル出力
new File("xls/test.txt").withPrintWriter { w ->
    for(画面項目 in sheet.画面項目行) {
        upper = 画面項目.物理名[0].toUpperCase();
        upper +=
            画面項目.物理名[1..画面項目.物理名.length() - 1]; 
        str = """
            // ${画面項目.論理名}
            private String ${画面項目.物理名};
            
            private String get${upper}() {
                return ${画面項目.物理名};
            }
            private void set${upper}(String str) {
                ${画面項目.物理名} = str;
            }""";
        w.println(str);
    }
}
 
// 以下エクセルの定義
 
@Sheet(name="Sheet1")
class ExcelSheet {
    @HorizontalRecords(tableLabel="画面項目定義"
        , recordClass=画面項目.class)
    public List<画面項目> 画面項目行;
}
 
class 画面項目 {
    @Column(columnName="論理名")
    public String 論理名;
    @Column(columnName="物理名")
    public String 物理名;
    @Column(columnName="タイプ")
    public String タイプ;
    @Column(columnName="長さ")
    public String  長さ;
    @Column(columnName="出力編集")
    public String 出力編集;
}

これを実行するとエクセルを処理して内容を吸い出して整形したテキストファイルができあがります。 サンプルでも JavaDoc くらいつけろですか。 😀

// タイトル
private String title;
 
private String getTitle() {
    return title;
}
private void setTitle(String str) {
    title = str;
}

・・・。 ・・・。 まちがって getter / setter を private にしてしまいました。 まぁサンプルということでご愛敬。。(笑)

さて、最初エクセルを取得する Bean を Groovy のプロパティをつかって public をつけずに定義していたら、うまく値が入りませんでした。 Groovy でも public String hoge; とかするのが正解のようです。

VBA で処理すると座標系でやってしまいがちで、これが結構数えたり面倒だったりするもんですが、XLSBeans を使うとオートで Bean にマッピングしてくれるので大変便利です。 エクセルのあちこちの位置に置いてみたりしてみましたが、うまく検索して場所を探してくれるようです。

Groovy から呼ぶと、public static void main() いらなかったり、ヒアドキュメント + GString のうめこみ変数とか、ファイルのオープンクローズとか不要とか、文字列操作とかいろいろ楽かもですね。 ぼくは慣れてないので、まだまだ簡単にかく方法あると思います。

てなわけで、Eclipse にプロジェクトひとつ準備しておくと何かのおりに使えるかもしれません。 🙂