/**********************************************************************
*
* Copyright (C) 2008 Andrew Khan
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
***************************************************************************/
package jxl.biff;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import jxl.Sheet;
import jxl.Cell;
import jxl.CellType;
import jxl.LabelCell;
/**
* Refactorisation to provide more sophisticated find cell by contents
* functionality
*/
public class CellFinder
{
private Sheet sheet;
public CellFinder(Sheet s)
{
sheet = s;
}
/**
* Gets the cell whose contents match the string passed in.
* If no match is found, then null is returned. The search is performed
* on a row by row basis, so the lower the row number, the more
* efficiently the algorithm will perform
*
* @param contents the string to match
* @param firstCol the first column within the range
* @param firstRow the first row of the range
* @param lastCol the last column within the range
* @param lastRow the last row within the range
* @param reverse indicates whether to perform a reverse search or not
* @return the Cell whose contents match the parameter, null if not found
*/
public Cell findCell(String contents,
int firstCol,
int firstRow,
int lastCol,
int lastRow,
boolean reverse)
{
Cell cell = null;
boolean found = false;
int numCols = lastCol - firstCol;
int numRows = lastRow - firstRow;
int row1 = reverse ? lastRow : firstRow;
int row2 = reverse ? firstRow : lastRow;
int col1 = reverse ? lastCol : firstCol;
int col2 = reverse ? firstCol : lastCol;
int inc = reverse ? -1 : 1;
for (int i = 0; i <= numCols && found == false; i++)
{
for (int j = 0; j <= numRows && found == false; j++)
{
int curCol = col1 + i * inc;
int curRow = row1 + j * inc;
if (curCol < sheet.getColumns() && curRow < sheet.getRows())
{
Cell c = sheet.getCell(curCol, curRow);
if (c.getType() != CellType.EMPTY)
{
if (c.getContents().equals(contents))
{
cell = c;
found = true;
}
}
}
}
}
return cell;
}
/**
* Finds a cell within a given range of cells
*
* @param contents the string to match
* @return the Cell whose contents match the parameter, null if not found
*/
public Cell findCell(String contents)
{
Cell cell = null;
boolean found = false;
for (int i = 0 ; i < sheet.getRows() && found == false; i++)
{
Cell[] row = sheet.getRow(i);
for (int j = 0 ; j < row.length && found == false; j++)
{
if (row[j].getContents().equals(contents))
{
cell = row[j];
found = true;
}
}
}
return cell;
}
/**
* Gets the cell whose contents match the regular expressionstring passed in.
* If no match is found, then null is returned. The search is performed
* on a row by row basis, so the lower the row number, the more
* efficiently the algorithm will perform
*
* @param pattern the regular expression string to match
* @param firstCol the first column within the range
* @param firstRow the first row of the range
* @param lastCol the last column within the range
* @param lastRow the last row within the range
* @param reverse indicates whether to perform a reverse search or not
* @return the Cell whose contents match the parameter, null if not found
*/
public Cell findCell(Pattern pattern,
int firstCol,
int firstRow,
int lastCol,
int lastRow,
boolean reverse)
{
Cell cell = null;
boolean found = false;
int numCols = lastCol - firstCol;
int numRows = lastRow - firstRow;
int row1 = reverse ? lastRow : firstRow;
int row2 = reverse ? firstRow : lastRow;
int col1 = reverse ? lastCol : firstCol;
int col2 = reverse ? firstCol : lastCol;
int inc = reverse ? -1 : 1;
for (int i = 0; i <= numCols && found == false; i++)
{
for (int j = 0; j <= numRows && found == false; j++)
{
int curCol = col1 + i * inc;
int curRow = row1 + j * inc;
if (curCol < sheet.getColumns() && curRow < sheet.getRows())
{
Cell c = sheet.getCell(curCol, curRow);
if (c.getType() != CellType.EMPTY)
{
Matcher m = pattern.matcher(c.getContents());
if (m.matches())
{
cell = c;
found = true;
}
}
}
}
}
return cell;
}
/**
* Gets the cell whose contents match the string passed in.
* If no match is found, then null is returned. The search is performed
* on a row by row basis, so the lower the row number, the more
* efficiently the algorithm will perform. This method differs
* from the findCell methods in that only cells with labels are
* queried - all numerical cells are ignored. This should therefore
* improve performance.
*
* @param contents the string to match
* @return the Cell whose contents match the paramter, null if not found
*/
public LabelCell findLabelCell(String contents)
{
LabelCell cell = null;
boolean found = false;
for (int i = 0; i < sheet.getRows() && !found; i++)
{
Cell[] row = sheet.getRow(i);
for (int j = 0; j < row.length && !found; j++)
{
if ((row[j].getType() == CellType.LABEL ||
row[j].getType() == CellType.STRING_FORMULA) &&
row[j].getContents().equals(contents))
{
cell = (LabelCell) row[j];
found = true;
}
}
}
return cell;
}
}
|