ライブラリ

Javaで帳票PDF動的生成はこれがベスト? – ミドルウェアなし・Excelでデザイン可能 / Herokuで動作するサンプル付き #herokujp #jjug

Java Advent Calendar 2013 – 一日目のエントリになります

電子化が進んでいる昨今ですがなにかと帳票類は欠かせません。紙の帳票は必要なくとも最低限pdfの請求書は必要、といった場面も多いのではないでしょうか?
電子帳票ソリューションといえばSVF(Super Visual Formade)が日本では有名かと思いますがオープンソースソフトウェアでもお手軽にpdfの帳票を作ることができます。
(ミドルウェアなし、というタイトルは半ば釣りで、本エントリではiTextというライブラリ/ミドルウェアを使っています)

今回使うのはiText。OSSのPDF操作ライブラリです。(追記:社内利用、OSSサービスなどで利用は無償。クローズドソースで商用利用をするには有償、というライセンス形態(AGPL)です)
java – Does it required to get licence for Itext pdf library for in house development? – Stack Overflow

iTextだけでイチから帳票を作ることもできますがプログラムで罫線や文字を細かくレイアウト、デザインするのはかなりの神業。そこでオススメなのがExcelなどのオフィスツール、AcrobatとiTextを組み合わせる方法です。
以下に手順とコードを示します。

1. 帳票のデザインとpdf化
ExcelでもWordでもIllustratorでも何でも良いので使い慣れたツールで帳票を作ります。金額や宛名など、動的に埋め込む部分は空欄にしておきます。
今回サンプルとして用意したのは見積書、請求書、納品書と3通り使うためのベース。なので帳票のタイトルすら書いてありません。
form.xlsx

またデザインした帳票はPDF化します。
MacであればOSにPDF機能が組み込まれているのでプリントダイアログの左下より、WindowsであればPrimoPDFやAdobe PDFプリンタなどを使ってPDF出力します。

2. Acrobatでフォーム要素追加
PDFにフォーム要素(動的に値を入れられる部分)を作るため、Acrobatで開き、編集します。

PDF出力からフォーム作成まで動画にしてみました。

なんとExcelで作った帳票デザインで入力箇所となりそうな部分を自動的に認識してくれます。すごい!!
フォーム要素を埋め込んだPDFの例はこちら

3. iTextでフォームに値を入れ、PDF出力
FileInputStreamやClass#getResourceAsStreamなどでAcrobatでフォーム要素を埋め込んだpdfファイルのストリームを開き、com.lowagie.text.pdf.PdfReaderのコンストラクタに渡します。
さらにPdfReaderのインスタンスはcom.lowagie.text.pdf.PDFStamperに渡し、フォーム要素をgetAcroFields()で取得します。
フォーム要素の値はsetField(キー,値)でセットします。
多くの場合、最終的なPDFは編集付加にしておきたいので、flattenという処理を行います。partial form fatteningという処理をすると指定したフォーム要素だけ編集不可にしておくこともできます。
partial form flatteningを使えばたとえば発注書PDFを生成してメールで送り、日付や注文書番号などをお客様に記入してもらい送り返してもらうということが可能です。便利(๑・ω-)~♡

具体的なコードはこちらをごらんください。iTextでPDFのフォーム要素に値を埋め込むための必要最小限のコードになっています。

コードサンプル:
https://github.com/yusuke/javaform

動作サンプル:
実際に動作するサンプルをHerokuに上げておきました。
以下のフォームをサブミットすると請求書PDFが動的に生成されます。
(値のバリデートはしていない手抜きサンプルなので数量、単価は数値を入力しないとダメです)