新機能
少し前にXMLで作成した帳票のテンプレートからPDFを生成するプログラムについて書きましたが、機能を追加したので新しいバージョンをアップします。主な変更点は、次の通り。異なるデータで複数のページを1ファイルに出力
テーブルではない「段落」を任意の位置に表示(主に宛名印刷き用)
複数ページに渡る表の出力(ページ毎にヘッダ、最後にフッタを表示)
Tomcatでの使い方
Webアプリケーションでこのライブラリを使う場合は/WEB/libに次のファイルを配置します。pdfbuilder.jar
iText-5.0.6.jar
iTextAsian.jar
iTextAsianCmaps.jar
pdfbuilder.jar はこのページの下のアイコンからダウンロードできます。
他のファイルは http://itextpdf.com/ からダウンロードしてください。
ただ、itextpdf.comからダウンロードしたiTextAsian.jarとiTextAsianCmaps.jarを使った場合は日本語が正しく表示されないかも知れません。その場合は、http://www.orquesta.org/takegata/Article/ArticleView.jsp?article_id=793からダウンロードしてください。
シンプルなテンプレート
次にシンプルなテンプレートの例を示します。test.xml
<document>
<table cols="2" widths="30mm 50mm">
<tr>
<td>氏名</td>
<td id="field1"></td>
</tr>
<tr>
<td>年齢</td>
<td id="field2"></td>
</tr>
<tr>
<td>職業</td>
<td id="field3"></td>
</tr>
</table>
</document>
<table cols="2" widths="30mm 50mm">
<tr>
<td>氏名</td>
<td id="field1"></td>
</tr>
<tr>
<td>年齢</td>
<td id="field2"></td>
</tr>
<tr>
<td>職業</td>
<td id="field3"></td>
</tr>
</table>
</document>
td要素のid属性でデータを埋め込むセルを指定します。上の例ではfield1に氏名、field2に年齢、field3に職業のデータが埋め込まれます。
WEB-INFの下にtemplateフォルダを作成し、このファイルを起きます。
JSPコード
次にこのテンプレートを使ってPDFを生成するJSPコードを示します。<%@ page contentType="text/html; charset=utf-8"%>
<%@ page import="java.util.ArrayList"%>
<%@ page import="java.util.HashMap"%>
<%@ page import="java.io.ByteArrayOutputStream"%>
<%@ page import="java.io.File"%>
<%@ page import="java.io.PrintWriter"%>
<%@ page import="jp.veltec.pdf.TableBuilder"%>
<%
try{
//step1
response.setContentType("application/pdf");
//step2
ByteArrayOutputStream baos = new ByteArrayOutputStream();
TableBuilder tableBuilder = new TableBuilder(baos);
//step3
String strWebInfPath = this.getServletContext().getRealPath("WEB-INF");
File template = new File(strWebInfPath + "/template/test.xml");
tableBuilder.setTemplateFile(template);
//step4
HashMap<String,String> hm = new HashMap<String,String>();
hm.put("field1","鈴木一朗");
hm.put("field2","30歳");
hm.put("field3","会社員");
//step5
tableBuilder.addPage(hm);
//step6
tableBuilder.close();
ServletOutputStream outstream = response.getOutputStream();
baos.writeTo(outstream);
outstream.flush();
baos=null;
}catch(Exception e){
e.printStackTrace();
response.setContentType("text/html; charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.println("<HTML><HEAD><TITLE>Test</TITLE></HEAD><BODY>");
writer.println(e.getMessage()+"<BR>");
for(StackTraceElement ele:e.getStackTrace()){
writer.println(ele.toString());
writer.println("<BR>");
}
writer.println("</BODY>");
writer.close();
}
%>
<%@ page import="java.util.ArrayList"%>
<%@ page import="java.util.HashMap"%>
<%@ page import="java.io.ByteArrayOutputStream"%>
<%@ page import="java.io.File"%>
<%@ page import="java.io.PrintWriter"%>
<%@ page import="jp.veltec.pdf.TableBuilder"%>
<%
try{
//step1
response.setContentType("application/pdf");
//step2
ByteArrayOutputStream baos = new ByteArrayOutputStream();
TableBuilder tableBuilder = new TableBuilder(baos);
//step3
String strWebInfPath = this.getServletContext().getRealPath("WEB-INF");
File template = new File(strWebInfPath + "/template/test.xml");
tableBuilder.setTemplateFile(template);
//step4
HashMap<String,String> hm = new HashMap<String,String>();
hm.put("field1","鈴木一朗");
hm.put("field2","30歳");
hm.put("field3","会社員");
//step5
tableBuilder.addPage(hm);
//step6
tableBuilder.close();
ServletOutputStream outstream = response.getOutputStream();
baos.writeTo(outstream);
outstream.flush();
baos=null;
}catch(Exception e){
e.printStackTrace();
response.setContentType("text/html; charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.println("<HTML><HEAD><TITLE>Test</TITLE></HEAD><BODY>");
writer.println(e.getMessage()+"<BR>");
for(StackTraceElement ele:e.getStackTrace()){
writer.println(ele.toString());
writer.println("<BR>");
}
writer.println("</BODY>");
writer.close();
}
%>
step1
responseオブジェクトにContentTypeをセットします。JSPからバイナリなどHTMLデータではないデータを送信する場合に必要な設定です。step2
新たなByteArrayOutputStreamを作成してTableBuilderのコンストラクタに渡します。step3
TableBuildernにテンプレートファイルをセットします。step4
新たなHashMapを作成してテンプレートに埋め込むデータをセットします。step5
埋め込むデータをセットしたHashMapオブジェクトをTableBuildernのaddPageメソッド渡します。ここでPDFのページが生成されます。別のデータをセットしてaddPageメソッドを呼べば複数のページを1つのファイルに出力することができます。step5
TableBuildernをクローズして生成されたPDFデータを送信します。フォントやセルを細かく設定すればもう少し見栄えの良い帳票を作ることができます。以下にPdfBuilderのバイナリとソース、サンプルを貼っておきます。
現在、このネタで本を書いています。ご意見ご要望などがあれば是非コメントください。
投稿:竹形 誠司[takegata]/2011年 05月 20日 11時 20分
/更新:2012年 09月 21日 23時 56分