Hello, iTextSharp!

今まで適当に使っていたので,ここらでざっと概要を把握するためのまとめ.iTextSharp 自体のリファレンスは存在しない(?)ようなので,リファレンスとしては iText (Java) の API リファレンスで代用するか有志の方が作成したヘルプファイルを眺めるかになるようです.

iTextSharp と言うか PDF ライブラリを使用する場合,目的としては以下の 2つに大別されるかと思います.

  • ゼロから PDF ファイルを生成する
  • 既存の PDF ファイルに何らかの情報を修正・追加する

各種用途で使用するクラス名をよく忘れるので,その部分だけざっと記述します.

ゼロから PDF ファイルを生成する

Document クラスを使っていくのが一般的のようです.

void Create() {
    var doc = new iTextSharp.text.Document();
    iTextSharp.text.pdf.PdfWriter.GetInstance(doc, new System.IO.FileStream(@"path\to\dest.pdf", System.IO.FileMode.Create));
    
    doc.Open();
    
    // doc.Add(new iTextSharp.text.Paragraph("Hello, iTextSharp!")
    // 等,必要な処理を記述する.
    // Paragraph の他,Chapter,Section,Image,List 等ある程度のものが揃っている模様.
    // http://api.itextpdf.com/itext/com/itextpdf/text/Element.html
    
    doc.Close();
}

Document クラスが(iTextSharp.text.pdf ではなく)iTextSharp.text 名前空間内に定義されているので,PDF 等の特定のファイルフォーマットとは独立した iTextSharp 内で文書構造を管理するためのクラスなのだろうと思います.

既存の PDF ファイルを修正する

こちらは PdfReader で読み込んで PdfStamper で修正すると言う形を取る事が一般的のようです.

void Edit() {
    // 対象の PDF ファイルにパスワードが設定されている場合は,第2引数で指定する.
    // ただし,iTextSharp ではパスワードを UTF-8 のバイト列で指定するようなので,
    // System.Text.Encoding.UTF8.GetBytes("password string") のようにする
    var reader = new iTextSharp.text.pdf.PdfReader(@"path\to\source.pdf");
    var stamper = new iTextSharp.text.pdf.PdfStamper(reader, new System.IO.FileStream(@"path\to\dest.pdf", System.IO.FileMode.Create));
    
    // 修正するための処理を記述する.
    // 例えば,文書プロパティを設定/変更する場合は stamper.MoreInfo プロパティ,
    // パスワードを設定する場合は stamper.SetEncryption() メソッド辺りを弄る.
    
    stamper.Close();
}

こちらの使い方は Document クラスを弄るものに比べて解説記事が少ない印象なので,もう少し適当にいろいろと弄ってみる必要がありそうです.

その他

例えば,2 つの PDF ファイルを結合する場合などには PdfCopyFields が使えるようです.

void Merge() {
    var head = new iTextSharp.text.pdf.PdfReader(@"path\to\1st.pdf");
    var tail = new iTextSharp.text.pdf.PdfReader(@"path\to\2nd.pdf");
    using (System.IO.FileStream fs = new FileStream(@"path\to\dest.pdf", System.IO.FileMode.Create)) {
        var copy = new iTextSharp.text.pdf.PdfCopyFields(fs);
        copy.AddDocument(head);
        copy.AddDocument(tail);
        copy.Close();
    }
    head.Close();
    tail.Close();
}

また,PDF ファイルから特定のページを抽出するには PdfCopy(PdfCopyFields ではない)が使えるようです.

void Extract(int n) {
    var reader = new iTestSharp.text.pdf.PdfReader(@"path\to\source.pdf");
    
    System.Diagnostics.Debug.Assert(n <= reader.NumberOfPages);
    var doc = new iTextSharp.text.Document();
    var copy = new iTextSharp.text.pdf.PdfCopy(doc, new System.IO.FileStream(@"path\to\dest.pdf", System.IO.FileMode.Create));
    doc.Open();
    
    copy.AddPage(copy.GetImportedPage(reader, n));
    // 「1st.pdf の i ページと 2nd.pdf の j ページを抽出した PDF ファイル」のように
    // 複数の PDF ファイルからページを抽出する必要がある場合,FreeReader() を呼ぶ必要がある?
    // http://stackoverflow.com/questions/6476784/itextsharp-pdf-pages-import-memory-issue
    // reader.Close()
    // copy.FreeReader(reader);
    
    doc.Close();
}