ExcelテンプレートエンジンJETTを利用して請求書を出力しよう
(お客様の声)
システム(入力画面)はあるのに「現場では見積書・請求書・納品書はExcelを使って手動で作成している」
この画面の端っこに「帳票出力」ボタンがあって押すと出力できたら良いなぁ
はじめに
お客様には提案したいけど、導入が難しいと思ってしまっているエンジニア(Java)に、きっと朗報なナレッジとなります。「JETT」は、ちょっとしたルールを理解することで、ある程度の想像のつく多くの帳票をテンプレート化することができ、そして動的に出力することができます。
以下は、「請求書」をテンプレート化し、データを受け渡し変換出力したイメージとなります。
サンプルコードは以下よりダウンロードできます。
jett-example
実際にダウンロードし動かしながら、ご確認ください。
「ExcelテンプレートエンジンJETTを利用してピボットテーブルでグラフを表示しよう」の記事も確認ください。
帳票変換処理のコード
変換処理で使用するJETTのクラスは、この「ExcelTransformerクラス」だけであり、
transformメソッドを呼んでいます。
package com.github.k3286.report;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.Workbook;
import net.sf.jett.transform.ExcelTransformer;
public class ReportMaker {
/**
* パラメータと、テンプレートファイル名を指定し、帳票変換を行う
* @param params パラメータ
* @param templateName テンプレートファイル名
* @return 変換したWorkbook
*/
public static Workbook toReport(Map<String, Object> params, String templateName) {
Workbook workbook = null;
InputStream is = null;
try {
is = ReportMaker.class.getResourceAsStream("/" + templateName);
ExcelTransformer transformer = new ExcelTransformer();
workbook = transformer.transform(is, params);
} catch (InvalidFormatException | IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return workbook;
}
}
動作させるテストクラス
請求書に表示するデータを設定しています、明細行も一緒に設定しています。
特別、こちらについては工夫は必要ありません。
変換処理は、データを「ReportMaker.toReport()メソッド」に渡してるだけです。
package com.github.k3286.report;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Test;
import com.github.k3286.dto.Invoice;
import com.github.k3286.dto.InvoiceDetail;
public class InvoiceMakerTest {
private static BigDecimal TAX_RATE = new BigDecimal(0.08);
/**
* 請求書の出力デモ
* @throws Exception
*/
@Test
public void invoice_test() throws Exception {
Invoice inv = new Invoice();
inv.setInvoiceNo("INV-00000001");
inv.setClientPostCode("〒123-3333");
inv.setClientAddress("東京都品川区東五反田1丁目6−3 東京建物五反田ビル 108F");
inv.setClientName("株式会社 松上電気");
inv.setSalesRep("営業 太郎");
inv.setInvoiceDate(new Date());
// 明細行は5行にしておく
for (int idx = 1; idx <= 5; idx++) {
InvoiceDetail dtl = new InvoiceDetail();
dtl.setItemName("サンプル明細ですよ " + idx);
dtl.setUnitCost(BigDecimal.valueOf(10000));
dtl.setQuantity(Double.valueOf(idx));
dtl.setAmt(dtl.getUnitCost().multiply(//
BigDecimal.valueOf(dtl.getQuantity())));
inv.getDetails().add(dtl);
}
BigDecimal total = BigDecimal.ZERO;
for (InvoiceDetail dtl : inv.getDetails()) {
total = total.add(dtl.getAmt());
}
// 立替金
inv.setAdvancePaid(BigDecimal.valueOf(10800));
// 税額
inv.setTaxAmt(total.multiply(TAX_RATE));
// 請求額(税込)
inv.setInvoiceAmtTaxin(total.add(inv.getTaxAmt()).add(inv.getAdvancePaid()));
// 備考
inv.setNote("これは備考です、サンプルとして備考を記述し、"
+ "そして帳票に出力をしてみました。"
+ "折り返してくれるといいのですが、どうでしょうか");
// 帳票変換
Map<String, Object> map = new HashMap<String, Object>();
map.put("inv", inv);
Workbook workbook = ReportMaker.toReport(map, "template_invoice.xlsx");
// ファイル出力
final String outPath = "output_invoice.xlsx";
try (FileOutputStream fileOut = new FileOutputStream(outPath)) {
workbook.write(fileOut);
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
帳票テンプレートで使用しているタグ
請求書のテンプレートファイルは「template_invoice.xlsx」です。
今回テンプレートファイルで使用するタグを説明します。
※ 詳細は「The JETT Tag Library」
タグ | 用途 | 使用箇所 | 備考 |
---|---|---|---|
<jt:forEach> | リストを展開し各要素を出力 | 明細 | サンプルは、limitに10を指定している。展開の行数を指定する。帳票の明細行が固定と決まっており、印刷イメージ(改ページ)を崩したくない場合に利用する |
$[SUM(セル)] | リストを展開したあとの数値の合計に使用する。指定したセルを基準に、展開されたセルまでを動的に数式化しSUM関数の引数に設定される | 小計 | $[SUM(Y26)] ⇒ SUM(Y26:Y30) |
応用へ
ReportMaker.java(抜粋)
ReportMaker.class.getResourceAsStream("/" + templateName);
ReportMaker.class.getResourceAsStream("/" + templateName);
は、classes配下にあるテンプレートファイルを見ることになります。
この場合は、アプリケーションに組み込んだ形となるため、
テンプレートファイルの変更のたびに、再ビルドが必要となります。
運用を考慮すると、管理ユーザにとって大変です。
テンプレートファイルを外で管理する方法を考えます。
・テンプレートファイルを特定の物理パスに配置し、読み込む。
・テンプレートファイルをDBに格納し、読み込む。
・Google Driveにテンプレートファイルを配置し、読み込む。(ただしオンライン)
・etc.
Author And Source
この問題について(ExcelテンプレートエンジンJETTを利用して請求書を出力しよう), 我々は、より多くの情報をここで見つけました https://qiita.com/k3286/items/d2d12242063e9731df11著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .