リストの使い方
Java用PDFライブラリ「iText」は、JavaプログラムからPDFファイルを生成したい場合に便利なライブラリである。本稿では、iTextでリストおよびテーブルのコンテンツを挿入する方法について解説する。
まずリストについては、リスト本体を表すcom.itextpdf.text.Listクラスと、リストの項目を表すcom.itextpdf.text.ListItemクラスを利用して作成する。この2つはいずれも前回出てきたElementインタフェースをimplementsしたものである。ListとListItemの基本的な使い方は次の通りだ。
リスト1
List list = new List(List.UNORDERED);
list.add(new ListItem("アイテム1", ipam12b));
list.add(new ListItem("アイテム2", ipam12b));
list.add(new ListItem("アイテム3", ipam12b));
Listのコンストラクタの引数にはList.ORDEREDまたはList.UNORDEREDを渡すことで、項目に対するナンバリングを行うか否かを指定することができる。項目を追加するには、addメソッドを用いてListItemオブジェクトを渡せばよい。ListItemのコンストラクタの第2引数に指定しているのはFontオブジェクトである。日本語を使用したい場合には、この例のようにコンストラクタにFontオブジェクトを渡しておく必要がある。addメソッドにはそのほかにStringオブジェクトや、ListItem以外のElementオブジェクトを渡すこともできる。たとえばネストされたリストを作成したい場合にはaddメソッドにListオブジェクトを渡せばよい。
以下に、リストを利用したPDFファイルを出力するプログラム例を示す。ここではListのaddメソッドに別のListオブジェクトを渡すことで、ネストされたリストを作成している。
リスト2
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.List;
import com.itextpdf.text.ListItem;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ITextSample4 {
public static void main(String[] args) {
// ドキュメントオブジェクトを作成
Document document = new Document(PageSize.A4, 30, 30, 40, 50);
try {
// 出力ストリームを作成
PdfWriter.getInstance(document,
new FileOutputStream("output4.pdf"));
// フォントの作成
BaseFont ipaMincho =
BaseFont.createFont("/usr/local/share/font-ipa/ipam.otf",
BaseFont.IDENTITY_H, true);
Font ipam12 = new Font(ipaMincho, 12);
Font ipam12b = new Font(ipaMincho, 12, Font.BOLD);
// ドキュメントへの文字の書き込み
document.open();
// リストを作成
List list = new List(List.UNORDERED);
list.add(new ListItem("攻略! ツール・ド・プログラミング", ipam12b));
List listTool = new List(List.ORDERED);
listTool.setIndentationLeft(20f);
listTool.add(new ListItem("Web標準技術を活用したOSSのRIAプラットフォーム「Appcelerator Titanium」", ipam12));
listTool.add(new ListItem("アプリケーションへの組込みも可能な「Apache FtpServer」", ipam12));
listTool.add(new ListItem("Ftpletを用いてApache FtpServerの動作をカスタマイズする", ipam12));
list.add(listTool);
list.add(new ListItem("FileMaker×PHPで作る、簡単・便利なWebアプリ", ipam12b));
List listFileMaker = new List(List.ORDERED);
listFileMaker.setIndentationLeft(20);
listFileMaker.add(new ListItem("まずは2大ライブラリを比較", ipam12));
listFileMaker.add(new ListItem("レコードの登録 - 各種関数・メソッドの紹介", ipam12));
listFileMaker.add(new ListItem("FileMaker のCRUDはこれで完璧! - FMEdit()~FMDelete()まで", ipam12));
list.add(listFileMaker);
document.add(list);
document.close();
} catch (DocumentException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
このプログラムを実行すると、図1のようなPDFファイルが生成される。
テーブルの使い方
テーブルをPDF文書に埋め込みたい場合には、com.itextpdf.text.pdf.PdfPTableクラスを利用する。PdfPTableクラスにはaddCellというメソッドがあり、これを使って個々のセルを追加することができる。セル自身はcom.itextpdf.text.pdf.PdfPCellというクラスで表される。PdfPTableクラスとPdfPCellクラスを用いてテーブルオブジェクトを作成する方法を以下に示す。
リスト3
// テーブルオブジェクトの作成
PdfPTable table = new PdfPTable(2); // 2列のテーブル
// セルを追加
PdfPCell cell1 = new PdfPCell(new Paragraph("セル1", ipam12b));
PdfPCell cell2 = new PdfPCell(new Paragraph("セル2", ipam12b));
PdfPCell cell3 = new PdfPCell(new Paragraph("セル3", ipam12b));
PdfPCell cell4 = new PdfPCell(new Paragraph("セル4", ipam12b));
table.addCell(cell1);
table.addCell(cell2);
table.addCell(cell3);
table.addCell(cell4);
基本的には列数を指定してPdfPTableオブジェクトを生成し、それに対してaddCellメソッドでPdfPCellオブジェクトを追加していけばよい。PdfPCellオブジェクトはParagraphなどのElementオブジェクトを指定して生成する。SwingのGridLayoutを使う場合に似ている。ここでは2列のテーブルを作成しているので、このコードによって生成されるテーブルは図2のようになる。
addCellメソッドでは、そのほかにImageオブジェクトやPdfPTableオブジェクトなどを追加することができる。PdfPTableオブジェクトを追加した場合は、セルの中にテーブルが入っている図3のようなテーブルが出力される。
列ごとに幅を変えたい場合には、setWidthsメソッドを使用する。このメソッドには、各列の幅の割合を格納したfloat配列を渡す。たとえば、4列のテーブルの幅の割合を4:1:1:1にしたい場合には次のように指定する。
リスト4
PdfPTable table = new PdfPTable(4); // 4列のテーブル
float[] columnWidths = {4, 1, 1, 1}; // 列の幅
table.setWidths(columnWidths);
複数の列や行にまたがるセルを作成したい場合には、PdfPCellクラスのsetColspanメソッドおよびsetRowspanメソッドを利用する。これらのメソッドに列数または行数を渡せば、そのセルは指定された列数/行数にまたがったセルとなる。たとえば2列3行にまたがるセルの場合は次のようになる。
リスト5
PdfPCell cell = new PdfPCell(new Paragraph("セル", ipam12b));
cell.setColspan(2); // セルを2列分結合
cell.setRowspan(3); // セルを3行分結合
以上を踏まえて、簡単なテーブルを構成したプログラムの例を示す。FontオブジェクトやDocumentオブジェクトを生成する部分についてはリストの例と同様なのでここでは省略する。
リスト6
// テーブルオブジェクトの作成
PdfPTable table = new PdfPTable(4); // 4列のテーブル
float[] columnWidths = {4, 1, 1, 1}; // 列の幅
table.setWidths(columnWidths);
// 1行目
PdfPCell cell11 = new PdfPCell(new Paragraph("品名", ipam12b));
PdfPCell cell12 = new PdfPCell(new Paragraph("単価", ipam12b));
PdfPCell cell13 = new PdfPCell(new Paragraph("数量", ipam12b));
PdfPCell cell14 = new PdfPCell(new Paragraph("金額", ipam12b));
table.addCell(cell11);
table.addCell(cell12);
table.addCell(cell13);
table.addCell(cell14);
// 2行目
PdfPCell cell21 = new PdfPCell(new Paragraph("産地直送りんご 12個入り", ipam12));
PdfPCell cell22 = new PdfPCell(new Paragraph("1200", ipam12));
PdfPCell cell23 = new PdfPCell(new Paragraph("4", ipam12));
PdfPCell cell24 = new PdfPCell(new Paragraph("4800", ipam12));
table.addCell(cell21);
table.addCell(cell22);
table.addCell(cell23);
table.addCell(cell24);
// 3行目
PdfPCell cell31 = new PdfPCell(new Paragraph("100%アップルジュース 180ml 10本入り", ipam12));
PdfPCell cell32 = new PdfPCell(new Paragraph("2000", ipam12));
PdfPCell cell33 = new PdfPCell(new Paragraph("2", ipam12));
PdfPCell cell34 = new PdfPCell(new Paragraph("4000", ipam12));
table.addCell(cell31);
table.addCell(cell32);
table.addCell(cell33);
table.addCell(cell34);
// 4行目以降
PdfPCell cell41 = new PdfPCell(new Paragraph("合計", ipam12b));
cell41.setRowspan(3); // セルを3行分結合
table.addCell(cell41);
PdfPCell cell43 = new PdfPCell(new Paragraph("小計", ipam12b));
cell43.setColspan(2); // セルを2列分結合
table.addCell(cell43);
PdfPCell cell44 = new PdfPCell(new Paragraph("8800", ipam12));
table.addCell(cell44);
PdfPCell cell53 = new PdfPCell(new Paragraph("消費税", ipam12b));
cell53.setColspan(2); // セルを2列分結合
table.addCell(cell53);
PdfPCell cell54 = new PdfPCell(new Paragraph("440", ipam12));
table.addCell(cell54);
PdfPCell cell63 = new PdfPCell(new Paragraph("総額", ipam12b));
cell63.setColspan(2); // セルを2列分結合
table.addCell(cell63);
PdfPCell cell64 = new PdfPCell(new Paragraph("9240", ipam12));
table.addCell(cell64);
// ドキュメントにテーブルを追加
document.add(table);
このプログラムによって生成されるPDFファイルは図4のようになる。
このようにiTextはAWTやSwingとは異なる独自のドキュメント構造を持つものの、使用方法はよく似ていて始めて使う場合でも混乱することはない。開発チームによれば、もともとはSwingのドキュメント構造を利用することを考えたが、それだと複雑すぎるためよりシンプルな仕組みを再構築したとのこと。ここで紹介した以外にもさまざまなコンテンツが用意されていおり、きわめて有用性の高いライブラリである。