267 lines
8.1 KiB
Java
267 lines
8.1 KiB
Java
/* ====================================================================
|
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
|
contributor license agreements. See the NOTICE file distributed with
|
|
this work for additional information regarding copyright ownership.
|
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
|
(the "License"); you may not use this file except in compliance with
|
|
the License. You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
==================================================================== */
|
|
|
|
package org.apache.poi.ss.util;
|
|
|
|
import org.apache.poi.ss.SpreadsheetVersion;
|
|
import org.apache.poi.ss.usermodel.Cell;
|
|
|
|
|
|
/**
|
|
* See OOO documentation: excelfileformat.pdf sec 2.5.14 - 'Cell Range Address'<p/>
|
|
*
|
|
* Common superclass of 8-bit and 16-bit versions
|
|
*/
|
|
public abstract class CellRangeAddressBase {
|
|
|
|
private int _firstRow;
|
|
private int _firstCol;
|
|
private int _lastRow;
|
|
private int _lastCol;
|
|
|
|
protected CellRangeAddressBase(int firstRow, int lastRow, int firstCol, int lastCol) {
|
|
_firstRow = firstRow;
|
|
_lastRow = lastRow;
|
|
_firstCol = firstCol;
|
|
_lastCol = lastCol;
|
|
}
|
|
|
|
/**
|
|
* Validate the range limits against the supplied version of Excel
|
|
*
|
|
* @param ssVersion the version of Excel to validate against
|
|
* @throws IllegalArgumentException if the range limits are outside of the allowed range
|
|
*/
|
|
public void validate(SpreadsheetVersion ssVersion) {
|
|
validateRow(_firstRow, ssVersion);
|
|
validateRow(_lastRow, ssVersion);
|
|
validateColumn(_firstCol, ssVersion);
|
|
validateColumn(_lastCol, ssVersion);
|
|
}
|
|
/**
|
|
* Runs a bounds check for row numbers
|
|
* @param row
|
|
*/
|
|
private static void validateRow(int row, SpreadsheetVersion ssVersion) {
|
|
int maxrow = ssVersion.getLastRowIndex();
|
|
if (row > maxrow) throw new IllegalArgumentException("Maximum row number is " + maxrow);
|
|
if (row < 0) throw new IllegalArgumentException("Minumum row number is 0");
|
|
}
|
|
|
|
/**
|
|
* Runs a bounds check for column numbers
|
|
* @param column
|
|
*/
|
|
private static void validateColumn(int column, SpreadsheetVersion ssVersion) {
|
|
int maxcol = ssVersion.getLastColumnIndex();
|
|
if (column > maxcol) throw new IllegalArgumentException("Maximum column number is " + maxcol);
|
|
if (column < 0) throw new IllegalArgumentException("Minimum column number is 0");
|
|
}
|
|
|
|
|
|
//TODO use the correct SpreadsheetVersion
|
|
public final boolean isFullColumnRange() {
|
|
return (_firstRow == 0 && _lastRow == SpreadsheetVersion.EXCEL97.getLastRowIndex())
|
|
|| (_firstRow == -1 && _lastRow == -1);
|
|
}
|
|
//TODO use the correct SpreadsheetVersion
|
|
public final boolean isFullRowRange() {
|
|
return (_firstCol == 0 && _lastCol == SpreadsheetVersion.EXCEL97.getLastColumnIndex())
|
|
|| (_firstCol == -1 && _lastCol == -1);
|
|
}
|
|
|
|
/**
|
|
* @return column number for the upper left hand corner
|
|
*/
|
|
public final int getFirstColumn() {
|
|
return _firstCol;
|
|
}
|
|
|
|
/**
|
|
* @return row number for the upper left hand corner
|
|
*/
|
|
public final int getFirstRow() {
|
|
return _firstRow;
|
|
}
|
|
|
|
/**
|
|
* @return column number for the lower right hand corner
|
|
*/
|
|
public final int getLastColumn() {
|
|
return _lastCol;
|
|
}
|
|
|
|
/**
|
|
* @return row number for the lower right hand corner
|
|
*/
|
|
public final int getLastRow() {
|
|
return _lastRow;
|
|
}
|
|
|
|
/**
|
|
* Determines if the given coordinates lie within the bounds
|
|
* of this range.
|
|
*
|
|
* @param rowInd The row, 0-based.
|
|
* @param colInd The column, 0-based.
|
|
* @return True if the coordinates lie within the bounds, false otherwise.
|
|
* @see #intersects(CellRangeAddressBase) for checking if two ranges overlap
|
|
*/
|
|
public boolean isInRange(int rowInd, int colInd) {
|
|
return _firstRow <= rowInd && rowInd <= _lastRow && //containsRow
|
|
_firstCol <= colInd && colInd <= _lastCol; //containsColumn
|
|
}
|
|
|
|
/**
|
|
* Determines if the given {@link CellReference} lies within the bounds
|
|
* of this range.
|
|
* <p/>NOTE: It is up to the caller to ensure the reference is
|
|
* for the correct sheet, since this instance doesn't have a sheet reference.
|
|
*
|
|
* @param ref the CellReference to check
|
|
* @return True if the reference lies within the bounds, false otherwise.
|
|
* @see #intersects(CellRangeAddressBase) for checking if two ranges overlap
|
|
*/
|
|
public boolean isInRange(CellReference ref) {
|
|
return isInRange(ref.getRow(), ref.getCol());
|
|
}
|
|
|
|
/**
|
|
* Determines if the given {@link Cell} lies within the bounds
|
|
* of this range.
|
|
* <p/>NOTE: It is up to the caller to ensure the reference is
|
|
* for the correct sheet, since this instance doesn't have a sheet reference.
|
|
*
|
|
* @param cell the Cell to check
|
|
* @return True if the cell lies within the bounds, false otherwise.
|
|
* @see #intersects(CellRangeAddressBase) for checking if two ranges overlap
|
|
*/
|
|
public boolean isInRange(Cell cell) {
|
|
return isInRange(cell.getRowIndex(), cell.getColumnIndex());
|
|
}
|
|
|
|
/**
|
|
* Check if the row is in the specified cell range
|
|
*
|
|
* @param rowInd the row to check
|
|
* @return true if the range contains the row [rowInd]
|
|
*/
|
|
public boolean containsRow(int rowInd) {
|
|
return _firstRow <= rowInd && rowInd <= _lastRow;
|
|
}
|
|
|
|
/**
|
|
* Check if the column is in the specified cell range
|
|
*
|
|
* @param colInd the column to check
|
|
* @return true if the range contains the column [colInd]
|
|
*/
|
|
public boolean containsColumn(int colInd) {
|
|
return _firstCol <= colInd && colInd <= _lastCol;
|
|
}
|
|
|
|
/**
|
|
* Determines whether or not this CellRangeAddress and the specified CellRangeAddress intersect.
|
|
*
|
|
* @param other a candidate cell range address to check for intersection with this range
|
|
* @return returns true if this range and other range have at least 1 cell in common
|
|
* @see #isInRange(int, int) for checking if a single cell intersects
|
|
*/
|
|
public boolean intersects(CellRangeAddressBase other) {
|
|
return this._firstRow <= other._lastRow &&
|
|
this._firstCol <= other._lastCol &&
|
|
other._firstRow <= this._lastRow &&
|
|
other._firstCol <= this._lastCol;
|
|
}
|
|
|
|
/**
|
|
* @param firstCol column number for the upper left hand corner
|
|
*/
|
|
public final void setFirstColumn(int firstCol) {
|
|
_firstCol = firstCol;
|
|
}
|
|
|
|
/**
|
|
* @param firstRow row number for the upper left hand corner
|
|
*/
|
|
public final void setFirstRow(int firstRow) {
|
|
_firstRow = firstRow;
|
|
}
|
|
|
|
/**
|
|
* @param lastCol column number for the lower right hand corner
|
|
*/
|
|
public final void setLastColumn(int lastCol) {
|
|
_lastCol = lastCol;
|
|
}
|
|
|
|
/**
|
|
* @param lastRow row number for the lower right hand corner
|
|
*/
|
|
public final void setLastRow(int lastRow) {
|
|
_lastRow = lastRow;
|
|
}
|
|
/**
|
|
* @return the size of the range (number of cells in the area).
|
|
*/
|
|
public int getNumberOfCells() {
|
|
return (_lastRow - _firstRow + 1) * (_lastCol - _firstCol + 1);
|
|
}
|
|
|
|
@Override
|
|
public final String toString() {
|
|
CellReference crA = new CellReference(_firstRow, _firstCol);
|
|
CellReference crB = new CellReference(_lastRow, _lastCol);
|
|
return getClass().getName() + " [" + crA.formatAsString() + ":" + crB.formatAsString() +"]";
|
|
}
|
|
|
|
// In case _firstRow > _lastRow or _firstCol > _lastCol
|
|
protected int getMinRow() {
|
|
return Math.min(_firstRow, _lastRow);
|
|
}
|
|
protected int getMaxRow() {
|
|
return Math.max(_firstRow, _lastRow);
|
|
}
|
|
protected int getMinColumn() {
|
|
return Math.min(_firstCol, _lastCol);
|
|
}
|
|
protected int getMaxColumn() {
|
|
return Math.max(_firstCol, _lastCol);
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object other) {
|
|
if (other instanceof CellRangeAddressBase) {
|
|
CellRangeAddressBase o = (CellRangeAddressBase) other;
|
|
return ((getMinRow() == o.getMinRow()) &&
|
|
(getMaxRow() == o.getMaxRow()) &&
|
|
(getMinColumn() == o.getMinColumn()) &&
|
|
(getMaxColumn() == o.getMaxColumn()));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
int code = (getMinColumn() +
|
|
(getMaxColumn() << 8) +
|
|
(getMinRow() << 16) +
|
|
(getMaxRow() << 24));
|
|
return code;
|
|
}
|
|
}
|