S-JIS[2014-05-03/2015-08-27] 変更履歴

Apache POI CellReference

POI3.10でA1形式を扱う方法について。


概要

POIでセルの位置を表すには、行インデックス・列インデックスを使う。(いわば0オリジンのR1C1形式)

が、A1形式からインデックスへ変換する方法も用意されている。


CellReference

セルの位置を表すにはCellReferenceクラスを使う。[2014-11-15]

import org.apache.poi.ss.util.CellReference;
		CellReference ref = new CellReference("sheet1", 0, 0, false, false);
		System.out.println(ref.formatAsString());

formatAsString()を呼び出すと、A1形式で位置を取得できる。

コンストラクターの引数
生成 formatAsString
int row, int col new CellReference(2, 0) A3
int row, int col, boolean absRow, boolean absCol new CellReference(2, 0, true, true) $A$3
String sheetName, int row, int col, boolean absRow, boolean absCol new CellReference("sheet", 2, 0, false, true) sheet!$A3

A1形式でのセルの取得

A1形式での位置はCellReferenceで取得できる。

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellReference;
		Sheet sheet = ;
		Cell cell = getCell(sheet, "A1");
	public static Cell getCell(Sheet sheet, String position) {
		CellReference reference = new CellReference(position); // A1形式
		Row row = sheet.getRow(reference.getRow());
		if (row != null) {
			Cell cell = row.getCell(reference.getCol());
			return cell;
		}
		return null;
	}

列インデックスの取得

列を表す文字列列インデックスを変換する方法。

import org.apache.poi.ss.util.CellReference;
	public static void printColumn() {
		int index = CellReference.convertColStringToIndex("Z");
		System.out.println(index);

		String column = CellReference.convertNumToColString(26);
		System.out.println(column);
	}

↓出力結果

25
AA

CellRangeAddress

セルの範囲を表すにはCellRangeAddressを使う。[2015-08-27]
セルの範囲とは、左上セルと右下セルを指定したブロックのこと。例えば「A1:B2」。
(これらをさらに複数指定するにはCellRangeAddressListを使う)

import org.apache.poi.ss.util.CellRangeAddress;
		int firstRow = 0; // 行1
		int lastRow  = 1; // 行2
		int firstColumn = 0; // 列A
		int lastColumn  = 1; // 列B
		CellRangeAddress range = new CellRangeAddress(firstRow, lastRow, firstColumn, lastColumn);
		CellRangeAddress range = CellRangeAddress.valueOf("A1:B2");

行インデックス・列インデックスで指定する場合はコンストラクターを使って生成する。

A1:B2」のようなセルのA1形式で指定する場合はvalueOf()を使う。
A1」(1つのセル)のみを指定した場合は、「A1:A1」を指定したのと同じになる。
(内部ではCellReferenceを使ってインデックスに変換している)


CellRangeAddressが保持している行・列は以下のようにして使用できる。

		for (int r = range.getFirstRow(); r <= range.getLastRow(); r++) {
			for (int c = range.getFirstColumn(); c <= range.getLastColumn(); c++) {
				〜
			}
		}

CellRangeAddressは(CellReferenceと違って)シート名を保持しておらず、絶対相対の区別も無い。
必要であれば、CellRangeAddressから値を取得する際に考慮する。

range=「A3:B5」の例
コード 出力結果 備考
range.getFirstRow() 2 先頭行インデックス
range.getLastRow() 4 最終行インデックス
range.getFirstColumn() 0 先頭列インデックス
range.getLastColumn() 1 最終列インデックス
range.formatAsString() A3:B5 相対位置
range.formatAsString(null, true) $A$3:$B$5 絶対位置
range.formatAsString("example", false) example!A3:B5 シート名付き
range.isInRange(2, 0) true 指定した位置が範囲内に含まれているかどうか

CellRangeAddressList

複数のセル範囲(CellRangeAddress)を保持するにはCellRangeAddressListを使う。[2015-08-27]

import org.apache.poi.ss.util.CellRangeAddressList;
		CellRangeAddressList list = new CellRangeAddressList();
		list.addCellRangeAddress(0, 0, 1, 1); // A1:B2
		list.addCellRangeAddress(CellRangeAddress.valueOf("B1:C3"));

		for (int i = 0; i < list.countRanges(); i++) {
			CellRangeAddress range = list.getCellRangeAddress(i);
			〜
		}

CellRangeAddressListのインスタンスを作り、addCellRangeAddress()でセル範囲(CellRangeAddress)を追加する。
なお、addCellRangeAddress(int firstRow, int firstCol, int lastRow, int lastCol)は、CellRangeAddressのコンストラクターの引数(firstRow, lastRow, firstCol, lastCol)とは行・列の並び順が違うので注意!

含まれている範囲の個数をcountRanges()で取得し、getCellRangeAddress()でCellRangeAddressを取得する。
(getSize()というメソッドもあるが、これはPOI内部で使用するバイト数か何かを返すようなので、セル範囲の個数ではない)


POI目次へ戻る / Excel操作ライブラリーへ戻る / Java目次へ戻る / 技術メモへ戻る
メールの送信先:ひしだま