PDF出力をするときに、何ページにも渡る帳票を出力するのは簡単ですが、二次元方向に伸びるページを出力する方法がなかなか思いつかず、苦労しました。
具体的には、印刷したページを並べてみると以下のような配置になるような帳票の出力です。
+-----+-----+-----+
| A-1 | B-1 | C-1 |
+-----+-----+-----+
| A-2 | B-2 | C-2 |
+-----+-----+-----+
| A-3 | B-3 | C-3 |
+-----+-----+-----+
いろいろ悩んで試行錯誤した結果、以下のような処理で出力することができた!…が、どうにもやり方が回りくどいような。無駄が多い気もするし。でも、とりあえず動いた時点のソースということでメモメモ。
これからデバッグして、問題ないことを確認してから、もっとスマートな方法がないかチャレンジしてみる予定。
FacesContext context = FacesContext.getCurrentInstance();
ExternalContext excon = context.getExternalContext();
HttpServletRequest request = (HttpServletRequest) excon.getRequest();
HttpServletResponse response = (HttpServletResponse) excon.getResponse();
// A列用のリスト
List<Map> listA = new ArrayList<Map>();
// B列用のリスト
List<Map> listB = new ArrayList<Map>();
// C列用のリスト
List<Map> listC = new ArrayList<Map>();
// 各列のリストを配列に入れる
List[] list = {listA, listB, listC};
// 上記リストに、実際にはデータが入っているものとして…
int columnNum = list.length;
// InputStream と JRDataSource は配列の数だけ用意していないと
// PDF出力が0byteになってしまうので、ここで用意する。
// fname はコンパイル済みのテンプレートファイルパス
InputStream[] stream = new InputStream[columnNum];
JRDataSource[] ds = new JRDataSource[columnNum];
for (int i = 0; i < columnNum; i++) {
stream[i] = excon.getResourceAsStream(fname[i]);
ds[i] = new JRBeanArrayDataSource(list[i].toArray());
}
// ここは特に普段と変更なし
JRExporter exporter = new JRPdfExporter();
exporter.setParameter(
JRExporterParameter.OUTPUT_STREAM,
response.getOutputStream());
// いったんA列のデータを変換しておく
JasperPrint jasperPrint = null;
jasperPrint = JasperFillManager.fillReport(
stream[0], new HashMap(), ds[0]);
// B列以降のデータを変換し、変換したA列に1ページ分ずつ追加していく
for (int i = 1; i < columnNum; i++) {
JasperPrint jp = JasperFillManager.fillReport(
stream[i], new HashMap(), ds[i]);
for (int j = 0; j < jp.getPages().size(); j++) {
jasperPrint.addPage((JRPrintPage) jp.getPages().get(j));
}
}
// PDF出力する
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
request.getSession().setAttribute(
ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE,
jasperPrint);
exporter.exportReport();
// 後処理
for (int i = 0; i < columnNum; i++) {
stream[i].close();
}
JRExporterParameter に JASPER_PRINT_LIST というパラメータがあるんだけど、これを使えばもっとスマートな処理になるかも?ただし、このパラメータの使い方がよくわからないので、今の時点では何とも言えず。
コメント