竹形誠司 ブログ
Java+MySQL+Tomcat    »トピック一覧
掲示板へのスパムが多いため、「ご質問」のコーナーはユーザー登録制とさせていただきました。お手数ですが、上の「新規ユーザーの登録」メニューより登録をお願いします。
帳票Web
アプリケーション

受注開発始めました
詳しくは こちら
竹形 誠司 著/ラトルズ刊
JSP帳票アプリケーション実践開発入門
JSP帳票アプリケーション
実践開発入門

JSP業務アプリケーション短期開発入門
JSP業務アプリケーション
短期開発入門

Java+MySQL+Tomcatで始めるWebアプリケーション構築入門
Java+MySQL+Tomcatで始めるWebアプリケーション構築入門

Java+MySQL+Tomcatで作る掲示板とブログ
Java+MySQL+Tomcatで作る
掲示板とブログ
XMLテンプレートを使って既存のPDFに文字をオーバーレイする
by 竹形 誠司[takegata]
iTextのPdfReader
iText PDFライブラリには既存のPDFデータを読み込むPdfReaderというAPIがあります。私が作ったPdfBuilderでは、この機能を使って既存のPDFデータに文字をオーバーレイできるような仕掛けがあります。これを使ったJSPコードの例を紹介します。PdfBuilderの使い方については前のエントリを参照してください。

既存のPDFデータ
たとえば、次のような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>

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();
}
%>

生成されたPDF
上のJSPコードを実行すると、次のようなPDFデータがブラウザに返されます。
生成されたPDFデータ
生成されたPDFデータ


但し、勝手に編集できないようにパスワードで保護されているPDFは読み込めません。悪しからず。
投稿:竹形 誠司[takegata]/2011年 05月 21日 01時 46分 /更新:2011年 05月 21日 01時 49分