CellPosition.java

  1. package com.gh.mygreen.xlsmapper.util;

  2. import java.awt.Point;
  3. import java.io.Serializable;
  4. import java.util.regex.Matcher;
  5. import java.util.regex.Pattern;

  6. import org.apache.poi.ss.usermodel.Cell;
  7. import org.apache.poi.ss.util.CellAddress;
  8. import org.apache.poi.ss.util.CellReference;

  9. /**
  10.  * 単一のセルのアドレスを表現するクラス。
  11.  * <p>{@link java.awt.Point}だと、行、列の表現がわかりづらくmutableなので、、その代わりに使用する。
  12.  * <p>{@link CellReference}との違いは、セルのアドレスの絶対一致を表現するためのもの。
  13.  * <p>POIに同じ用途のクラス{@link CellAddress}が存在するが、
  14.  *    こちらは{@link Serializable}や{@link Cloneable}が実装されておらず、使い勝手が悪い。</p>
  15.  *
  16.  * @since 1.4
  17.  * @author T.TSUCHIE
  18.  *
  19.  */
  20. public class CellPosition implements Serializable, Comparable<CellPosition>, Cloneable {

  21.     /** serialVersionUID */
  22.     private static final long serialVersionUID = 8579701754512731611L;

  23.     /**
  24.      * シート上の先頭の位置を表現するための定数。
  25.      */
  26.     public static final CellPosition A1 = new CellPosition(0, 0);

  27.     private final int row;

  28.     private final int column;

  29.     private final String toStringText;

  30.     /**
  31.      * CellAddressのインスタンスを作成する。
  32.      *
  33.      * @param row 行番号 (0から始まる)
  34.      * @param column 列番号 (0から始まる)
  35.      * @throws IllegalArgumentException {@literal row < 0 || column < 0}
  36.      */
  37.     private CellPosition(int row, int column) {
  38.         ArgUtils.notMin(row, 0, "row");
  39.         ArgUtils.notMin(column, 0, "column");
  40.         this.row = row;
  41.         this.column = column;
  42.         this.toStringText = CellReference.convertNumToColString(column) + (row + 1);
  43.     }

  44.     /**
  45.      * CellAddressのインスタンスを作成する。
  46.      *
  47.      * @param row 行番号 (0から始まる)
  48.      * @param column 列番号 (0から始まる)
  49.      * @return {@link CellPosition}のインスタンス
  50.      * @throws IllegalArgumentException {@literal row < 0 || column < 0}
  51.      */
  52.     public static CellPosition of(int row, int column) {
  53.         ArgUtils.notMin(row, 0, "row");
  54.         ArgUtils.notMin(column, 0, "column");

  55.         return new CellPosition(row, column);
  56.     }

  57.     /**
  58.      * CellAddressのインスタンスを作成する。
  59.      * @param cell セルのインスタンス。
  60.      * @return {@link CellPosition}のインスタンス
  61.      * @throws IllegalArgumentException {@literal cell == null.}
  62.      */
  63.     public static CellPosition of(final Cell cell) {
  64.         ArgUtils.notNull(cell, "cell");

  65.         return of(cell.getRowIndex(), cell.getColumnIndex());
  66.     }

  67.     /**
  68.      * CellAddressのインスタンスを作成する。
  69.      * @param reference セルの参照形式。
  70.      * @return {@link CellPosition}のインスタンス
  71.      * @throws IllegalArgumentException {@literal reference == null.}
  72.      */
  73.     public static CellPosition of(final CellReference reference) {
  74.         ArgUtils.notNull(reference, "reference");

  75.         return of(reference.getRow(), reference.getCol());
  76.     }

  77.     /**
  78.      * CellAddressのインスタンスを作成する。
  79.      * @param address セルのアドレス
  80.      * @return {@link CellPosition}のインスタンス
  81.      * @throws IllegalArgumentException {@literal address == null.}
  82.      */
  83.     public static CellPosition of(final CellAddress address) {
  84.         ArgUtils.notNull(address, "address");

  85.         return of(address.getRow(), address.getColumn());
  86.     }

  87.     /**
  88.      * CellAddressのインスタンスを作成する。
  89.      * @param address 'A1'の形式のセルのアドレス
  90.      * @return {@link CellPosition}のインスタンス
  91.      * @throws IllegalArgumentException {@literal address == null || address.length() == 0 || アドレスの書式として不正}
  92.      */
  93.     public static CellPosition of(final String address) {
  94.         ArgUtils.notEmpty(address, "address");

  95.         if(!matchedCellAddress(address)) {
  96.             throw new IllegalArgumentException(address + " is wrong cell address pattern.");
  97.         }

  98.         return of(new CellReference(address));
  99.     }

  100.     private static final Pattern PATTERN_CELL_ADREESS = Pattern.compile("^([a-zA-Z]+)([0-9]+)$");

  101.     private static boolean matchedCellAddress(final String address) {
  102.         final Matcher matcher = PATTERN_CELL_ADREESS.matcher(address);
  103.         return matcher.matches();
  104.     }

  105.     /**
  106.      * CellAddressのインスタンスを作成する。
  107.      * @param point セルの座標
  108.      * @return {@link CellPosition}のインスタンス
  109.      * @throws IllegalArgumentException {@literal point == null.}
  110.      */
  111.     public static CellPosition of(final Point point) {
  112.         ArgUtils.notNull(point, "point");
  113.         return of(point.y, point.x);
  114.     }

  115.     @Override
  116.     public int compareTo(final CellPosition other) {
  117.         ArgUtils.notNull(other, "other");

  118.         int r = this.row - other.row;
  119.         if (r != 0) {
  120.             return r;
  121.         }

  122.         int c = this.column - other.column;
  123.         if (c != 0) {
  124.             return c;
  125.         }

  126.         return 0;
  127.     }

  128.     @Override
  129.     public int hashCode() {
  130.         final int prime = 31;
  131.         int result = 1;
  132.         result = prime * result + column;
  133.         result = prime * result + row;
  134.         return result;
  135.     }

  136.     @Override
  137.     public boolean equals(final Object obj) {
  138.         if(this == obj) {
  139.             return true;
  140.         }
  141.         if(obj == null) {
  142.             return false;
  143.         }
  144.         if(!(obj instanceof CellPosition)) {
  145.             return false;
  146.         }
  147.         CellPosition other = (CellPosition) obj;
  148.         if(column != other.column) {
  149.             return false;
  150.         }
  151.         if(row != other.row) {
  152.             return false;
  153.         }
  154.         return true;
  155.     }

  156.     @Override
  157.     public CellPosition clone() {
  158.         return new CellPosition(row, column);
  159.     }

  160.     /**
  161.      * 行番号を取得する。
  162.      * @return 行番号 (0から始まる)
  163.      */
  164.     public int getRow() {
  165.         return row;
  166.     }

  167.     /**
  168.      * 列番号を取得する。
  169.      * @return 列番号 (0から始まる)
  170.      */
  171.     public int getColumn() {
  172.         return column;
  173.     }

  174.     /**
  175.      * {@link Point}の形式に変換します。
  176.      * @return {@link Point}のインスタンス。
  177.      *          x座標が列番号(column index)、y座標が行番号(row index)なります。
  178.      */
  179.     public Point toPoint() {
  180.         return new Point(column, row);
  181.     }

  182.     /**
  183.      * POIの{@link CellAddress}の形式に変換します。
  184.      * @return {@link CellAddress}のインスタンス。
  185.      */
  186.     public CellAddress toCellAddress() {
  187.         return new CellAddress(row, column);
  188.     }

  189.     /**
  190.      * セルのアドレスを取得する。
  191.      * @return 'A1'の形式で、セルノアドレスを文字列として表現する。
  192.      */
  193.     public String formatAsString() {
  194.         return toStringText;
  195.     }

  196.     /**
  197.      * 行番号に指定した値を加算する。
  198.      * @param value 加算する値
  199.      * @return 加算したインスタンス
  200.      */
  201.     public CellPosition addRow(int value) {
  202.         return new CellPosition(row + value, column);
  203.     }

  204.     /**
  205.      * 列番号に指定した値を加算する。
  206.      * @param value 加算する値
  207.      * @return 加算したインスタンス
  208.      */
  209.     public CellPosition addColumn(int value) {
  210.         return new CellPosition(row, column + value);
  211.     }

  212.     /**
  213.      * {@link #formatAsString()}の値を返します。
  214.      */
  215.     @Override
  216.     public String toString() {
  217.         return formatAsString();
  218.     }

  219. }