CellPosition.java
package com.gh.mygreen.xlsmapper.util;
import java.awt.Point;
import java.io.Serializable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.ss.util.CellReference;
/**
* 単一のセルのアドレスを表現するクラス。
* <p>{@link java.awt.Point}だと、行、列の表現がわかりづらくmutableなので、、その代わりに使用する。
* <p>{@link CellReference}との違いは、セルのアドレスの絶対一致を表現するためのもの。
* <p>POIに同じ用途のクラス{@link CellAddress}が存在するが、
* こちらは{@link Serializable}や{@link Cloneable}が実装されておらず、使い勝手が悪い。</p>
*
* @since 1.4
* @author T.TSUCHIE
*
*/
public class CellPosition implements Serializable, Comparable<CellPosition>, Cloneable {
/** serialVersionUID */
private static final long serialVersionUID = 8579701754512731611L;
/**
* シート上の先頭の位置を表現するための定数。
*/
public static final CellPosition A1 = new CellPosition(0, 0);
private final int row;
private final int column;
private final String toStringText;
/**
* CellAddressのインスタンスを作成する。
*
* @param row 行番号 (0から始まる)
* @param column 列番号 (0から始まる)
* @throws IllegalArgumentException {@literal row < 0 || column < 0}
*/
private CellPosition(int row, int column) {
ArgUtils.notMin(row, 0, "row");
ArgUtils.notMin(column, 0, "column");
this.row = row;
this.column = column;
this.toStringText = CellReference.convertNumToColString(column) + (row + 1);
}
/**
* CellAddressのインスタンスを作成する。
*
* @param row 行番号 (0から始まる)
* @param column 列番号 (0から始まる)
* @return {@link CellPosition}のインスタンス
* @throws IllegalArgumentException {@literal row < 0 || column < 0}
*/
public static CellPosition of(int row, int column) {
ArgUtils.notMin(row, 0, "row");
ArgUtils.notMin(column, 0, "column");
return new CellPosition(row, column);
}
/**
* CellAddressのインスタンスを作成する。
* @param cell セルのインスタンス。
* @return {@link CellPosition}のインスタンス
* @throws IllegalArgumentException {@literal cell == null.}
*/
public static CellPosition of(final Cell cell) {
ArgUtils.notNull(cell, "cell");
return of(cell.getRowIndex(), cell.getColumnIndex());
}
/**
* CellAddressのインスタンスを作成する。
* @param reference セルの参照形式。
* @return {@link CellPosition}のインスタンス
* @throws IllegalArgumentException {@literal reference == null.}
*/
public static CellPosition of(final CellReference reference) {
ArgUtils.notNull(reference, "reference");
return of(reference.getRow(), reference.getCol());
}
/**
* CellAddressのインスタンスを作成する。
* @param address セルのアドレス
* @return {@link CellPosition}のインスタンス
* @throws IllegalArgumentException {@literal address == null.}
*/
public static CellPosition of(final CellAddress address) {
ArgUtils.notNull(address, "address");
return of(address.getRow(), address.getColumn());
}
/**
* CellAddressのインスタンスを作成する。
* @param address 'A1'の形式のセルのアドレス
* @return {@link CellPosition}のインスタンス
* @throws IllegalArgumentException {@literal address == null || address.length() == 0 || アドレスの書式として不正}
*/
public static CellPosition of(final String address) {
ArgUtils.notEmpty(address, "address");
if(!matchedCellAddress(address)) {
throw new IllegalArgumentException(address + " is wrong cell address pattern.");
}
return of(new CellReference(address));
}
private static final Pattern PATTERN_CELL_ADREESS = Pattern.compile("^([a-zA-Z]+)([0-9]+)$");
private static boolean matchedCellAddress(final String address) {
final Matcher matcher = PATTERN_CELL_ADREESS.matcher(address);
return matcher.matches();
}
/**
* CellAddressのインスタンスを作成する。
* @param point セルの座標
* @return {@link CellPosition}のインスタンス
* @throws IllegalArgumentException {@literal point == null.}
*/
public static CellPosition of(final Point point) {
ArgUtils.notNull(point, "point");
return of(point.y, point.x);
}
@Override
public int compareTo(final CellPosition other) {
ArgUtils.notNull(other, "other");
int r = this.row - other.row;
if (r != 0) {
return r;
}
int c = this.column - other.column;
if (c != 0) {
return c;
}
return 0;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + column;
result = prime * result + row;
return result;
}
@Override
public boolean equals(final Object obj) {
if(this == obj) {
return true;
}
if(obj == null) {
return false;
}
if(!(obj instanceof CellPosition)) {
return false;
}
CellPosition other = (CellPosition) obj;
if(column != other.column) {
return false;
}
if(row != other.row) {
return false;
}
return true;
}
@Override
public CellPosition clone() {
return new CellPosition(row, column);
}
/**
* 行番号を取得する。
* @return 行番号 (0から始まる)
*/
public int getRow() {
return row;
}
/**
* 列番号を取得する。
* @return 列番号 (0から始まる)
*/
public int getColumn() {
return column;
}
/**
* {@link Point}の形式に変換します。
* @return {@link Point}のインスタンス。
* x座標が列番号(column index)、y座標が行番号(row index)なります。
*/
public Point toPoint() {
return new Point(column, row);
}
/**
* POIの{@link CellAddress}の形式に変換します。
* @return {@link CellAddress}のインスタンス。
*/
public CellAddress toCellAddress() {
return new CellAddress(row, column);
}
/**
* セルのアドレスを取得する。
* @return 'A1'の形式で、セルノアドレスを文字列として表現する。
*/
public String formatAsString() {
return toStringText;
}
/**
* 行番号に指定した値を加算する。
* @param value 加算する値
* @return 加算したインスタンス
*/
public CellPosition addRow(int value) {
return new CellPosition(row + value, column);
}
/**
* 列番号に指定した値を加算する。
* @param value 加算する値
* @return 加算したインスタンス
*/
public CellPosition addColumn(int value) {
return new CellPosition(row, column + value);
}
/**
* {@link #formatAsString()}の値を返します。
*/
@Override
public String toString() {
return formatAsString();
}
}