Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

iTextを利用してJavaからPDF形式の帳票を出力する

オープンソースのPDF生成ライブラリを使用した帳票の出力

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2005/06/01 10:00

現在のWebシステムにおいて帳票の出力を行う場合、PDF形式が選択されることが一般的になっています。この記事では、「iText」というオープンソースのライブラリを活用して、PDFの出力を行う方法を解説します。

はじめに

 現在のWebシステムにおいて帳票の出力を行う場合、PDF形式が選択されることが一般的になっています。その理由としては、データサイズをコンパクトにすることができる、情報の改ざんを防止できる、などが挙げられます。一般ユーザにも普及していますので、システム開発時に顧客からPDF形式での情報の出力を求められることも多いのではないでしょうか。

 この記事では、「iText」というライブラリを活用して、PDFの出力を行う方法を解説します。

対象読者

 Javaプログラミングで開発を行った経験のある方、および、Javaプログラミングに興味をお持ちの方を対象としています。

必要な環境

 このサンプルアプリケーションを動作させるには、以下のソフトウェアが最低限必要です。環境についての詳細や設定方法については、サーバサイド技術の学び舎 - WINGSにある「サーバサイド環境構築設定」を参照してください。

 サンプルは、必要なjarファイルを含めてwarファイル形式で提供しています。記事上部リンクからファイル「itext.war」をダウンロードし、アプリケーションサーバに配置(ディプロイ)して下さい(Tomcatの場合は、「webapps」フォルダ配下にwarファイルを設定して、再起動して下さい)。アプリケーションサーバ起動後に、「http://localhost:8080/itext」にアクセスすると、サンプルを動作させることができます(ホスト名・ポート番号はご自身の環境に合わせて変更して下さい)。

iTextとは

 iTextはPDFをJavaで扱うためのライブラリとしてオープンソースで開発されています。使用する際は、MPLLGPLから、いずれかのライセンスを選択することとなっています。

 ライブラリはjarファイル形式で配布されています。利用する際は、iTextのサイトから「itext-1.3.jar」をダウンロードして下さい。また、日本語を使用する際は、別途日本語フォント用のライブラリが必要となりますのでこちらのサイトから「iTextAsian.jar」をダウンロードして下さい。

サンプルアプリケーションの概要

 サンプルとして、iTextを使用して動的にPDFを作成するWebアプリケーションを紹介します。

 処理の流れは、以下のようになります。

  1. ブラウザより名前を入力して送信。
  2. リクエストを受け取ったサーブレットが、PDF形式でデータをクライアントに返信する。
  3. ブラウザに動的に作成されたPDFが表示される。

 サンプルとして作成するPDFは、業務システムで一般的に作成されるような一覧表をイメージしています。

動的に作成したPDFをブラウザに表示
動的に作成したPDFをブラウザに表示

iTextを使用した動的なPDF作成

 iTextでは、出力するPDF全体をDocumentクラスとして表現しています。文字列はPhraseクラスやParagraphクラス、表はTableクラスで表現し、Document#addメソッドでDocumentクラスにそれぞれのオブジェクトを追加して、出力するPDFを作成する仕組みになっています。

 それでは、詳細なアプリケーションの流れを見ていきましょう。

名前の入力

入力画面
入力画面

 入力画面の「送信」ボタンをクリックすると、itextServletクラスのdoPostメソッドが実行されます。

 ここでは、クライアントから送信されてきた名前をrequestインスタンスから取り出しています。

「iTextServlet.java」 抜粋
public class itextServlet extends HttpServlet {
  protected void doPost(HttpServletRequest request,
    HttpServletResponse response)
      throws ServletException, IOException {
      
      //入力画面から送信されてきた名称を表示します。
      request.setCharacterEncoding("Shift-JIS");
      String strName =request.getParameter("input_name");;
    
    //(以下略)
  }

PDF出力用クラスの定義

 文書オブジェクトを作成して、PDF出力の準備をします。

「iTextServlet.java」 抜粋
//出力用のStreamをインスタンス化します。
ByteArrayOutputStream byteout = new ByteArrayOutputStream();

//文書オブジェクトを生成
//ページサイズを設定します。
Document doc = new Document(PageSize.A4, 50, 50, 50, 50); 

try {
    //アウトプットストリームをPDFWriterに設定します。
    PdfWriter pdfwriter = PdfWriter.getInstance(doc, byteout);
}

