1. 帳票出力(Jasper/JXLS/POI)
Templateの編集画面でExcelやPDFの出力定義を設定することで帳票出力機能を利用することが出来ます。
2. 帳票出力の作成
帳票出力機能を利用するために、Template定義に以下の設定を行わなければなりません。
-
帳票定義のTemplateを呼び出すActionクラスを作成します。
-
JasperReports(PDF)、JXLS(Excel)、またはApache POI(Excel)用のテンプレートファイルを作成しておきます。
-
Template定義の編集画面でテンプレートタイプに
Report
を選択、Report Type
にJasperReports
、JXLS
、またはPOI
のいずれかを選択し、作成したテンプレートファイルをアップロードします。-
JasperReportsを利用する場合、Template定義で
DataSource
、Parameters
の設定項目 にRequestContextまたはSessionContextに値をセットしたAttribute名を設定します。 -
JXLSを利用する場合、Template定義で
Context Parameter Mappings
の設定項目にテンプレートファイルに設定したパラメータ名、RequestContextまたはSessionContextに値をセットしたAttribute名を設定します。また、帳票出力処理をカスタマイズしたい場合、JavaまたはGroovyを利用してOutput Logicを実装し、Custom Output Logic
に設定します。 -
POIを利用する場合、JavaまたはGroovyを利用してOutput Logicを実装し、Template定義の
Output Logic
に設定します。
-
-
Actionクラスが呼び出されるときに、帳票出力処理が実行されます。
3. 設定
Template定義の編集画面での設定項目
項目 | 内容 |
---|---|
Report Type |
出力ライブラリー形式を設定します。 以下の形式をサポートしてます。
|
Format |
出力するファイルの形式を設定します。
※PDF出力はJasperReports形式のみ対応しています。 |
File |
各ReportTypeに対応したテンプレートファイルを設定します。 |
Password Attribute Name |
出力するレポートに対してパスワードを設定する場合に、そのパスワード値をセットしたRequestのAttribute名を指定します。 パスワードは、ユーザーに画面上で指定させてリクエストでもらったり、システム内部で固定したり、ランダムで設定してメール通知したり要件に応じて実装し、このTemplateを利用する前のCommandでここで指定したAttributeに対して、パスワードをセットしてください。 ※パスワードは、いずれのReportTypeにおいてもXLS形式には対応していません。Excelに対してパスワード指定する場合はXLSX形式を利用してください。 |
DataSource Attribute Name |
Report Typeが 詳細は「JasperReports DataSource設定」を参照してください。 |
Parameters |
Report Typeが 詳細は「JasperReports Parameters設定」を参照してください。 |
Context Parameter Mappings |
Report Typeが 詳細は「Context Parameter Mappings設定」を参照してください。 |
Custom Output Logic |
Report Typeが 詳細は「Custom Output Logic設定」を参照してください。 |
Output Logic |
Report Typeが 詳細は「Poi Output Logic設定」を参照してください。 |
3.1. JasperReports設定
JasperReports DataSource設定
JasperFillManager.fillReport実行時のデータソースを指定することができます。
このTemplateを利用する前のCommandでJRDataSourceを実装したクラスのインスタンスをAttributeにセットしてください。 そのAttribute名をここで指定することで、JasperFillManager.fillReport実行時にデータソースをセットします。 未設定の場合、JREmptyDataSourceをJasperFillManager.fillReportに渡します。
またEntityの検索結果などをデータソースとして利用したい場合は、
org.iplass.mtp.web.template.report.JasperReportingEntityDataSource
を利用することも可能です。 EntityのJava Mapping Classを利用していない場合、各Entityで個別に追加したプロパティに対しては、getXXXというメソッドがない為、JRBeanCollectionDataSourceを使うのが難しくなります。 JasperReportingEntityDataSourceを利用することで、EntityのListをそのまま指定し、 Fieldとして利用することができます。
-
Entity
テスト用のEntity定義を登録しておきます。
-
Command
/** * 検索結果をJasperReportingEntityDataSourceとして「orderItems」Attributeにセット。 */ import org.iplass.mtp.ManagerLocator; import org.iplass.mtp.entity.Entity; import org.iplass.mtp.entity.EntityManager; import org.iplass.mtp.entity.query.Query; import org.iplass.mtp.entity.SearchResult; import org.iplass.mtp.entity.LoadOption; import org.iplass.mtp.entity.query.condition.predicate.Equals; import org.iplass.mtp.web.template.report.JasperReportingEntityDataSource; String oid = request.getParam("oid"); request.setAttribute("oid", oid); EntityManager em = ManagerLocator.manager(EntityManager.class); //Order検索(OrderItemは別で取得するのでReferenceは取得しない) Entity order = em.load(oid, "test.report.Order", new LoadOption(false, false)); request.setAttribute("order", order); //OrderItem検索 Query query = new Query() .select("price", "quantity", "product.name", "product.price") .from("test.report.OrderItem") .where(new Equals("order.oid", oid)); SearchResult<Entity> orderItems = em.searchEntity(query); //JasperReportingEntityDataSourceとしてEntityのListを格納 request.setAttribute("orderItems", new JasperReportingEntityDataSource(orderItems.getList())); (1)
1 JasperReportingEntityDataSourceとして「orderItems」Attributeにセット。 -
Template
-
JasperReports
JasperReports Parameters設定
JasperFillManager.fillReport実行時のパラメータにセットする値を指定することができます。
項目 | 内容 |
---|---|
Value Type |
パラメータとして渡す変数タイプを設定をします。 以下の形式をサポートしてます。
|
Name |
パラメータとして渡すMapに設定するKey名を指定します。 |
Value |
Value Typeが (例) |
Template |
Value Typeが パラメータとしてJasperReport形式にコンパイルした結果をセットします。 |
-
Template
-
JasperReports
表示方法
作成したCommandクラスとTemplateを呼び出すActionクラスを作成します。
-
作成したCommandクラス
-
帳票出力Template定義
管理画面にログインし、以下のURLにアクセスすると、帳票出力処理が実行されます。
http://hostname:port/{コンテキスト名}/{テナント名}/test/report/order?oid=xxx
-
パラメータとして指定されている部分
-
データソースとして指定されている部分
3.2. JXLS設定
JXLS形式で帳票出力を行うために最低限必要な準備は、JXLS用のExcelテンプレートファイルを用意し、パラメータとして渡す reportData に設定するKeyとValue(値が格納されているRequestContext、またはSessionContextのAttribute名)を設定することです。 帳票出力のロジックは、設定しない場合でも標準的な帳票出力処理を実行しますが、独自にカスタマイズすることも可能です。JXLS では式評価エンジンを利用しており、iPLAss では GroovyScript を利用します。
JXLSの仕様については、以下のサイトを参照してください。
http://jxls.sourceforge.net
注意点として、JXLSのEach-Commandなどを利用して大量のセルにデータを書き込む場合、性能が極端に低下する可能性があります。大まかな目安として、Each-Commandなどを利用してデータを書き込むセル数 (行と列の積) が10,000を超えるような場合には POI の利用を検討してください。
|
Context Parameter Mappings設定
テンプレートファイルからExcel帳票の生成を実行する際のパラメータマッピングを設定します。
項目 | 内容 |
---|---|
Key |
パラメータとして渡す reportData に設定するKey名を指定します。 |
Value |
パラメータとして渡す reportData に設定する値が格納されているAttribute名を指定します。 このTemplateを利用する前に実行するCommandで、RequestContext、またはSessionContextの指定したAttributeに値をセットしてください。
|
To Map |
このオプションが有効の場合、reportData に値をセットする際にGenericEntityのインスタンス、もしくはそのListをMap形式に変換します。 EntityのJava Mapping Classを利用していない場合、各Entityで個別に追加したプロパティ(以下、個別プロパティ)に対しては、getXXXというメソッドがない為、JXLSの帳票出力処理において値が取得できない場合があります。
|
-
Entity
テスト用のEntity定義を登録します。
この例では、 JasperReports DataSource設定 での例と同一のEntity定義を利用します。 -
Command
import org.iplass.mtp.ManagerLocator; import org.iplass.mtp.entity.Entity; import org.iplass.mtp.entity.EntityManager; import org.iplass.mtp.entity.query.Query; import org.iplass.mtp.entity.SearchResult; import org.iplass.mtp.entity.LoadOption; import org.iplass.mtp.entity.query.condition.predicate.Equals; String oid = request.getParam("oid"); request.setAttribute("oid", oid); EntityManager em = ManagerLocator.manager(EntityManager.class); //Order検索(OrderItemは別で取得するのでReferenceは取得しない) Entity order = em.load(oid, "test.report.Order", new LoadOption(false, false)); request.setAttribute("order", order); //OrderItem検索 Query query = new Query() .select("price", "quantity", "product.name", "product.price") .from("test.report.OrderItem") .where(new Equals("order.oid", oid)); SearchResult<Entity> orderItems = em.searchEntity(query); //EntityのListを格納 request.setAttribute("orderItems", orderItems.getList());
-
テンプレートファイル
JXLS用のExcelテンプレートファイルを作成します。
-
Template
Template定義を設定します。
-
OrderItemの繰り返し出力の並び替え属性に、個別に追加したプロパティ(price)を指定した為、
To Map
を有効にします。
表示方法(シンプル)
-
Action
作成したCommandクラスとTemplateを呼び出すActionクラスを作成します。
-
作成したCommandクラス
-
帳票出力Template定義
管理画面にログインし、以下のURLにアクセスすると、帳票出力処理が実行されます。
http://hostname:port/{コンテキスト名}/{テナント名}/test/report/orderJxls?oid=xxx
-
出力結果
Custom Output Logic設定
帳票出力の処理を独自にカスタマイズしたい場合、JavaまたはGroovyを利用してJXLS用のOutput Logicを実装し、設定することが可能です。
帳票出力処理の設定カスタマイズには JxlsTemplateFillerBuilder を設定します。設定方法の詳細は Builder Options を参照ください。
Custom Output Logic を設定しない場合は、JxlsTemplateFillerBuilder にテンプレートを設定しビルドしたインスタンスの JxlsTemplateFiller.fill によって帳票出力が実行されます。
JavaクラスによるOutput Logicの実装
必ず org.iplass.mtp.web.template.report.JxlsReportOutputLogic
インターフェースクラスをimplementsし、実装して下さい。
import java.io.OutputStream;
import java.util.Map;
import org.iplass.mtp.web.template.report.JxlsReportOutputLogic;
import org.jxls.builder.JxlsTemplateFillerBuilder;
public class SampleOutputLogicJXLS implements JxlsReportOutputLogic {
@Override
public void reportWrite(JxlsTemplateFillerBuilder<?> builder, Map<String, Object> reportData, OutputStream out) {
builder.build().fill(reportData, () -> out); (1)
// Map<String, Object>に格納した値の取得
Object obj = reportData.get("Key"); (2)
}
}
1 | JxlsTemplateFillerBuilder を用いて帳票出力を実行可能です。より複雑な出力が必要な場合、引数の JxlsTemplateFillerBuilder を設定し出力処理を実装してください。 |
2 | reportData(Map) に格納した値を取得して、処理に組み込むことが可能です。 |
GroovyによるOutput Logicの実装
Groovyの記述形式で実装する事ができます。 org.iplass.mtp.web.template.report.JxlsReportOutputLogic
インターフェースクラスのように以下のバインド変数、およびメソッド(詳細はJavaDocを参照)がGroovyScript内で利用可能です。
バインド変数 | 内容 |
---|---|
builder |
Jxls テンプレート処理のビルダーインスタンス (Apache POIテンプレートを利用する JxlsTemplateFillerBuilder を利用) |
reportData |
帳票出力パラメータが格納されたMap |
out |
帳票出力先 |
表示方法(カスタム)
この例では、Grid-Commandを利用して、動的な列/行数のグリッドを出力する方法を示します。
-
Command
import org.iplass.mtp.ManagerLocator; import org.iplass.mtp.entity.Entity; import org.iplass.mtp.entity.EntityManager; import org.iplass.mtp.entity.query.Query; import org.iplass.mtp.entity.SearchResult; import org.iplass.mtp.entity.LoadOption; import org.iplass.mtp.entity.query.condition.predicate.Equals; String oid = request.getParam("oid"); request.setAttribute("oid", oid); EntityManager em = ManagerLocator.manager(EntityManager.class); //Order検索(OrderItemは別で取得するのでReferenceは取得しない) Entity order = em.load(oid, "test.report.Order", new LoadOption(false, false)); request.setAttribute("order", order); //OrderItem検索 Query query = new Query() .select("price", "quantity", "product.name", "product.price") .from("test.report.OrderItem") .where(new Equals("order.oid", oid)); SearchResult<Entity> orderItems = em.searchEntity(query); //Header部分の指定 request.setAttribute("headers", Arrays.asList("商品名", "数量", "単価", "金額")) //Data部分(EntityのList)の指定 request.setAttribute("data", orderItems.getList());
-
テンプレートファイル
-
Template
-
OutputLogicのプログラム内で直接個別プロパティを指定する為、
To Map
を有効にします。
-
import org.jxls.builder.xls.XlsCommentAreaBuilder;
import org.jxls.command.GridCommand;
builder
// grid コマンドの props に設定 (1)
.withAreaBuilder({transformer, clearTemplateCells ->
def areaList = new XlsCommentAreaBuilder().build(transformer, clearTemplateCells);
for (area in areaList) {
for (commandData in area.getCommandDataList()) {
if (commandData.getCommand() instanceof GridCommand) {
// 出力するプロパティを指定
commandData.getCommand().setProps('product.name, quantity, product.price, price'); (2)
}
}
}
return areaList;
})
.build()
.fill(reportData, { out });
1 | 本例では全 Area に設定されている GridCommand に対してプロパティを設定します。 |
2 | GridCommand (jx:grid) の props に出力プロパティ情報を設定します。 |
管理画面にログインし、以下のURLにアクセスすると、帳票出力処理が実行されます。
http://hostname:port/{コンテキスト名}/{テナント名}/test/report/orderJxls?oid=xxx
-
出力結果
3.3. Apache POI設定
Poi Output Logic設定
Poi用のOutput Logicの実装方法は2種類あります。
JavaクラスによるOutput Logicの実装
必ず org.iplass.mtp.web.template.report.PoiReportOutputLogic
インターフェースクラスをimplementsし、実装して下さい。
import org.iplass.mtp.command.RequestContext;
import org.iplass.mtp.web.template.report.PoiReportOutputLogic;
import org.apache.poi.ss.usermodel.Workbook;
public class TutorialReportLogic implements PoiReportOutputLogic {
@Override
public void reportOutput(RequestContext context, Workbook book) {
// 処理
def sheet = book.getSheet("シート名"); (1)
sheet.getRow(XXX).getCell(YYY).setCellValue("セルの値"); (2)
}
}
1 | シート名でテンプレートファイルのシートを取得します。 |
2 | テンプレートシートのXXXの行のYYYのセルに値をセットします。 ※SXSSFWorkbookの場合、テンプレートとして設定してあるExcelに既に存在するRowを取得しようとしてもnullが返ってくるので、 「テンプレートのXXXのセルに値を設定する」といった利用はできません。Sheet#createRow(rowIndex)やRow#createCell(colIndex) を利用して、データをExcelに出力する時に利用されます。 詳しくは SXSSFWorkbookのConstructor Detailを参照してください。 |
GroovyによるOutput Logicの実装
Groovyの記述形式で実装する事ができます。org.iplass.mtp.web.template.report.PoiReportOutputLogic
インターフェースクラスのように以下のバインド変数がGroovyScriptで利用可能です。
バインド変数 | 内容 |
---|---|
context |
リクエストコンテキスト |
book |
ワークブック |
表示方法
-
Template
OutputLogicの実装
import org.iplass.mtp.entity.Entity; import org.iplass.mtp.entity.EntityManager; import org.iplass.mtp.entity.LoadOption; import org.iplass.mtp.entity.SearchResult; import org.iplass.mtp.entity.query.Query; import org.iplass.mtp.entity.query.condition.predicate.Equals; def sheet = book.getSheet("order"); String oid = context.getParam("oid"); int rowNo = 1; def row = sheet.getRow(rowNo); row.getCell(4).setCellValue(oid); EntityManager em = manager(EntityManager.class); // Order検索(OrderItemは別で取得するのでReferenceは取得しない) Entity order = em.load(oid, "test.report.Order", new LoadOption(false, false)); rowNo = 5; row = sheet.getRow(rowNo); row.getCell(0).setCellValue(order.orderNo); row.getCell(1).setCellValue(order.customer); row.getCell(2).setCellValue(order.address); row.getCell(3).setCellValue(order.mail); row.getCell(4).setCellValue(order.tel); // OrderItem検索 Query query = new Query().select("price", "quantity", "product.name", "product.price") .from("test.report.OrderItem").where(new Equals("order.oid", oid)); SearchResult<Entity> orderItems = em.searchEntity(query); rowNo = 9; for (Entity item : orderItems.getList()) { row = sheet.getRow(rowNo); row.getCell(0).setCellValue(item.product.name); row.getCell(2).setCellValue(item.quantity); row.getCell(3).setCellValue(item.product.price); row.getCell(4).setCellValue(item.price); rowNo++; }
-
Action
-
今回はParameterMappingsを利用し、パスから
oid
を取得します。 -
作成した帳票出力Template定義。
-
管理画面にログインし、以下のURLにアクセスすると、帳票出力処理が実行されます。
http://hostname:port/{コンテキストパス}/{テナント名}/test/report/orderPoi/xxx