iTextのPdfReader
iText PDFライブラリには既存のPDFデータを読み込むPdfReaderというAPIがあります。私が作ったPdfBuilderでは、この機能を使って既存のPDFデータに文字をオーバーレイできるような仕掛けがあります。これを使ったJSPコードの例を紹介します。PdfBuilderの使い方については前のエントリを参照してください。既存のPDFデータ
たとえば、次のようなPDFデータがあったとします。
既存のPDF
上のような帳票の場合、宛名と明細と備考の3つのパートに分けてテーブルを作成するといい感じです。
XMLテンプレートの作成
<pdf>要素で読み込むPDFファイルを指定し、文字列を乗せたい位置にセルが来るようにテーブルを調整します。<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<document size="A5L">
<pdf src="invoice.pdf"/>
<table cols="1" position="absolute" left="50mm" top="28mm" widths="50mm" border-width="0mm">
<tr>
<td id="client-name" font-size="14pt" character-spacing="3mm"></td>
</tr>
</table>
<table cols="4" position="absolute" left="20mm" top="46mm" widths="82.5mm 31.5mm 21mm 31mm" height="6.8mm" border-width="0mm">
<tr>
<td id="item1"></td>
<td id="price1" align-h="right"></td>
<td id="qty1" align-h="right"></td>
<td id="amount1" align-h="right"></td>
</tr>
<tr>
<td id="item2"></td>
<td id="price2" align-h="right"></td>
<td id="qty2" align-h="right"></td>
<td id="amount2" align-h="right"></td>
</tr>
<tr>
<td id="item3"></td>
<td id="price3" align-h="right"></td>
<td id="qty3" align-h="right"></td>
<td id="amount3" align-h="right"></td>
</tr>
<tr>
<td id="item4"></td>
<td id="price4" align-h="right"></td>
<td id="qty4" align-h="right"></td>
<td id="amount4" align-h="right"></td>
</tr>
<tr>
<td id="item5"></td>
<td id="price5" align-h="right"></td>
<td id="qty5" align-h="right"></td>
<td id="amount5" align-h="right"></td>
</tr>
<tr>
<td id="item6"></td>
<td id="price6" align-h="right"></td>
<td id="qty6" align-h="right"></td>
<td id="amount6" align-h="right"></td>
</tr>
<tr>
<td id="item7"></td>
<td id="price7" align-h="right"></td>
<td id="qty7" align-h="right"></td>
<td id="amount7" align-h="right"></td>
</tr>
<tr>
<td id="item8"></td>
<td id="price8" align-h="right"></td>
<td id="qty8" align-h="right"></td>
<td id="amount8" align-h="right"></td>
</tr>
<tr>
<td id="item9"></td>
<td id="price9" align-h="right"></td>
<td id="qty9" align-h="right"></td>
<td id="amount9" align-h="right"></td>
</tr>
<tr>
<td colspan="3"></td>
<td id="total" align-h="right" font-style="bold"></td>
</tr>
</table>
<table cols="1" position="absolute" left="20mm" top="123mm" height="13mm" widths="165mm" border-width="0mm">
<tr>
<td id="memo"></td>
</tr>
</table>
</document>
<document size="A5L">
<pdf src="invoice.pdf"/>
<table cols="1" position="absolute" left="50mm" top="28mm" widths="50mm" border-width="0mm">
<tr>
<td id="client-name" font-size="14pt" character-spacing="3mm"></td>
</tr>
</table>
<table cols="4" position="absolute" left="20mm" top="46mm" widths="82.5mm 31.5mm 21mm 31mm" height="6.8mm" border-width="0mm">
<tr>
<td id="item1"></td>
<td id="price1" align-h="right"></td>
<td id="qty1" align-h="right"></td>
<td id="amount1" align-h="right"></td>
</tr>
<tr>
<td id="item2"></td>
<td id="price2" align-h="right"></td>
<td id="qty2" align-h="right"></td>
<td id="amount2" align-h="right"></td>
</tr>
<tr>
<td id="item3"></td>
<td id="price3" align-h="right"></td>
<td id="qty3" align-h="right"></td>
<td id="amount3" align-h="right"></td>
</tr>
<tr>
<td id="item4"></td>
<td id="price4" align-h="right"></td>
<td id="qty4" align-h="right"></td>
<td id="amount4" align-h="right"></td>
</tr>
<tr>
<td id="item5"></td>
<td id="price5" align-h="right"></td>
<td id="qty5" align-h="right"></td>
<td id="amount5" align-h="right"></td>
</tr>
<tr>
<td id="item6"></td>
<td id="price6" align-h="right"></td>
<td id="qty6" align-h="right"></td>
<td id="amount6" align-h="right"></td>
</tr>
<tr>
<td id="item7"></td>
<td id="price7" align-h="right"></td>
<td id="qty7" align-h="right"></td>
<td id="amount7" align-h="right"></td>
</tr>
<tr>
<td id="item8"></td>
<td id="price8" align-h="right"></td>
<td id="qty8" align-h="right"></td>
<td id="amount8" align-h="right"></td>
</tr>
<tr>
<td id="item9"></td>
<td id="price9" align-h="right"></td>
<td id="qty9" align-h="right"></td>
<td id="amount9" align-h="right"></td>
</tr>
<tr>
<td colspan="3"></td>
<td id="total" align-h="right" font-style="bold"></td>
</tr>
</table>
<table cols="1" position="absolute" left="20mm" top="123mm" height="13mm" widths="165mm" border-width="0mm">
<tr>
<td id="memo"></td>
</tr>
</table>
</document>
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="javax.xml.parsers.DocumentBuilder"%>
<%@ page import="javax.xml.parsers.DocumentBuilderFactory"%>
<%@ page import="org.w3c.dom.NodeList"%>
<%@ page import="jp.veltec.pdf.TableBuilder"%>
<%
try{
String mTemplateFile = request.getParameter("template_file");
response.setContentType("application/pdf");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
TableBuilder tableBuilder = new TableBuilder(baos);
String strWebInfPath = this.getServletContext().getRealPath("WEB-INF");
File template = new File(strWebInfPath + "/template/table_print_14.xml");
tableBuilder.setImagePath(strWebInfPath + "/template");
tableBuilder.setTemplateFile(template);
HashMap<String,String> hm = new HashMap<String,String>();
hm.put("client-name","鈴木一朗");
hm.put("item1","バット");
hm.put("price1","¥10,000");
hm.put("qty1","2");
hm.put("amount1","¥20,000");
hm.put("item2","ボール");
hm.put("price2","¥1,000");
hm.put("qty2","5");
hm.put("amount2","¥5,000");
hm.put("item3","グローブ");
hm.put("price3","¥20,000");
hm.put("qty3","1");
hm.put("amount3","¥20,000");
hm.put("total","¥45,000");
hm.put("memo","これはテストです。");
tableBuilder.addPage(hm);
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="javax.xml.parsers.DocumentBuilder"%>
<%@ page import="javax.xml.parsers.DocumentBuilderFactory"%>
<%@ page import="org.w3c.dom.NodeList"%>
<%@ page import="jp.veltec.pdf.TableBuilder"%>
<%
try{
String mTemplateFile = request.getParameter("template_file");
response.setContentType("application/pdf");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
TableBuilder tableBuilder = new TableBuilder(baos);
String strWebInfPath = this.getServletContext().getRealPath("WEB-INF");
File template = new File(strWebInfPath + "/template/table_print_14.xml");
tableBuilder.setImagePath(strWebInfPath + "/template");
tableBuilder.setTemplateFile(template);
HashMap<String,String> hm = new HashMap<String,String>();
hm.put("client-name","鈴木一朗");
hm.put("item1","バット");
hm.put("price1","¥10,000");
hm.put("qty1","2");
hm.put("amount1","¥20,000");
hm.put("item2","ボール");
hm.put("price2","¥1,000");
hm.put("qty2","5");
hm.put("amount2","¥5,000");
hm.put("item3","グローブ");
hm.put("price3","¥20,000");
hm.put("qty3","1");
hm.put("amount3","¥20,000");
hm.put("total","¥45,000");
hm.put("memo","これはテストです。");
tableBuilder.addPage(hm);
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();
}
%>
生成されたPDF
上のJSPコードを実行すると、次のようなPDFデータがブラウザに返されます。
生成されたPDFデータ
但し、勝手に編集できないようにパスワードで保護されているPDFは読み込めません。悪しからず。
投稿:竹形 誠司[takegata]/2011年 05月 21日 01時 46分
/更新:2011年 05月 21日 01時 49分