ドキュメントを構成するさまざまな部品

前回はJavaプログラムでPDF文書を出力するためのライブラリである「iText」について紹介した。そこで示した例では、ドキュメントに追加するコンテンツとして文字列をセットしたcom.itextpdf.text.Paragraphオブジェクトを使用した。

Paragraphクラスは文字通り段落を表すクラスである。iTextにはParagraphと同様にドキュメントの構造上の部品を表すクラスがいくつか用意されており、それらはcom.itextpdf.text.Elementインタフェースをimplementsしている。Elementインタフェースをimplementsしたクラスのうち、代表的なものを以下に挙げる(パッケージはPdfPTable以外はすべてcom.itextpdf.text)。

  • Chunk - ドキュメントに追加するテキストの最小単位となる部品を表すクラス
  • Phrase - 句を表すクラスで、複数のChunkから構成される
  • Paragraph - 段落を表すクラスで、ChunkやPhraseから構成される。Phraseのサブクラスだが、インデントなどのレイアウト用パラメータを持つ
  • Section - セクション(節、項)を表すクラスで、Paragraphや他のSection、Listなどから構成される
  • Chapter - Sectionのサブクラスで、チャプター(章)を表す。Chapterの下に複数のSectionを追加することができる
  • ListItem - リストの内容を表すクラス。ListItemクラスはParagraphクラスを継承している
  • List - リストを表すクラスで、複数のListItemから構成される
  • Image - 画像(JPEG/PNG/GIF)を表すクラス
  • Anchor - Phraseのサブクラスで、リンクなどのアンカー部品を表す
  • Header - ヘッダー部品を表すクラス
  • com.itextpdf.text.pdf.PdfPTable - 表を表すクラス

多くのクラスは、コンテンツを追加するためのaddメソッドを備えている。addメソッドには構成要素となる他のElementオブジェクトや、Stringオブジェクトなどを渡すことができる。ただし、PhraseにParagraphを追加する場合のような、自身より大きな構成要素を表すオブジェクトの追加はできないようになっている。

以下に、これらのクラスを利用してPDF文書を作成するプログラム例を示す。

リスト1

import com.itextpdf.text.Chapter;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Section;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfWriter;

import java.io.*;