 Documentクラスは、出力するPDFを表す文書オブジェクトです。Documentクラスのコンストラクタにて、出力するPDFのページサイズと上下左右の余白を設定できます(省略した場合は、デフォルトでA4サイズとなります)。PdfWriterクラスは、PDFの出力を行うクラスです。PdfWriterクラスに、出力するDocumentインスタンスと、出力先としてByteArrayOutputStreamインスタンスを設定します。

 これでPDF出力の初期設定は完了です。

フォントの設定

 出力するフォントの設定を行います。

「iTextServlet.java」 抜粋
/* フォント設定部 */
//(ゴシック15pt(太字)
Font font_header =
    new Font(BaseFont.createFont("HeiseiKakuGo-W5","UniJIS-UCS2-H",
    BaseFont.NOT_EMBEDDED),15,Font.BOLD);
//ゴシック11pt
Font font_g11 =
    new Font(BaseFont.createFont("HeiseiKakuGo-W5","UniJIS-UCS2-H",
    BaseFont.NOT_EMBEDDED),11);
//ゴシック10pt
Font font_g10 =
    new Font(BaseFont.createFont("HeiseiKakuGo-W5","UniJIS-UCS2-H",
    BaseFont.NOT_EMBEDDED),10);
//明朝10pt
Font font_m10 =
    new Font(BaseFont.createFont("HeiseiMin-W3", "UniJIS-UCS2-HW-H",
    BaseFont.NOT_EMBEDDED),10);
//ゴシック11pt(下線あり)
Font font_underline_11 =
    new Font(BaseFont.createFont("HeiseiKakuGo-W5","UniJIS-UCS2-H",
    BaseFont.NOT_EMBEDDED),11,Font.UNDERLINE);
//ゴシック11pt(赤)
Font font_red_11 =
    new Font(BaseFont.createFont("HeiseiKakuGo-W5","UniJIS-UCS2-H",
    BaseFont.NOT_EMBEDDED),11);
font_red_11.setColor(new Color(255,0,0));

 フォントの設定には、Fontクラスを使用します。文書を出力する際にフォント情報としてFontクラスのインスタンスを設定します。何度も使用するようなフォントは処理の初期段階で設定しておき、再利用すると処理が冗長にならずに良いと思います。

 Fontクラスのインスタンスを作成する際、Fontクラスのコンストラクタの第1引数にフォントの種類を表すBaseFontクラスのインスタンスを渡しています。第2引数にはフォントタイプ(太字、下線付き)を指定するFontクラスの定数を、また、第3引数にはint型で指定したフォントサイズを渡します。フォントに色の設定を行う場合は、Font#setColorメソッドを使用してRGB形式で色を指定して下さい。

 なお、日本語フォントを使用する際は、BaseFont#createFontメソッドにてBaseFontインスタンスを作成して下さい。BaseFont#createFontの第1引数には使用するフォント名を、第2引数にはエンコーディング名を設定します(日本語のフォント、エンコーディングは「iTextAsian.jar」に格納されています)。

iTextで利用可能な日本語フォント
フォント名説明
KozMinPro-Regular明朝体
HeiseiMin-W3明朝体
HeiseiKakuGo-W5ゴシック体
iTextで利用可能なエンコーディング
エンコーディング名説明
UniJIS-UCS2-HAdobe日本語文字のUniCode用エンコーディング
UniJIS-UCS2-VUniJIS-UCS2-Hの縦書きエンコーディング
UniJIS-UCS2-HW-HUniJIS-UCS2-Hのうち、プロポーショナル文字のみ半角文字に変更したエンコーディング
UniJIS-UCS2-HW-VUniJIS-UCS2-HW-Hの縦書きエンコーディング

PDFファイルの説明の設定

 出力されたPDFに作成者を設定します。

「iTextServlet.java」 抜粋
//出力するPDFに説明を付与します。
doc.addAuthor("岡 雅久"); 
doc.addSubject("iTextサンプル");

 出力するPDFに作成者と説明を設定することができます。Document#addAuthorメソッドで作成者名を、Document#addSubjectメソッドで文書の説明を設定します。

PDFのプロパティ
PDFのプロパティ

ヘッダーとフッターの設定

