倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

PoiBuilder で Quick Guide (20) : セルのマージ

今回はセルのマージ (Merging cells) です(一覧)。 セルのマージとは、矩形範囲の複数のセルを1つのセルに合体させることです。

Java コード


セルのマージを行う手順は以下のようになってます:

  1. CellRangeAddress オブジェクトを生成する
  2. 生成した CellRangeAddress オブジェクトを引数にして Sheet#addMergedRegion() メソッドを呼び出す

です。 CellRangeAddress オブジェクトを生成する方法は、以下の2つがよく使われると思います:

  • CellRangeAddress クラスのコンストラクタを使用する。 int 値4つを引数にとるコンストラクタ
      (最初の行, 最後の行, 最初の列, 最後の列)
    の番号を指定します。
  • static メソッド CellRangeAddress#valueOf() メソッドを用いて、"$B$3:$C$3" や "B3C3" のような String オブジェクトから生成する。

コンストラクタに指定するのは0から始まる番号、valueOf() メソッドに渡す文字列に指定するのは1から始まる番号なのに注意。

サンプルコードは以下のようになります:

    Workbook wb = new HSSFWorkbook();
    Sheet sheet = wb.createSheet("new sheet");

    Row row = sheet.createRow((short) 1);
    Cell cell = row.createCell((short) 1);
    cell.setCellValue("This is a test of merging");

    sheet.addMergedRegion(new CellRangeAddress(
            1, //first row (0-based)
            1, //last row  (0-based)
            1, //first column (0-based)
            2  //last column  (0-based)
    ));

このサンプルではコンストラクタから CellRangeAddress オブジェクトを生成しています。

poi-builder による構築


poi-builder による構築サンプルの前に、セルのマージとは関係ないことですが poi-builder 0.0.6 から、ビルダークラスを SpreadsheetBuilder に変更しました。 今まで通り PoiBuilder も使えますが @Deprecated になってます。 “poi-builder” と書いたときはモジュール名(Maven2/3 では artifactId)のことと思ってください。

では構築のサンプル。 マージの仕方をいろいろ載せたので(計7通り)、上記の Java コードのサンプルとは少し異なってます(基本は同じ):

@GrabResolver('http://www5.ocn.ne.jp/~coast/repo/')
@Grab('org.waman.tools:poi-builder:0.0.6')

import org.waman.tools.poi.SpreadsheetBuilder

def workbook = new SpreadsheetBuilder().workbook{
    sheet('new sheet'){
        //***** cellRangeAddress ノードを使う場合 (1) 〜 (3) *****
        row(1){
            cell(1, cellValue:'This is a test of merging')
            // (1) CellRangeAddress クラスのコンストラクタ (int, int, int, int)
            merge(cellRangeAddress(1, 1, 1, 2)) 
        }

        row(2){
            cell(1, cellValue:'This is a test of merging 2')
            // (2) CellRangeAddress#valueOf(String) 
            merge(cellRangeAddress('$B$3:$C$3'))
        }

        row(3){
            cell(1, cellValue:'This is a test of merging 3')
            // (3) 属性と Groovy の範囲 (IntRange) を使う
            merge(cellRangeAddress(row:3, column:1..2))
        }

        //***** merge ノードのみでマージする場合 (4) 〜 (7) *****
        row(4){
            cell(1, cellValue:'This is a test of merging 4')
            // (4) (1) の merge(cellRangeAddress(int, int, int, int)) と同じ
            merge(4, 4, 1, 2)
        }

        row(5){
            cell(1, cellValue:'This is a test of merging 5')
            // (5) (2) の merge(cellRangeAddress(String)) と同じ
            merge('B6:C6')
//            merge('$B$6:$C$6')
        }

        row(6){
            cell(1, cellValue:'This is a test of merging 6')
            // (6) (3) の merge(cellRangeAddress(row:○, column:○)) と同じ
            merge(row:6, column:1..2)
        }

        row(7){
            cell(1, cellValue:'This is a test of merging 7'){
                // (7) cell ノードの子要素として書き、マージする幅と高さを指定
                merge(1, 2)
            }
        }
    }
}

いろいろ書いてますが、新しく出てきているノードは

  • cellRangeAddress ノード
  • merge ノード

の2つです。 また、(1) 〜 (3) の方法は (4) 〜 (6) の方法と実質的に同じで、単に cellRangeAddress ノードを省略できることを示しているだけです*1

cellRangeAddress ノードは CellRangeAddress オブジェクトを構築するノードですが、内容や属性として渡せるのは

  • 4つの int 値 ・・・ CellRangeAddress クラスのコンストラクタからインスタンス生成
  • String オブジェクト ・・・ CellRangeAddress#valueOf() メソッドによってインスタンス生成
  • row, column 属性 ・・・ IntRange オブジェクトを指定し、行 (row) と列 (column) のマージする範囲を指定

です。 3つ目は Groovy で使いやすくするために実装してみました。 使い方は上記のビルド・スクリプトの (3), (6) を参照。 cellRangeAddress ノードは sheet, row, cell ノードの子ノードとして書けます*2

merge ノードは Sheet#addMergedRegion() を実行するノードですが、CellRangeAddress オブジェクト以外が渡された場合は適当に CellRangeAddress オブジェクトを生成します。 使い方や書ける場所は cellRangeAddress ノードと大体同じですが、cell ノードの子ノードとして書いた場合だけ、幅と高さを指定してマージを行うことができます(ビルド・スクリプトの (7) 参照)。 親となる cell ノードの位置から、指定された幅と高さでマージを行います。

作成されるスプレッドシート





現場で使えるJavaライブラリ

現場で使えるJavaライブラリ


プログラミングGROOVY

プログラミングGROOVY

*1:poi-builder 0.0.6 では、内部で cellRangeAddress ノードと同じ構築を行ってます。

*2:workbook ノードの子ノードとしては書けないのでご注意を。 これは、poi-builder が cellRangeAddress ノードで生成される CellRangeAddress オブジェクトにシート情報を付加しているためです(そのうちやる「便利な機能」の記事参照)。 ちなみに CellRangeAddress クラス自体にはシート情報は含まれていないので、POI に精通している人にはおかしく感じるかも知れません。