iText を使うと段組などの楽しい配置が可能。
iText Tutorial: ColumnText とか com.lowagie.examples.objects.columns.ColumnObjects とか見てたらなかなかおもしろい。



改ページが自動で行われると嫌な場合は段組テキスト表示用のColumnTextを使うといいみたい。自動的に右端で改行をしてくれて、与えられた領域内でテキストが収まりきらないときはColumnText.go()の戻り値で検出できる。溢れたテキストは任意のColumnTextに続けて表示させることも可能な優れもの。



きのこる先生 -チラシの裏 - PDFライブラリiTextを使う2

というわけで、ColumnText を試してみた。

サンプルソースコード(ColumnsSample.java)


import java.io.*;
 
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;
 
public class ColumnsSample {
 
  // Ref.
  //
  // - iText Tutorial: ColumnText
  //   http://itextdocs.lowagie.com/tutorial/objects/columns/
  //
  // - com.lowagie.examples.objects.columns.ColumnObjects
  //   http://itext.ugent.be/library/com/lowagie/examples/objects/columns/ColumnObjects.java
  //   The ColumnObjects.java is a great!
  //
  // - きのこる先生 -チラシの裏 - PDFライブラリiTextを使う2
  //   http://d.hatena.ne.jp/halo_w2/20070213/p1
  
  // The texts by
  //
  // - The Wonderful Wizard of Oz by L. Frank Baum - Project Gutenberg
  //   http://www.gutenberg.org/etext/55
  
  private static String headings[] = {
    "Introduction",
    "1. The Cyclone",
    "2. The Council with the Munchkins",
    "3. How Dorothy Saved the Scarecrow",
    "4. The Road Through the Forest",
    "5. The Rescue of the Tin Woodman",
    "6. The Cowardly Lion",
    "7. The Journey to the Great Oz",
  };
 
  private static String texts[] = {
    "Folklore, legends, myths and fairy tales have followed childhood through the ages, for every healthy youngster has a wholesome and instinctive love for stories fantastic, marvelous and manifestly unreal. The winged fairies of Grimm and Andersen have brought more happiness to childish hearts than all other human creations.",
    "Dorothy lived in the midst of the great Kansas prairies, with Uncle Henry, who was a farmer, and Aunt Em, who was the farmer's wife.",
    "She was awakened by a shock, so sudden and severe that if Dorothy had not been lying on the soft bed she might have been hurt.",
    "When Dorothy was left alone she began to feel hungry.",
    "After a few hours the road began to be rough, and the walking grew so difficult that the Scarecrow often stumbled over the yellow bricks, which were here very uneven.",
    "When Dorothy awoke the sun was shining through the trees and Toto had long been out chasing birds around him and squirrels.",
    "All this time Dorothy and her companions had been walking through the thick woods.",
    "They were obliged to camp out that night under a large tree in the forest, for there were no houses near.",
  };
 
  public static void main(String[] args) throws Exception {
    
    Document doc = new Document(PageSize.A6, 10, 10, 10, 10);
    PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream("20070804_columns.pdf"));
 
    float gutter = 20; // 列と列のスペース
    int numColumns = 3; // 列の数
    float fullWidth = doc.right() - doc.left(); // 描画範囲
    float columnWidth = (fullWidth - (numColumns - 1) * gutter) / numColumns; // 列の幅
    float columnLeft[] = new float[numColumns]; // 列の左端の位置
    for(int i=0; i<numColumns; i++){
      columnLeft[i] = doc.left() + (columnWidth + gutter) * i;
    }
    
    // フォント
    Font font4Heading =
      FontFactory.getFont(
        FontFactory.TIMES_ROMAN, 14, Font.BOLD, new java.awt.Color(255, 0, 0));
    Font font4Text = FontFactory.getFont(FontFactory.TIMES_ROMAN, 11);
    
    // Document#open
    doc.open();
 
    // 列の区切りとなる縦線を描画
    PdfContentByte cb = writer.getDirectContent();
    for(int i=1; i<numColumns; i++){
      float x = columnLeft[i] - gutter / 2.0f;
      cb.moveTo(x, doc.top());
      cb.lineTo(x, doc.bottom());
    }
    cb.stroke();
 
    // 描画位置の道標: まずは文書の上の方をセットする
    float currentY = doc.top();
    ColumnText ct = new ColumnText(cb);
    ct.setYLine(currentY);
 
    // タイトルと文章を追加していく
    for(int i=0; i<headings.length; i++) {
      ct.addText(new Chunk(headings[i] + "\n", font4Heading));
      ct.addText(new Chunk(texts[i] + "\n\n", font4Text));
    }
 
    // 現在描画中の列のインデックス
    int currentColumn = 0;
    
    // 最初の列を作る
    {
      float llx = columnLeft[currentColumn];
      float lly = doc.bottom();
      float urx = columnLeft[currentColumn] + columnWidth;
      float ury = currentY;
      float leading = 15.0f;
      int alignment = Element.ALIGN_LEFT;
      ct.setSimpleColumn(llx, lly, urx, ury, leading, alignment);
    }
 
    while(true){
      
      // テキストを書き出す
      int rc = ct.go();
      
      // すべてのテキストが収まった
      if((rc & ColumnText.NO_MORE_TEXT) != 0){
        break;
      }
      
      // テキストが列の範囲内に収まらなかったので、新しく列を作る必要がある
      currentColumn++;
      
      // 最後の列にも収まらなかったのでアキラメ
      if(currentColumn >= numColumns){
        break;
      }
 
      // 新しく列を作る
      float llx = columnLeft[currentColumn];
      float lly = doc.bottom();
      float urx = columnLeft[currentColumn] + columnWidth;
      float ury = currentY;
      float leading = 15.0f;
      int alignment = Element.ALIGN_LEFT;
      ct.setSimpleColumn(llx, lly, urx, ury, leading, alignment);
    }
    
    doc.close();
  }
}

出力したPDFファイル -> 20070804_columns.pdf

文章は The Wonderful Wizard of Oz by L. Frank Baum - Project Gutenberg を拝借。

tags: zlashdot Java Java PDF iText

Posted by NI-Lab. (@nilab)