 出力するPDFのヘッダーとフッターを設定します。

「iTextServlet.java」抜粋
//ヘッダーの設定をします。
HeaderFooter header = new HeaderFooter(
    new Phrase("○○商事 月間売上実績", font_header), false);
header.setAlignment(Element.ALIGN_CENTER);
doc.setHeader(header);
//フッターの設定をします。
HeaderFooter footer = new HeaderFooter(
    new Phrase("--"), new Phrase("--"));
footer.setAlignment(Element.ALIGN_CENTER);
footer.setBorder(Rectangle.NO_BORDER);
doc.setFooter(footer);

 ヘッダーとフッターの設定には、HeaderFooterクラスを使用します。

 ヘッダーに設定したい文字列は、PhraseクラスにFontクラスのインスタンスと合わせて設定します。HeaderFooter#setAlignmentメソッドを使用して表示位置を調整して、Documnet#setHeaderメソッドでPDFに出力する設定を行います。表示位置の指定の際には、Elementクラスに保持している定数を使用すると便利です。

 また、フッターの場合も同様に、Phraseクラスに出力情報を設定し、Documnet#setFooterメソッドでPDFに出力する設定を行います。なお、HeaderFooterクラスのコンストラクタで、入力引数を2つ取るメソッドを使用すると、ページナンバーを出力することができます。

ページナンバーの出力
ページナンバーの出力

文書の出力開始

 PDF文書の出力を開始します。

「iTextServlet.java」 抜粋
//文章の出力を開始します。
doc.open(); 

/* 売上実績表のテーブルを作成します */
//帳票明細の条件部分を設定します。
doc.add(new Paragraph("2005年5月実績", font_red_11));          
Paragraph para_1 = new Paragraph("担当者:" +  strName, font_g11);
para_1.setAlignment(Element.ALIGN_RIGHT);
doc.add(para_1);    
doc.add(new Paragraph(""));
Paragraph para_2 =
    new Paragraph("商品名:△△△△", font_underline_11);    
para_2.setAlignment(Element.ALIGN_LEFT);
doc.add(para_2);

 文書の出力を開始する際は、Document#openメソッドを使用します(ヘッダー、フッター、PDFの作成者情報は文書出力開始前に設定しておく必要があります)。出力したい文字列は、ParagraphクラスにFontクラスのインスタンスと合わせて設定して、Documnet#addメソッドでPDFに出力します。Paragraphクラスは、Phraseクラスを継承しているので基本的な性質は同じですが、ParagraphクラスではsetAlignmentメソッドを使用した表示位置の指定などの体裁の設定ができます。

表の出力

 業務アプリケーションで帳票を作成する際、表の作成はほぼ必須ではないでしょうか。iTextではライブラリに用意されたクラスを使用することで簡単に表を作成できます。

「iTextServlet.java」 テーブル作成部分抜粋1
//帳票明細の明細行を設定します。
Table uriage_table = new Table(4);

//売上テーブル全体の幅を設定します。
uriage_table.setWidth(100);
//テーブル各列の幅をパーセンテージで設定します。
int uriage_table_width[] = {10,20,40,30};    
uriage_table.setWidths(uriage_table_width);    
//テーブルのデフォルトの表示位置(横)を設定します。
uriage_table.setDefaultHorizontalAlignment(Element.ALIGN_CENTER);
//テーブルのデフォルトの表示位置(縦)を設定します。
uriage_table.setDefaultVerticalAlignment(Element.ALIGN_MIDDLE);
//テーブルの余白を設定します。
uriage_table.setPadding(3);
//テーブルのセル間の間隔を設定します。
uriage_table.setSpacing(0);
//テーブルの線の色を設定します。
uriage_table.setBorderColor(new Color(0, 0, 0));

 iTextで表を作成するには、Tableクラスを使用します。インスタンス化する際に引数として作成する表の列数を設定します。Table#setWidthメソッドで表全体の表示幅をパーセンテージで設定します。また、Table#setWidthsメソッドで各列の幅をパーセンテージで設定します。

「iTextServlet.java」 テーブル作成部分抜粋2
//明細行の項目名部分のセルの設定を行います
//(セルに網掛け設定を行います)。
Cell cell_11 = new Cell(new Phrase("順位", font_g10));
cell_11.setGrayFill(0.8f);
Cell cell_21 = new Cell(new Phrase("顧客コード", font_g10));
cell_21.setGrayFill(0.8f);
Cell cell_31 = new Cell(new Phrase("顧客名称", font_g10));
cell_31.setGrayFill(0.8f);
Cell cell_41 = new Cell(new Phrase("金額", font_g10));
cell_41.setGrayFill(0.8f);

//テーブルにセルを設定します
uriage_table.addCell(cell_11);
uriage_table.addCell(cell_21);
uriage_table.addCell(cell_31);
uriage_table.addCell(cell_41);

