Webアプリケーションから帳票を発行しようとした場合、皆さんはどのような方法を用いているでしょうか。もちろん、CSS(Cascading StyleSheet)で精緻(せいち)なレイアウトを設計してブラウザ上から印刷させるという方法も可能でしょう。また、「POIを使用してJavaからExcel出力を行う」でも紹介したようにPOIでExcel帳票を作成するという方法もあるかもしれません。そして、それほど厳密でない帳票であれば、おそらくこれらの方法で十分なはずです。
しかし、これらのアプローチには「帳票の改ざんができてしまう」という問題点があります。CSS+HTMLにせよ、Excelにせよ、これをクライアント側で編集・更新するのは容易です。特に、確証としての意味がある帳票などでは、帳票が正規の発行者から提供されたオリジナルであることを保証できなければいけませんから、CSSやExcel帳票ではそもそもの用途を満たし得ないということになります。
しかし、PDF(Portable Document Format)を利用すれば、これらの問題は解決します。PDF文書ならば基本的に改変はできませんし、その他、印刷やコピーを禁止するなどセキュリティ的な制御も可能です。また、PDF文書を参照するには、フリーで提供されているAdobe Readerさえあればよいので、クライアント環境にもほぼ依存しないと思ってよいでしょう。
このPDF文書を動的に生成するために、Javaの世界ではPDFLibというライブラリが提供されています。PDFLibは有償のライブラリですが、取りあえずダウンロードして試してみることはできますので、まずは使ってみたいという方も気軽に試用できます。また、PDFLibのうれしいところは、Javaをはじめ、.NET(C#、VB.NET)、COM(VB、ASP、WSH)、C、PHPなど主要な言語/環境に対応しているという点です。PDFLibを利用することで、Javaだけでなく、その他の環境でもほとんど同じ感覚でプログラミングを行うことができます。
それでは早速、具体的なコードを眺めてみることにしましょう。
PDFLibライブラリは、以下のサイトからダウンロードすることができます。
・ http://www.pdflib.com/jp/
ダウンロードしたpdflib-X.X.X-Windows.zip(X.X.Xはバージョン番号)を解凍します。解凍された「pdflib-X-X-X-Windows/bind/java」フォルダ配下にはpdf_java.dll、pdflib.jarがありますので、pdf_java.dllをシステムフォルダ(Windows XPならば「c:\windows\system32」など)に、pdflib.jarをアプリケーションルート配下の「/WEB-INF/lib」フォルダに、それぞれコピーしてください。
環境の準備が整ったところで、PDF文書を生成するためのサーブレットクラスを定義してみましょう。
package to.msn.wings.javatips;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.pdflib.PDFlibException;
import com.pdflib.pdflib;
public class PdfGenerate extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
pdflib objPdf=null;
try {
objPdf=new pdflib();
// 新規のPDF文書を生成
objPdf.begin_document("", "");
// 文書情報を設定
objPdf.set_info("Author","Y.Yamada");
// 設定した紙面サイズで新規ページを生成
objPdf.begin_page_ext(595,842,"");
// フォントを生成
int intFnt=objPdf.load_font("HeiseiMin-W3","UniJIS-UCS2-H","");
objPdf.setfont(intFnt,18);
// 行間を設定
objPdf.set_value("leading",20);
// テキストの開始位置を設定
objPdf.set_text_pos(10,700);
// 文字列を出力
objPdf.show("PDFLibの");
objPdf.continue_text("サンプルです。");
// 後始末
objPdf.end_page_ext("");
objPdf.end_document("");
// PDF文書をバイナリデータとしてクライアントに出力
byte[] buf = objPdf.get_buffer();
response.setContentType("application/pdf;charset=Windows-31J");
response.setHeader("Content-disposition","attachment; filename=simple.pdf");
response.setContentLength(buf.length);
ServletOutputStream objOut=response.getOutputStream();
objOut.write(buf);
objOut.close();
} catch (PDFlibException e) {
e.printStackTrace();
} finally {
// PDFLibオブジェクトを破棄
if(objPdf!=null){objPdf.delete();}
}
}
} |
本サーブレットクラスを実行するに当たっては、あらかじめデプロイメント・ディスクリプタ(web.xml)に対して、サーブレットの登録を行っておく必要があります。<url-pattern>要素に「/simple.pdf」のように指定しておくことで、サーブレットクラスをあたかも静的なPDFファイルであるかのように見せることができます(拙稿「JSPとサーブレットの違いを明らかにする」も併せて参照してください)。
<?xml version="1.0" encoding="UTF-8" ?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-app_2_4.xsd"
version="2.4">
……中略……
<servlet>
<servlet-name>PdfGenerate</servlet-name>
<servlet-class>to.msn.wings.javatips.PdfGenerate</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>PdfGenerate</servlet-name>
<url-pattern>/simple.pdf</url-pattern>
</servlet-mapping>
……中略……
</web-app> |
このコードの実行結果は、以下のようになります。
実行結果(規定のライセンス料金を支払うまでは、生成されたPDF文書には斜めに大きく「www.pdflib.com」のロゴが表示されます)
ロジックの詳細な流れについては、コード内のコメントを参照いただくとして、ここではPDFLibを利用したコーディングの大まかな流れを押さえてみてください。
- 新規PDF文書の生成(赤字部分)
- 基本情報(メタ情報、フォントなど)の設定(黄字部分)
- 文字列データの出力(緑字部分)
- PDF文書としてクライアントに出力(紫字部分)
これがすべての流れではありませんが、基本的なPDF文書を生成する程度ならば、ほとんど共通だと思っていただければよいでしょう。本稿ではあらかじめハードコーディングされた文字列を出力しているだけですが、もちろん、この部分をリクエスト・パラメータなどから生成することも可能です。PDFLibライブラリに関する詳細については、上記のダウンロードサイトからも確認することができますので、興味のある方はご覧になってみるとよいでしょう。