public class ITextSample2 {
    public static void main(String[] args) {
    // ドキュメントオブジェクトを作成
        Document document = new Document(PageSize.A4, 30, 30, 40, 50);

        try {
        // 出力ストリームを作成
            PdfWriter.getInstance(document,
                  new FileOutputStream("output2.pdf"));

        // フォントの作成
        BaseFont ipaMincho =
        BaseFont.createFont("/usr/local/share/font-ipa/ipam.otf",
                                BaseFont.IDENTITY_H, true);
        Font ipam12 = new Font(ipaMincho, 12);
        Font ipam12ib = new Font(ipaMincho, 12, Font.ITALIC | Font.BOLD);  // 太字斜体
        Font ipam16 = new Font(ipaMincho, 16);
        Font ipam18 = new Font(ipaMincho, 18);

        // ドキュメントへの文字の書き込み
            document.open();

        // チャプター1
        Chapter chapter1 = new Chapter(new Paragraph("概要", ipam18), 1);
        Paragraph p1 = new Paragraph();
        p1.add(new Phrase("これは", ipam12));
        p1.add(new Phrase("iText", ipam12ib));
        p1.add(new Phrase("を利用して出力されたPDF文書です。", ipam12));
        chapter1.add(p1);

        // セクション1.1
        Section section11 =
        chapter1.addSection(new Paragraph("この連載について", ipam16), 2);
        Paragraph p11 =
        new Paragraph("この連載ではプログラミングを手助けするツールやライブラリ、フレームワーク、プラットフォームなどについて紹介しています。", ipam12);
        section11.add(p11);

        // セクション1.2
        Section section12 =
        chapter1.addSection(new Paragraph("iTextについて", ipam16), 2);
        Paragraph p12 = new Paragraph();
        p12.add(new Phrase("iText", ipam12ib));
        p12.add(new Phrase("はJavaプログラムでPDFを出力するためのライブラリです。", ipam12));
        section12.add(p12);

        // チャプター1をドキュメントに追加
        document.add(chapter1);

            document.close();

        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

このプログラムを実行すると、図1のようなPDFファイルが生成される。

図1 複数のフォントを使ってドキュメントを構成した例

順番に解説していこう。まず、今回は複数のフォントを使いたいのであらかじめ必要な分のFontオブジェクトを作成している。Fontの作成方法は前回解説したのと同様である。ここでは文字サイズの異なるフォントや、太字/イタリック体にしたフォントを作っている。

次にチャプター1の部分である。チャプターを表すChapterオブジェクトはコンストラクタにタイトルとチャプター番号を指定して生成する。タイトルはStringで渡すこともできるが、Paragraphを使用すればフォントを設定できるという利点がある。次にParagraphオブジェクトを生成し、そこに複数のPhraseオブジェクトを追加している。Phraseごとにフォントを設定することができ、この例の場合は「iText」だけが太字のイタリック体として出力されるようになっている。そしてこのParagraphオブジェクトをチャプター1の構成要素として追加している。

リスト2

// タイトルを指定してChapterを作成
Chapter chapter1 = new Chapter(new Paragraph("概要", ipam18), 1);

// 複数のPhraseを利用してParaghraphを構成
Paragraph p1 = new Paragraph();
p1.add(new Phrase("これは", ipam12));
p1.add(new Phrase("iText", ipam12ib));
p1.add(new Phrase("を利用して出力されたPDF文書です。", ipam12));

// ParagraphをChapterに追加
chapter1.add(p1);

チャプター1には2つのセクションがある。セクションを表すSectionオブジェクトはこれまで出てきた他の部品と違いコンストラクタを使って生成することができない。Sectionは必ずいずれかのChapterまたはSectionの構成要素になるので、ChapterクラスまたはSectionクラスのaddSectionメソッドを使って生成しなければならない。addSectionメソッドには、セクションのタイトルと階層の深さを指定する。そのほかに、インデントを付けたい場合にはその幅を指定することもできる。この例では、次のようにセクション1.1の構成要素としてParagraphオブジェクトを追加している。

リスト3

// Sectionを生成してChapterに追加
Section section11 =
    chapter1.addSection(new Paragraph("この連載について", ipam16), 2);

// ParagraphをSectionに追加
Paragraph p11 =
      new Paragraph("この連載ではプログラミングを手助けするツールやライブラリ、フレームワーク、プラットフォームなどについて紹介しています。", ipam12);
section11.add(p11);

セクション1.2にも同様にParagraphオブジェクトを追加しているが、このParagraphは複数のPhraseから構成されている。そして最期にチャプター1をDocumentオブジェクトに追加する。

ドキュメントに画像を追加する

文字だけでなく画像を追加することもできる。画像を表すのはImageクラスであり、オブジェクトは次のようにgetInstanseメソッドを用いて生成する。ここに示したように、Stringでファイル名を指定する方法と、ファイルのURLを指定する方法がある。それに加えて、サイズや色をはじめとする各種オプションを指定して生成する方法が用意されている。

リスト4

// ファイル名を指定してImageを生成
Image image1 = Image.getInstance("image.jpg");

// URLを指定してImageを生成
URL sourceUrl = new URL("http://journal.mycom.co.jp/column/tool/025/index.top.jpg");
Image image2 = Image.getInstance(sourceUrl);

以下に、Imageオブジェクトを生成してParagraphに追加するコードの例を示す。2つ目のImageに対して使っているscaleAbsoluteメソッドは画像のサイズを変更するためのメソッドである。

リスト5

// チャプター1
Chapter chapter1 = new Chapter(new Paragraph("画像の挿入", ipam18), 1);

// ファイルを指定して画像を挿入
Paragraph p1 = new Paragraph();
Image image1 = Image.getInstance("image.jpg");
p1.add(image1);
p1.add(new Phrase("攻略!ツール・ド・プログラミング", ipam12));
chapter1.add(p1);

// URLを指定して画像を挿入
Paragraph p2 = new Paragraph();
URL sourceUrl = new URL("http://journal.mycom.co.jp/column/tool/025/index.top.jpg");
Image image2 = Image.getInstance(sourceUrl);
image2.scaleAbsolute(50, 50);     // サイズ変更
p2.add(image2);
p2.add(new Phrase(sourceUrl.toString(), ipam12));
chapter1.add(p2);

このコードによって生成されるPDFファイルは図2のようになる。どちらも同じ画像だが、1つ目はローカルのファイルから読み込んだ画像であり、2つ目は指定されたURLから読み込んだ画像となっている。

図2 ドキュメントに画像を埋め込んだ例