 表の各項目を設定するには、Cellクラスを使用します。出力したい文字列は、PhraseクラスにFontクラスのインスタンスと合わせて設定し、Cellクラスに格納します。セルに網掛け設定を行いたい場合は、Cell.setGrayFillメソッドを使用します。作成したCellクラスは、Table#addCellメソッドで表に追加します。

「iTextServlet.java」 テーブル作成部分抜粋3
//合計行を出力します。
Cell cell_goukei = new Cell(new Phrase("合計", font_g10));
cell_goukei.setGrayFill(0.8f);
cell_goukei.setColspan(3);
uriage_table.addCell(cell_goukei);
Cell cell_sum = new Cell(new Phrase("136,900", font_m10));
cell_sum.setHorizontalAlignment(Element.ALIGN_RIGHT);
uriage_table.addCell(cell_sum);

//テーブルをドキュメントオブジェクトに追加します。
doc.add(uriage_table);

 Cell#setColspanメソッドで列の結合、Cell#setRowspanメソッドで行の結合が行えます。

 Cellクラスの設定が完了したTableクラスは、Documnet#addメソッドでPDFに出力します。

クライアントへの出力

 出力したPDFを、クライアントのブラウザへ送信します。

「iTextServlet.java」 抜粋
public class itextServlet extends HttpServlet {
  protected void doPost(HttpServletRequest request,
    HttpServletResponse response)
      throws ServletException, IOException {

    //(省略)

    // 出力を終了します。
    doc.close(); 
   
    // ブラウザへのデータを送信します
    //(出力するコンテキストタイプにPDFを指定します)。
    response.setContentType("application/pdf");
    response.setContentLength(byteout.size());
    OutputStream out = response.getOutputStream();
    out.write(byteout.toByteArray());
    out.close();

 Documnet#closeメソッドにてPDFへの出力処理を完了します。出力したPDFは、OutputStream#writeメソッドでクライアントに送信します。

 また、PDFタイプのデータであることをクライアントのブラウザに伝えるために、HttpServletResponse#setContentTypeにてコンテンツタイプ(MIME)をPDFとして設定しています。

 以上で、PDFファイルを動的に作成する処理は終了です。

iTextに関するTips
 iTextのサイトにあるチュートリアルは大変充実しており、参考になるサンプルがコーディング例とともに多数用意されていて、英語が苦手であっても十分参考になります(中には、大変ユニークなサンプルもあります)。iTextを利用される際は、ぜひ一度ご覧下さい。

まとめ

 iTextの主なライブラリクラスをまとめます。

クラス名説明
Document出力するPDF文書を表すクラスです。
PdfWriter「Document」クラスをもとに、指定された出力先にPDF出力を行うクラスです。
Fontフォントを指定するためのクラスです。色の指定も可能です。
HeaderFooterヘッダー、フッターを設定するためのクラスです。
Chunk文字列の最小単位を表すクラスです。単一のフォントで表現されます。
Phrase文字列を設定するためのクラスです。複数のChunkクラスで構成されます。Chunkクラスを使用せずに直接文字列を設定することも可能です。
Paragraph文字列を設定するためのクラスで、Phraseクラスを継承しています。このクラス独自にインデントや表示位置の設定ができます。複数のChunkクラス、Phraseクラスで構成されますが、直接文字列を設定することも可能です。
Table表の出力を行うためのクラスです。
Cell表の各セルの設定を行うためのクラスです。

 本稿では、簡単な業務帳票を動的に作成する処理を通して、iTextライブラリでPDFを作成する基本的な処理について紹介しました。PDFを作成する基本的な処理はサンプルのとおりですが、iTextにはまだいろいろなライブラリが用意されていますので、興味のある方は、iText付属のAPIドキュメントなどをぜひご一読ください。

参考資料

  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • WINGSプロジェクト 岡 雅久(オカ マサヒサ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

All contents copyright © 2005-2018 Shoeisha Co., Ltd. All rights reserved. ver.1.5