<!-- Don't forget to update status.xml too! -->
<release version="3.1.1-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="add">Made HSSFFormulaEvaluator no longer require initialisation with sheet or row</action>
<action dev="POI-DEVELOPERS" type="add">Extended support for cached results of formula cells</action>
<action dev="POI-DEVELOPERS" type="fix">45639 - Fixed AIOOBE due to bad index logic in ColumnInfoRecordsAggregate</action>
<action dev="POI-DEVELOPERS" type="fix">Fixed special cases of INDEX function (single column/single row, errors)</action>
<!-- Don't forget to update changes.xml too! -->
<changes>
<release version="3.1.1-alpha1" date="2008-??-??">
+ <action dev="POI-DEVELOPERS" type="add">Made HSSFFormulaEvaluator no longer require initialisation with sheet or row</action>
<action dev="POI-DEVELOPERS" type="add">Extended support for cached results of formula cells</action>
<action dev="POI-DEVELOPERS" type="fix">45639 - Fixed AIOOBE due to bad index logic in ColumnInfoRecordsAggregate</action>
<action dev="POI-DEVELOPERS" type="fix">Fixed special cases of INDEX function (single column/single row, errors)</action>
import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.ValueEval;
import org.apache.poi.hssf.record.formula.functions.FreeRefFunction;
-import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
public final class AnalysisToolPak {
private static final FreeRefFunction NotImplemented = new FreeRefFunction() {
- public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol,
- HSSFWorkbook workbook, HSSFSheet sheet) {
+ public ValueEval evaluate(Eval[] args, HSSFWorkbook workbook, int srcCellSheet,
+ int srcCellRow, int srcCellCol) {
return ErrorEval.FUNCTION_NOT_IMPLEMENTED;
}
};
_desiredParity = desiredParity;
}
- public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook,
- HSSFSheet sheet) {
+ public ValueEval evaluate(Eval[] args, HSSFWorkbook workbook, int srcCellSheet, int srcCellRow,
+ int srcCellCol) {
if (args.length != 1) {
return ErrorEval.VALUE_INVALID;
}
return BoolEval.valueOf(val == _desiredParity);
}
- private static int evaluateArgParity(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
- ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
+ private static int evaluateArgParity(Eval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
+ ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short)srcCellCol);
double d = OperandResolver.coerceValueToDouble(ve);
if (d < 0) {
// enforce singleton
}
- public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook,
- HSSFSheet sheet) {
+ public ValueEval evaluate(Eval[] args, HSSFWorkbook workbook, int srcCellSheet, int srcCellRow,
+ int srcCellCol) {
double result;
try {
return new NumberEval(result);
}
- private static double evaluateDateArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
- ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
+ private static double evaluateDateArg(Eval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
+ ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short) srcCellCol);
if (ve instanceof StringEval) {
String strVal = ((StringEval) ve).getStringValue();
return cal;
}
- private static int evaluateIntArg(Eval arg, int srcCellRow, short srcCellCol) throws EvaluationException {
- ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, srcCellCol);
+ private static int evaluateIntArg(Eval arg, int srcCellRow, int srcCellCol) throws EvaluationException {
+ ValueEval ve = OperandResolver.getSingleValue(arg, srcCellRow, (short) srcCellCol);
return OperandResolver.coerceValueToInt(ve);
}
}
import org.apache.poi.hssf.record.formula.atp.AnalysisToolPak;
import org.apache.poi.hssf.record.formula.functions.FreeRefFunction;
-import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
/**
*
*/
final class ExternalFunction implements FreeRefFunction {
- public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet) {
+ public ValueEval evaluate(Eval[] args, HSSFWorkbook workbook,
+ int srcCellSheet, int srcCellRow,int srcCellCol) {
int nIncomingArgs = args.length;
if(nIncomingArgs < 1) {
int nOutGoingArgs = nIncomingArgs -1;
Eval[] outGoingArgs = new Eval[nOutGoingArgs];
System.arraycopy(args, 1, outGoingArgs, 0, nOutGoingArgs);
- return targetFunc.evaluate(outGoingArgs, srcCellRow, srcCellCol, workbook, sheet);
+ return targetFunc.evaluate(outGoingArgs, workbook, srcCellSheet, srcCellRow, srcCellCol);
}
private FreeRefFunction findExternalUserDefinedFunction(HSSFWorkbook workbook,
+++ /dev/null
-/* ====================================================================
- 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.hssf.record.formula.eval;
-
-import org.apache.poi.hssf.record.formula.AreaI;
-import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;
-import org.apache.poi.hssf.usermodel.HSSFCell;
-import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
-import org.apache.poi.hssf.usermodel.HSSFRow;
-import org.apache.poi.hssf.usermodel.HSSFSheet;
-import org.apache.poi.hssf.util.CellReference;
-
-/**
- *
- * @author Josh Micich
- */
-public final class LazyAreaEval extends AreaEvalBase {
-
- private final HSSFSheet _sheet;
- private HSSFFormulaEvaluator _evaluator;
-
- public LazyAreaEval(AreaI ptg, HSSFSheet sheet, HSSFFormulaEvaluator evaluator) {
- super(ptg);
- _sheet = sheet;
- _evaluator = evaluator;
- }
-
- public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
-
- int rowIx = (relativeRowIndex + getFirstRow() ) & 0xFFFF;
- int colIx = (relativeColumnIndex + getFirstColumn() ) & 0x00FF;
-
- HSSFRow row = _sheet.getRow(rowIx);
- if (row == null) {
- return BlankEval.INSTANCE;
- }
- HSSFCell cell = row.getCell(colIx);
- if (cell == null) {
- return BlankEval.INSTANCE;
- }
- return _evaluator.getEvalForCell(cell, _sheet);
- }
-
- public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
- AreaI area = new OffsetArea(getFirstRow(), getFirstColumn(),
- relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
-
- return new LazyAreaEval(area, _sheet, _evaluator);
- }
- public String toString() {
- CellReference crA = new CellReference(getFirstRow(), getFirstColumn());
- CellReference crB = new CellReference(getLastRow(), getLastColumn());
- StringBuffer sb = new StringBuffer();
- sb.append(getClass().getName()).append("[");
- String sheetName = _evaluator.getSheetName(_sheet);
- sb.append(sheetName);
- sb.append('!');
- sb.append(crA.formatAsString());
- sb.append(':');
- sb.append(crB.formatAsString());
- sb.append("]");
- return sb.toString();
- }
-}
+++ /dev/null
-/* ====================================================================\r
- Licensed to the Apache Software Foundation (ASF) under one or more\r
- contributor license agreements. See the NOTICE file distributed with\r
- this work for additional information regarding copyright ownership.\r
- The ASF licenses this file to You under the Apache License, Version 2.0\r
- (the "License"); you may not use this file except in compliance with\r
- the License. You may obtain a copy of the License at\r
-\r
- http://www.apache.org/licenses/LICENSE-2.0\r
-\r
- Unless required by applicable law or agreed to in writing, software\r
- distributed under the License is distributed on an "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- See the License for the specific language governing permissions and\r
- limitations under the License.\r
-==================================================================== */\r
-\r
-package org.apache.poi.hssf.record.formula.eval;\r
-\r
-import org.apache.poi.hssf.record.formula.AreaI;\r
-import org.apache.poi.hssf.record.formula.Ref3DPtg;\r
-import org.apache.poi.hssf.record.formula.RefPtg;\r
-import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;\r
-import org.apache.poi.hssf.usermodel.HSSFCell;\r
-import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;\r
-import org.apache.poi.hssf.usermodel.HSSFRow;\r
-import org.apache.poi.hssf.usermodel.HSSFSheet;\r
-import org.apache.poi.hssf.util.CellReference;\r
-\r
-/**\r
-*\r
-* @author Josh Micich \r
-*/\r
-public final class LazyRefEval extends RefEvalBase {\r
-\r
- private final HSSFSheet _sheet;\r
- private final HSSFFormulaEvaluator _evaluator;\r
-\r
-\r
- public LazyRefEval(RefPtg ptg, HSSFSheet sheet, HSSFFormulaEvaluator evaluator) {\r
- super(ptg.getRow(), ptg.getColumn());\r
- _sheet = sheet;\r
- _evaluator = evaluator;\r
- }\r
- public LazyRefEval(Ref3DPtg ptg, HSSFSheet sheet, HSSFFormulaEvaluator evaluator) {\r
- super(ptg.getRow(), ptg.getColumn());\r
- _sheet = sheet;\r
- _evaluator = evaluator;\r
- }\r
-\r
- public ValueEval getInnerValueEval() {\r
- int rowIx = getRow();\r
- int colIx = getColumn();\r
- \r
- HSSFRow row = _sheet.getRow(rowIx);\r
- if (row == null) {\r
- return BlankEval.INSTANCE;\r
- }\r
- HSSFCell cell = row.getCell(colIx);\r
- if (cell == null) {\r
- return BlankEval.INSTANCE;\r
- }\r
- return _evaluator.getEvalForCell(cell, _sheet);\r
- }\r
- \r
- public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {\r
- \r
- AreaI area = new OffsetArea(getRow(), getColumn(),\r
- relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);\r
-\r
- return new LazyAreaEval(area, _sheet, _evaluator);\r
- }\r
- \r
- public String toString() {\r
- CellReference cr = new CellReference(getRow(), getColumn());\r
- StringBuffer sb = new StringBuffer();\r
- sb.append(getClass().getName()).append("[");\r
- String sheetName = _evaluator.getSheetName(_sheet);\r
- sb.append(sheetName);\r
- sb.append('!');\r
- sb.append(cr.formatAsString());\r
- sb.append("]");\r
- return sb.toString();\r
- }\r
-}\r
*
* @param args the pre-evaluated arguments for this function. args is never <code>null</code>,
* nor are any of its elements.
+ * @param srcCellSheet zero based sheet index of the cell containing the currently evaluating formula
* @param srcCellRow zero based row index of the cell containing the currently evaluating formula
* @param srcCellCol zero based column index of the cell containing the currently evaluating formula
* @param workbook is the workbook containing the formula/cell being evaluated
- * @param sheet is the sheet containing the formula/cell being evaluated
* @return never <code>null</code>. Possibly an instance of <tt>ErrorEval</tt> in the case of
* a specified Excel error (Exceptions are never thrown to represent Excel errors).
*
*/
- ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet);
+ ValueEval evaluate(Eval[] args, HSSFWorkbook workbook, int srcCellSheet, int srcCellRow, int srcCellCol);
}
*/
public final class Indirect implements FreeRefFunction {
- public ValueEval evaluate(Eval[] args, int srcCellRow, short srcCellCol, HSSFWorkbook workbook, HSSFSheet sheet) {
+ public ValueEval evaluate(Eval[] args, HSSFWorkbook workbook, int srcCellSheet, int srcCellRow, int srcCellCol) {
// TODO - implement INDIRECT()
return ErrorEval.FUNCTION_NOT_IMPLEMENTED;
}
private static final class CellEvaluationFrame {
private final HSSFWorkbook _workbook;
- private final HSSFSheet _sheet;
+ private final int _sheetIndex;
private final int _srcRowNum;
private final int _srcColNum;
- public CellEvaluationFrame(HSSFWorkbook workbook, HSSFSheet sheet, int srcRowNum, int srcColNum) {
+ public CellEvaluationFrame(HSSFWorkbook workbook, int sheetIndex, int srcRowNum, int srcColNum) {
if (workbook == null) {
throw new IllegalArgumentException("workbook must not be null");
}
- if (sheet == null) {
- throw new IllegalArgumentException("sheet must not be null");
+ if (sheetIndex < 0) {
+ throw new IllegalArgumentException("sheetIndex must not be negative");
}
_workbook = workbook;
- _sheet = sheet;
+ _sheetIndex = sheetIndex;
_srcRowNum = srcRowNum;
_srcColNum = srcColNum;
}
if (_workbook != other._workbook) {
return false;
}
- if (_sheet != other._sheet) {
+ if (_sheetIndex != other._sheetIndex) {
return false;
}
if (_srcRowNum != other._srcRowNum) {
* @return human readable string for debug purposes
*/
public String formatAsString() {
- return "R=" + _srcRowNum + " C=" + _srcColNum + " ShIx=" + _workbook.getSheetIndex(_sheet);
+ return "R=" + _srcRowNum + " C=" + _srcColNum + " ShIx=" + _sheetIndex;
}
public String toString() {
* @return <code>true</code> if the specified cell has not been visited yet in the current
* evaluation. <code>false</code> if the specified cell is already being evaluated.
*/
- public boolean startEvaluate(HSSFWorkbook workbook, HSSFSheet sheet, int srcRowNum, int srcColNum) {
- CellEvaluationFrame cef = new CellEvaluationFrame(workbook, sheet, srcRowNum, srcColNum);
+ public boolean startEvaluate(HSSFWorkbook workbook, int sheetIndex, int srcRowNum, int srcColNum) {
+ CellEvaluationFrame cef = new CellEvaluationFrame(workbook, sheetIndex, srcRowNum, srcColNum);
if (_evaluationFrames.contains(cef)) {
return false;
}
* required. However, they have been included to assert correct behaviour,
* and form more meaningful error messages.
*/
- public void endEvaluate(HSSFWorkbook workbook, HSSFSheet sheet, int srcRowNum, int srcColNum) {
+ public void endEvaluate(HSSFWorkbook workbook, int sheetIndex, int srcRowNum, int srcColNum) {
int nFrames = _evaluationFrames.size();
if (nFrames < 1) {
throw new IllegalStateException("Call to endEvaluate without matching call to startEvaluate");
nFrames--;
CellEvaluationFrame cefExpected = (CellEvaluationFrame) _evaluationFrames.get(nFrames);
- CellEvaluationFrame cefActual = new CellEvaluationFrame(workbook, sheet, srcRowNum, srcColNum);
+ CellEvaluationFrame cefActual = new CellEvaluationFrame(workbook, sheetIndex, srcRowNum, srcColNum);
if (!cefActual.equals(cefExpected)) {
throw new RuntimeException("Wrong cell specified. "
+ "Corresponding startEvaluate() call was for cell {"
import org.apache.poi.hssf.record.formula.eval.ErrorEval;
import org.apache.poi.hssf.record.formula.eval.Eval;
import org.apache.poi.hssf.record.formula.eval.FunctionEval;
-import org.apache.poi.hssf.record.formula.eval.LazyAreaEval;
-import org.apache.poi.hssf.record.formula.eval.LazyRefEval;
import org.apache.poi.hssf.record.formula.eval.NameEval;
import org.apache.poi.hssf.record.formula.eval.NameXEval;
import org.apache.poi.hssf.record.formula.eval.NumberEval;
*/
public class HSSFFormulaEvaluator {
- /**
- * used to track the number of evaluations
- */
+ /**
+ * used to track the number of evaluations
+ */
private static final class Counter {
public int value;
+ public int depth;
public Counter() {
value = 0;
}
}
- private final HSSFSheet _sheet;
private final HSSFWorkbook _workbook;
private final EvaluationCache _cache;
private Counter _evaluationCounter;
+ /**
+ * @deprecated (Sep 2008) HSSFSheet parameter is ignored
+ */
public HSSFFormulaEvaluator(HSSFSheet sheet, HSSFWorkbook workbook) {
- this(sheet, workbook, new EvaluationCache(), new Counter());
+ this(workbook);
+ if (false) {
+ sheet.toString(); // suppress unused parameter compiler warning
+ }
+ }
+ public HSSFFormulaEvaluator(HSSFWorkbook workbook) {
+ this(workbook, new EvaluationCache(), new Counter());
}
- private HSSFFormulaEvaluator(HSSFSheet sheet, HSSFWorkbook workbook, EvaluationCache cache, Counter evaluationCounter) {
- _sheet = sheet;
+ private HSSFFormulaEvaluator(HSSFWorkbook workbook, EvaluationCache cache, Counter evaluationCounter) {
_workbook = workbook;
_cache = cache;
_evaluationCounter = evaluationCounter;
/**
* for debug use. Used in toString methods
*/
- public String getSheetName(HSSFSheet sheet) {
+ /* package */ String getSheetName(HSSFSheet sheet) {
return _workbook.getSheetName(_workbook.getSheetIndex(sheet));
}
/**
* @param cell
*/
public CellValue evaluate(HSSFCell cell) {
- CellValue retval = null;
- if (cell != null) {
- switch (cell.getCellType()) {
- case HSSFCell.CELL_TYPE_BLANK:
- retval = new CellValue(HSSFCell.CELL_TYPE_BLANK);
- break;
+ if (cell == null) {
+ return null;
+ }
+
+ switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_BOOLEAN:
- retval = new CellValue(HSSFCell.CELL_TYPE_BOOLEAN);
- retval.setBooleanValue(cell.getBooleanCellValue());
- break;
+ return CellValue.valueOf(cell.getBooleanCellValue());
case HSSFCell.CELL_TYPE_ERROR:
- retval = new CellValue(HSSFCell.CELL_TYPE_ERROR);
- retval.setErrorValue(cell.getErrorCellValue());
- break;
+ return CellValue.getError(cell.getErrorCellValue());
case HSSFCell.CELL_TYPE_FORMULA:
- retval = getCellValueForEval(internalEvaluate(cell, _sheet));
- break;
+ return evaluateFormulaCellValue(cell);
case HSSFCell.CELL_TYPE_NUMERIC:
- retval = new CellValue(HSSFCell.CELL_TYPE_NUMERIC);
- retval.setNumberValue(cell.getNumericCellValue());
- break;
+ return new CellValue(cell.getNumericCellValue());
case HSSFCell.CELL_TYPE_STRING:
- retval = new CellValue(HSSFCell.CELL_TYPE_STRING);
- retval.setRichTextStringValue(cell.getRichStringCellValue());
- break;
- }
+ return new CellValue(cell.getRichStringCellValue());
}
- return retval;
+ throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")");
}
* @return The type of the formula result (the cell's type remains as HSSFCell.CELL_TYPE_FORMULA however)
*/
public int evaluateFormulaCell(HSSFCell cell) {
- if (cell != null) {
- switch (cell.getCellType()) {
- case HSSFCell.CELL_TYPE_FORMULA:
- CellValue cv = getCellValueForEval(internalEvaluate(cell, _sheet));
- switch (cv.getCellType()) {
- case HSSFCell.CELL_TYPE_BOOLEAN:
- cell.setCellValue(cv.getBooleanValue());
- break;
- case HSSFCell.CELL_TYPE_ERROR:
- cell.setCellValue(cv.getErrorValue());
- break;
- case HSSFCell.CELL_TYPE_NUMERIC:
- cell.setCellValue(cv.getNumberValue());
- break;
- case HSSFCell.CELL_TYPE_STRING:
- cell.setCellValue(cv.getRichTextStringValue());
- break;
- case HSSFCell.CELL_TYPE_BLANK:
- break;
- case HSSFCell.CELL_TYPE_FORMULA: // this will never happen, we have already evaluated the formula
- break;
- }
- return cv.getCellType();
- }
+ if (cell == null || cell.getCellType() != HSSFCell.CELL_TYPE_FORMULA) {
+ return -1;
}
- return -1;
+ CellValue cv = evaluateFormulaCellValue(cell);
+ // cell remains a formula cell, but the cached value is changed
+ setCellValue(cell, cv);
+ return cv.getCellType();
}
/**
* @param cell
*/
public HSSFCell evaluateInCell(HSSFCell cell) {
- if (cell != null) {
- switch (cell.getCellType()) {
- case HSSFCell.CELL_TYPE_FORMULA:
- CellValue cv = getCellValueForEval(internalEvaluate(cell, _sheet));
- switch (cv.getCellType()) {
- case HSSFCell.CELL_TYPE_BOOLEAN:
- cell.setCellType(HSSFCell.CELL_TYPE_BOOLEAN);
- cell.setCellValue(cv.getBooleanValue());
- break;
- case HSSFCell.CELL_TYPE_ERROR:
- cell.setCellErrorValue(cv.getErrorValue());
- break;
- case HSSFCell.CELL_TYPE_NUMERIC:
- cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
- cell.setCellValue(cv.getNumberValue());
- break;
- case HSSFCell.CELL_TYPE_STRING:
- cell.setCellType(HSSFCell.CELL_TYPE_STRING);
- cell.setCellValue(cv.getRichTextStringValue());
- break;
- case HSSFCell.CELL_TYPE_BLANK:
- break;
- case HSSFCell.CELL_TYPE_FORMULA: // this will never happen, we have already evaluated the formula
- break;
- }
- }
+ if (cell == null) {
+ return null;
+ }
+ if (cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
+ CellValue cv = evaluateFormulaCellValue(cell);
+ setCellType(cell, cv); // cell will no longer be a formula cell
+ setCellValue(cell, cv);
}
return cell;
}
+ private static void setCellType(HSSFCell cell, CellValue cv) {
+ int cellType = cv.getCellType();
+ switch (cellType) {
+ case HSSFCell.CELL_TYPE_BOOLEAN:
+ case HSSFCell.CELL_TYPE_ERROR:
+ case HSSFCell.CELL_TYPE_NUMERIC:
+ case HSSFCell.CELL_TYPE_STRING:
+ cell.setCellType(cellType);
+ return;
+ case HSSFCell.CELL_TYPE_BLANK:
+ // never happens - blanks eventually get translated to zero
+ case HSSFCell.CELL_TYPE_FORMULA:
+ // this will never happen, we have already evaluated the formula
+ }
+ throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
+ }
+
+ private static void setCellValue(HSSFCell cell, CellValue cv) {
+ int cellType = cv.getCellType();
+ switch (cellType) {
+ case HSSFCell.CELL_TYPE_BOOLEAN:
+ cell.setCellValue(cv.getBooleanValue());
+ break;
+ case HSSFCell.CELL_TYPE_ERROR:
+ cell.setCellErrorValue(cv.getErrorValue());
+ break;
+ case HSSFCell.CELL_TYPE_NUMERIC:
+ cell.setCellValue(cv.getNumberValue());
+ break;
+ case HSSFCell.CELL_TYPE_STRING:
+ cell.setCellValue(cv.getRichTextStringValue());
+ break;
+ case HSSFCell.CELL_TYPE_BLANK:
+ // never happens - blanks eventually get translated to zero
+ case HSSFCell.CELL_TYPE_FORMULA:
+ // this will never happen, we have already evaluated the formula
+ default:
+ throw new IllegalStateException("Unexpected cell value type (" + cellType + ")");
+ }
+ }
/**
* Loops over all cells in all sheets of the supplied
* cells, and calling evaluateFormulaCell on each one.
*/
public static void evaluateAllFormulaCells(HSSFWorkbook wb) {
+ HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb);
for(int i=0; i<wb.getNumberOfSheets(); i++) {
HSSFSheet sheet = wb.getSheetAt(i);
- HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
for (Iterator rit = sheet.rowIterator(); rit.hasNext();) {
HSSFRow r = (HSSFRow)rit.next();
}
}
-
/**
* Returns a CellValue wrapper around the supplied ValueEval instance.
* @param eval
*/
- private static CellValue getCellValueForEval(ValueEval eval) {
- CellValue retval = null;
- if (eval != null) {
- if (eval instanceof NumberEval) {
- NumberEval ne = (NumberEval) eval;
- retval = new CellValue(HSSFCell.CELL_TYPE_NUMERIC);
- retval.setNumberValue(ne.getNumberValue());
- }
- else if (eval instanceof BoolEval) {
- BoolEval be = (BoolEval) eval;
- retval = new CellValue(HSSFCell.CELL_TYPE_BOOLEAN);
- retval.setBooleanValue(be.getBooleanValue());
- }
- else if (eval instanceof StringEval) {
- StringEval ne = (StringEval) eval;
- retval = new CellValue(HSSFCell.CELL_TYPE_STRING);
- retval.setStringValue(ne.getStringValue());
- }
- else if (eval instanceof BlankEval) {
- retval = new CellValue(HSSFCell.CELL_TYPE_BLANK);
- }
- else if (eval instanceof ErrorEval) {
- retval = new CellValue(HSSFCell.CELL_TYPE_ERROR);
- retval.setErrorValue((byte)((ErrorEval)eval).getErrorCode());
-// retval.setRichTextStringValue(new HSSFRichTextString("#An error occurred. check cell.getErrorCode()"));
- }
- else {
- retval = new CellValue(HSSFCell.CELL_TYPE_ERROR);
- }
+ private CellValue evaluateFormulaCellValue(HSSFCell cell) {
+ ValueEval eval = internalEvaluate(cell);
+ if (eval instanceof NumberEval) {
+ NumberEval ne = (NumberEval) eval;
+ return new CellValue(ne.getNumberValue());
}
- return retval;
+ if (eval instanceof BoolEval) {
+ BoolEval be = (BoolEval) eval;
+ return CellValue.valueOf(be.getBooleanValue());
+ }
+ if (eval instanceof StringEval) {
+ StringEval ne = (StringEval) eval;
+ return new CellValue(new HSSFRichTextString(ne.getStringValue()));
+ }
+ if (eval instanceof ErrorEval) {
+ return CellValue.getError(((ErrorEval)eval).getErrorCode());
+ }
+ throw new RuntimeException("Unexpected eval class (" + eval.getClass().getName() + ")");
}
/**
* Dev. Note: Internal evaluate must be passed only a formula cell
* else a runtime exception will be thrown somewhere inside the method.
* (Hence this is a private method.)
+ * @return never <code>null</code>, never {@link BlankEval}
*/
- private ValueEval internalEvaluate(HSSFCell srcCell, HSSFSheet sheet) {
+ private ValueEval internalEvaluate(HSSFCell srcCell) {
int srcRowNum = srcCell.getRowIndex();
int srcColNum = srcCell.getCellNum();
ValueEval result;
- int sheetIndex = _workbook.getSheetIndex(sheet);
+ int sheetIndex = _workbook.findSheetIndex(srcCell.getSheet());
result = _cache.getValue(sheetIndex, srcRowNum, srcColNum);
if (result != null) {
return result;
}
_evaluationCounter.value++;
+ _evaluationCounter.depth++;
EvaluationCycleDetector tracker = EvaluationCycleDetectorManager.getTracker();
- if(!tracker.startEvaluate(_workbook, sheet, srcRowNum, srcColNum)) {
+ if(!tracker.startEvaluate(_workbook, sheetIndex, srcRowNum, srcColNum)) {
return ErrorEval.CIRCULAR_REF_ERROR;
}
try {
- result = evaluateCell(srcRowNum, (short)srcColNum, srcCell.getCellFormula());
+ result = evaluateCell(sheetIndex, srcRowNum, (short)srcColNum, srcCell.getCellFormula());
} finally {
- tracker.endEvaluate(_workbook, sheet, srcRowNum, srcColNum);
+ tracker.endEvaluate(_workbook, sheetIndex, srcRowNum, srcColNum);
_cache.setValue(sheetIndex, srcRowNum, srcColNum, result);
+ _evaluationCounter.depth--;
}
if (isDebugLogEnabled()) {
String sheetName = _workbook.getSheetName(sheetIndex);
}
return result;
}
- private ValueEval evaluateCell(int srcRowNum, short srcColNum, String cellFormulaText) {
+ private ValueEval evaluateCell(int sheetIndex, int srcRowNum, short srcColNum, String cellFormulaText) {
Ptg[] ptgs = FormulaParser.parse(cellFormulaText, _workbook);
Eval p = (Eval) stack.pop();
ops[j] = p;
}
- logDebug("invoke " + operation + " (nAgs=" + numops + ")");
- opResult = invokeOperation(operation, ops, srcRowNum, srcColNum, _workbook, _sheet);
+// logDebug("invoke " + operation + " (nAgs=" + numops + ")");
+ opResult = invokeOperation(operation, ops, _workbook, sheetIndex, srcRowNum, srcColNum);
} else {
- opResult = getEvalForPtg(ptg, _sheet);
+ opResult = getEvalForPtg(ptg, sheetIndex);
}
if (opResult == null) {
throw new RuntimeException("Evaluation result must not be null");
}
- logDebug("push " + opResult);
+// logDebug("push " + opResult);
stack.push(opResult);
}
return evaluationResult;
}
- private static Eval invokeOperation(OperationEval operation, Eval[] ops, int srcRowNum, short srcColNum,
- HSSFWorkbook workbook, HSSFSheet sheet) {
+ private static Eval invokeOperation(OperationEval operation, Eval[] ops,
+ HSSFWorkbook workbook, int sheetIndex, int srcRowNum, int srcColNum) {
if(operation instanceof FunctionEval) {
FunctionEval fe = (FunctionEval) operation;
if(fe.isFreeRefFunction()) {
- return fe.getFreeRefFunction().evaluate(ops, srcRowNum, srcColNum, workbook, sheet);
+ return fe.getFreeRefFunction().evaluate(ops, workbook, sheetIndex, srcRowNum, srcColNum);
}
}
- return operation.evaluate(ops, srcRowNum, srcColNum);
+ return operation.evaluate(ops, srcRowNum, (short)srcColNum);
}
private HSSFSheet getOtherSheet(int externSheetIndex) {
Workbook wb = _workbook.getWorkbook();
return _workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(externSheetIndex));
}
- private HSSFFormulaEvaluator createEvaluatorForAnotherSheet(HSSFSheet sheet) {
- return new HSSFFormulaEvaluator(sheet, _workbook, _cache, _evaluationCounter);
- }
/**
* returns an appropriate Eval impl instance for the Ptg. The Ptg must be
* StringPtg, BoolPtg <br/>special Note: OperationPtg subtypes cannot be
* passed here!
*/
- private Eval getEvalForPtg(Ptg ptg, HSSFSheet sheet) {
+ private Eval getEvalForPtg(Ptg ptg, int sheetIndex) {
if (ptg instanceof NamePtg) {
// named ranges, macro functions
NamePtg namePtg = (NamePtg) ptg;
return new NameEval(nameRecord.getNameText());
}
if (nameRecord.hasFormula()) {
- return evaluateNameFormula(nameRecord.getNameDefinition(), sheet);
+ return evaluateNameFormula(nameRecord.getNameDefinition(), sheetIndex);
}
throw new RuntimeException("Don't now how to evalate name '" + nameRecord.getNameText() + "'");
NameXPtg nameXPtg = (NameXPtg) ptg;
return new NameXEval(nameXPtg.getSheetRefIndex(), nameXPtg.getNameIndex());
}
- if (ptg instanceof RefPtg) {
- return new LazyRefEval(((RefPtg) ptg), sheet, this);
- }
- if (ptg instanceof Ref3DPtg) {
- Ref3DPtg refPtg = (Ref3DPtg) ptg;
- HSSFSheet xsheet = getOtherSheet(refPtg.getExternSheetIndex());
- return new LazyRefEval(refPtg, xsheet, createEvaluatorForAnotherSheet(xsheet));
- }
- if (ptg instanceof AreaPtg) {
- return new LazyAreaEval(((AreaPtg) ptg), sheet, this);
- }
- if (ptg instanceof Area3DPtg) {
- Area3DPtg a3dp = (Area3DPtg) ptg;
- HSSFSheet xsheet = getOtherSheet(a3dp.getExternSheetIndex());
- return new LazyAreaEval(a3dp, xsheet, createEvaluatorForAnotherSheet(xsheet));
- }
if (ptg instanceof IntPtg) {
return new NumberEval(((IntPtg)ptg).getValue());
if (ptg instanceof ErrPtg) {
return ErrorEval.valueOf(((ErrPtg) ptg).getErrorCode());
}
+ HSSFSheet sheet = _workbook.getSheetAt(sheetIndex);
+ if (ptg instanceof RefPtg) {
+ return new LazyRefEval(((RefPtg) ptg), sheet, this);
+ }
+ if (ptg instanceof AreaPtg) {
+ return new LazyAreaEval(((AreaPtg) ptg), sheet, this);
+ }
+ if (ptg instanceof Ref3DPtg) {
+ Ref3DPtg refPtg = (Ref3DPtg) ptg;
+ HSSFSheet xsheet = getOtherSheet(refPtg.getExternSheetIndex());
+ return new LazyRefEval(refPtg, xsheet, this);
+ }
+ if (ptg instanceof Area3DPtg) {
+ Area3DPtg a3dp = (Area3DPtg) ptg;
+ HSSFSheet xsheet = getOtherSheet(a3dp.getExternSheetIndex());
+ return new LazyAreaEval(a3dp, xsheet, this);
+ }
+
if (ptg instanceof UnknownPtg) {
- // TODO - remove UnknownPtg
+ // POI uses UnknownPtg when the encoded Ptg array seems to be corrupted.
+ // This seems to occur in very rare cases (e.g. unused name formulas in bug 44774, attachment 21790)
+ // In any case, formulas are re-parsed before execution, so UnknownPtg should not get here
throw new RuntimeException("UnknownPtg not allowed");
}
+
throw new RuntimeException("Unexpected ptg class (" + ptg.getClass().getName() + ")");
}
- private Eval evaluateNameFormula(Ptg[] ptgs, HSSFSheet sheet) {
+ private Eval evaluateNameFormula(Ptg[] ptgs, int sheetIndex) {
if (ptgs.length > 1) {
throw new RuntimeException("Complex name formulas not supported yet");
}
- return getEvalForPtg(ptgs[0], sheet);
+ return getEvalForPtg(ptgs[0], sheetIndex);
}
/**
* impl instance and return that. Since the cell could be an external
* reference, we need the sheet that this belongs to.
* Non existent cells are treated as empty.
- * @param cell
- * @param sheet
- * @param workbook
*/
- public ValueEval getEvalForCell(HSSFCell cell, HSSFSheet sheet) {
+ /* package */ ValueEval getEvalForCell(HSSFCell cell) {
if (cell == null) {
return BlankEval.INSTANCE;
case HSSFCell.CELL_TYPE_STRING:
return new StringEval(cell.getRichStringCellValue().getString());
case HSSFCell.CELL_TYPE_FORMULA:
- return internalEvaluate(cell, sheet);
+ return internalEvaluate(cell);
case HSSFCell.CELL_TYPE_BOOLEAN:
return BoolEval.valueOf(cell.getBooleanCellValue());
case HSSFCell.CELL_TYPE_BLANK:
* @author Amol S. Deshmukh < amolweb at ya hoo dot com >
*/
public static final class CellValue {
- private int cellType;
- private HSSFRichTextString richTextStringValue;
- private double numberValue;
- private boolean booleanValue;
- private byte errorValue;
-
- /**
- * CellType should be one of the types defined in HSSFCell
- * @param cellType
- */
- public CellValue(int cellType) {
- super();
- this.cellType = cellType;
- }
+ public static final CellValue TRUE = new CellValue(HSSFCell.CELL_TYPE_BOOLEAN, 0.0, true, null, 0);
+ public static final CellValue FALSE= new CellValue(HSSFCell.CELL_TYPE_BOOLEAN, 0.0, false, null, 0);
+
+ private final int _cellType;
+ private final double _numberValue;
+ private final boolean _booleanValue;
+ private final HSSFRichTextString _richTextStringValue;
+ private final int _errorCode;
+
+ private CellValue(int cellType, double numberValue, boolean booleanValue,
+ HSSFRichTextString textValue, int errorCode) {
+ _cellType = cellType;
+ _numberValue = numberValue;
+ _booleanValue = booleanValue;
+ _richTextStringValue = textValue;
+ _errorCode = errorCode;
+ }
+
+
+ /* package*/ CellValue(double numberValue) {
+ this(HSSFCell.CELL_TYPE_NUMERIC, numberValue, false, null, 0);
+ }
+ /* package*/ static CellValue valueOf(boolean booleanValue) {
+ return booleanValue ? TRUE : FALSE;
+ }
+ /* package*/ CellValue(HSSFRichTextString stringValue) {
+ this(HSSFCell.CELL_TYPE_STRING, 0.0, false, stringValue, 0);
+ }
+ /* package*/ static CellValue getError(int errorCode) {
+ return new CellValue(HSSFCell.CELL_TYPE_ERROR, 0.0, false, null, errorCode);
+ }
+
+
/**
* @return Returns the booleanValue.
*/
public boolean getBooleanValue() {
- return booleanValue;
- }
- /**
- * @param booleanValue The booleanValue to set.
- */
- public void setBooleanValue(boolean booleanValue) {
- this.booleanValue = booleanValue;
+ return _booleanValue;
}
/**
* @return Returns the numberValue.
*/
public double getNumberValue() {
- return numberValue;
- }
- /**
- * @param numberValue The numberValue to set.
- */
- public void setNumberValue(double numberValue) {
- this.numberValue = numberValue;
+ return _numberValue;
}
/**
* @return Returns the stringValue. This method is deprecated, use
* @deprecated
*/
public String getStringValue() {
- return richTextStringValue.getString();
- }
- /**
- * @param stringValue The stringValue to set. This method is deprecated, use
- * getRichTextStringValue instead.
- * @deprecated
- */
- public void setStringValue(String stringValue) {
- this.richTextStringValue = new HSSFRichTextString(stringValue);
+ return _richTextStringValue.getString();
}
/**
* @return Returns the cellType.
*/
public int getCellType() {
- return cellType;
+ return _cellType;
}
/**
* @return Returns the errorValue.
*/
public byte getErrorValue() {
- return errorValue;
- }
- /**
- * @param errorValue The errorValue to set.
- */
- public void setErrorValue(byte errorValue) {
- this.errorValue = errorValue;
+ return (byte) _errorCode;
}
/**
* @return Returns the richTextStringValue.
*/
public HSSFRichTextString getRichTextStringValue() {
- return richTextStringValue;
- }
- /**
- * @param richTextStringValue The richTextStringValue to set.
- */
- public void setRichTextStringValue(HSSFRichTextString richTextStringValue) {
- this.richTextStringValue = richTextStringValue;
+ return _richTextStringValue;
}
}
--- /dev/null
+/* ====================================================================
+ 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.hssf.usermodel;
+
+import org.apache.poi.hssf.record.formula.AreaI;
+import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;
+import org.apache.poi.hssf.record.formula.eval.AreaEval;
+import org.apache.poi.hssf.record.formula.eval.AreaEvalBase;
+import org.apache.poi.hssf.record.formula.eval.BlankEval;
+import org.apache.poi.hssf.record.formula.eval.ValueEval;
+import org.apache.poi.hssf.util.CellReference;
+
+/**
+ *
+ * @author Josh Micich
+ */
+final class LazyAreaEval extends AreaEvalBase {
+
+ private final HSSFSheet _sheet;
+ private HSSFFormulaEvaluator _evaluator;
+
+ public LazyAreaEval(AreaI ptg, HSSFSheet sheet, HSSFFormulaEvaluator evaluator) {
+ super(ptg);
+ _sheet = sheet;
+ _evaluator = evaluator;
+ }
+
+ public ValueEval getRelativeValue(int relativeRowIndex, int relativeColumnIndex) {
+
+ int rowIx = (relativeRowIndex + getFirstRow() ) & 0xFFFF;
+ int colIx = (relativeColumnIndex + getFirstColumn() ) & 0x00FF;
+
+ HSSFRow row = _sheet.getRow(rowIx);
+ if (row == null) {
+ return BlankEval.INSTANCE;
+ }
+ HSSFCell cell = row.getCell(colIx);
+ if (cell == null) {
+ return BlankEval.INSTANCE;
+ }
+ return _evaluator.getEvalForCell(cell);
+ }
+
+ public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {
+ AreaI area = new OffsetArea(getFirstRow(), getFirstColumn(),
+ relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);
+
+ return new LazyAreaEval(area, _sheet, _evaluator);
+ }
+ public String toString() {
+ CellReference crA = new CellReference(getFirstRow(), getFirstColumn());
+ CellReference crB = new CellReference(getLastRow(), getLastColumn());
+ StringBuffer sb = new StringBuffer();
+ sb.append(getClass().getName()).append("[");
+ String sheetName = _evaluator.getSheetName(_sheet);
+ sb.append(sheetName);
+ sb.append('!');
+ sb.append(crA.formatAsString());
+ sb.append(':');
+ sb.append(crB.formatAsString());
+ sb.append("]");
+ return sb.toString();
+ }
+}
--- /dev/null
+/* ====================================================================\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to You under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+==================================================================== */\r
+\r
+package org.apache.poi.hssf.usermodel;\r
+\r
+import org.apache.poi.hssf.record.formula.AreaI;\r
+import org.apache.poi.hssf.record.formula.Ref3DPtg;\r
+import org.apache.poi.hssf.record.formula.RefPtg;\r
+import org.apache.poi.hssf.record.formula.AreaI.OffsetArea;\r
+import org.apache.poi.hssf.record.formula.eval.AreaEval;\r
+import org.apache.poi.hssf.record.formula.eval.BlankEval;\r
+import org.apache.poi.hssf.record.formula.eval.RefEvalBase;\r
+import org.apache.poi.hssf.record.formula.eval.ValueEval;\r
+import org.apache.poi.hssf.util.CellReference;\r
+\r
+/**\r
+*\r
+* @author Josh Micich \r
+*/\r
+final class LazyRefEval extends RefEvalBase {\r
+\r
+ private final HSSFSheet _sheet;\r
+ private final HSSFFormulaEvaluator _evaluator;\r
+\r
+\r
+ public LazyRefEval(RefPtg ptg, HSSFSheet sheet, HSSFFormulaEvaluator evaluator) {\r
+ super(ptg.getRow(), ptg.getColumn());\r
+ _sheet = sheet;\r
+ _evaluator = evaluator;\r
+ }\r
+ public LazyRefEval(Ref3DPtg ptg, HSSFSheet sheet, HSSFFormulaEvaluator evaluator) {\r
+ super(ptg.getRow(), ptg.getColumn());\r
+ _sheet = sheet;\r
+ _evaluator = evaluator;\r
+ }\r
+\r
+ public ValueEval getInnerValueEval() {\r
+ int rowIx = getRow();\r
+ int colIx = getColumn();\r
+ \r
+ HSSFRow row = _sheet.getRow(rowIx);\r
+ if (row == null) {\r
+ return BlankEval.INSTANCE;\r
+ }\r
+ HSSFCell cell = row.getCell(colIx);\r
+ if (cell == null) {\r
+ return BlankEval.INSTANCE;\r
+ }\r
+ return _evaluator.getEvalForCell(cell);\r
+ }\r
+ \r
+ public AreaEval offset(int relFirstRowIx, int relLastRowIx, int relFirstColIx, int relLastColIx) {\r
+ \r
+ AreaI area = new OffsetArea(getRow(), getColumn(),\r
+ relFirstRowIx, relLastRowIx, relFirstColIx, relLastColIx);\r
+\r
+ return new LazyAreaEval(area, _sheet, _evaluator);\r
+ }\r
+ \r
+ public String toString() {\r
+ CellReference cr = new CellReference(getRow(), getColumn());\r
+ StringBuffer sb = new StringBuffer();\r
+ sb.append(getClass().getName()).append("[");\r
+ String sheetName = _evaluator.getSheetName(_sheet);\r
+ sb.append(sheetName);\r
+ sb.append('!');\r
+ sb.append(cr.formatAsString());\r
+ sb.append("]");\r
+ return sb.toString();\r
+ }\r
+}\r
sheet.createRow(32768).createCell(0).setCellValue(31);
sheet.createRow(32769).createCell(0).setCellValue(11);
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
CellValue result;
try {
result = fe.evaluate(cell);
public void testEvaluate() {
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("externalFunctionExample.xls");
HSSFSheet sheet = wb.getSheetAt(0);
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
confirmCellEval(sheet, 0, 0, fe, "YEARFRAC(B1,C1)", 29.0/90.0);
confirmCellEval(sheet, 1, 0, fe, "YEARFRAC(B2,C2)", 0.0);
confirmCellEval(sheet, 2, 0, fe, "YEARFRAC(B3,C3,D3)", 0.0);
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("yearfracExamples.xls");
HSSFSheet sheet = wb.getSheetAt(0);
- HSSFFormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator formulaEvaluator = new HSSFFormulaEvaluator(wb);
int nSuccess = 0;
int nFailures = 0;
int nUnexpectedErrors = 0;
/**
* Translates StackOverflowError into AssertionFailedError
*/
- private static CellValue evaluateWithCycles(HSSFWorkbook wb, HSSFSheet sheet, HSSFCell testCell)
+ private static CellValue evaluateWithCycles(HSSFWorkbook wb, HSSFCell testCell)
throws AssertionFailedError {
- HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb);
try {
return evaluator.evaluate(testCell);
} catch (StackOverflowError e) {
// arguments before invoking operators, POI must handle such potential cycles gracefully.
- CellValue cellValue = evaluateWithCycles(wb, sheet, testCell);
+ CellValue cellValue = evaluateWithCycles(wb, testCell);
assertTrue(cellValue.getCellType() == HSSFCell.CELL_TYPE_NUMERIC);
assertEquals(2, cellValue.getNumberValue(), 0);
HSSFCell testCell = row.createCell(0);
testCell.setCellFormula("A1");
- CellValue cellValue = evaluateWithCycles(wb, sheet, testCell);
+ CellValue cellValue = evaluateWithCycles(wb, testCell);
confirmCycleErrorCode(cellValue);
}
HSSFCell testCell = row.createCell(3);
testCell.setCellFormula("A1");
- CellValue cellValue = evaluateWithCycles(wb, sheet, testCell);
+ CellValue cellValue = evaluateWithCycles(wb, testCell);
confirmCycleErrorCode(cellValue);
}
String actualFormula=cell.getCellFormula();
assertEquals("myFunc()", actualFormula);
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
CellValue evalResult = fe.evaluate(cell);
// Check the return value from ExternalFunction.evaluate()
.getCellFormula());
// We might as well evaluate the formula
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
CellValue cv = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType());
}
// use POI's evaluator as an extra sanity check
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
CellValue cv;
cv = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType());
double expectedResult = (4.0 * 8.0 + 5.0 * 9.0) / 10.0;
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet1, wb);
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
CellValue cv = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType());
*/
private void processFunctionGroup(int startRowIndex, String testFocusFunctionName) {
- HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, workbook);
+ HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(workbook);
int rowIndex = startRowIndex;
while (true) {
cell.setCellFormula("B1%");
row.createCell(1).setCellValue(50.0);
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
CellValue cv;
try {
cv = fe.evaluate(cell);
int failureCount = 0;
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook(FILE_NAME);
HSSFSheet sheet = wb.getSheetAt(0);
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
int maxRow = sheet.getLastRowNum();
for (int rowIx=START_ROW_IX; rowIx<maxRow; rowIx++) {
HSSFRow row = sheet.getRow(rowIx);
HSSFSheet sheet = wb.createSheet("new sheet");
cell11 = sheet.createRow(0).createCell(0);
cell11.setCellType(HSSFCell.CELL_TYPE_FORMULA);
- evaluator = new HSSFFormulaEvaluator(sheet, wb);
+ evaluator = new HSSFFormulaEvaluator(wb);
}
/**
private void processTestSheet(HSSFWorkbook workbook, String sheetName) {
HSSFSheet sheet = workbook.getSheetAt(0);
- HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, workbook);
+ HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(workbook);
int maxRows = sheet.getLastRowNum()+1;
int result = Result.NO_EVALUATIONS_FOUND; // so far
cell.setCellFormula("isblank(Sheet2!A1:A1)");
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet1, wb);
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
CellValue result = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_BOOLEAN, result.getCellType());
assertEquals(true, result.getBooleanValue());
private int processTestSheet(HSSFWorkbook workbook, int sheetIndex, String sheetName) {
HSSFSheet sheet = workbook.getSheetAt(sheetIndex);
- HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, workbook);
+ HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(workbook);
int maxRows = sheet.getLastRowNum()+1;
int result = Result.NO_EVALUATIONS_FOUND; // so far
}
private static void process(HSSFWorkbook wb) {
+ HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(wb);
for(int i=0; i<wb.getNumberOfSheets(); i++) {
HSSFSheet s = wb.getSheetAt(i);
- HSSFFormulaEvaluator eval =
- new HSSFFormulaEvaluator(s, wb);
Iterator it = s.rowIterator();
while(it.hasNext()) {
}
public void testBug43093() {
- HSSFWorkbook xlw = new HSSFWorkbook();
+ HSSFWorkbook xlw = new HSSFWorkbook();
addNewSheetWithCellsA1toD4(xlw, 1);
addNewSheetWithCellsA1toD4(xlw, 2);
HSSFCell s2E4 = s2r3.createCell(4);
s2E4.setCellFormula("SUM(s3!B2:C3)");
- HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(s2, xlw);
+ HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(xlw);
double d = eva.evaluate(s2E4).getNumberValue();
// internalEvaluate(...) Area3DEval.: 311+312+321+322 expected
// Now evaluate, they should all be changed
- HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(s, wb);
+ HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(wb);
eval.evaluateFormulaCell(c1);
eval.evaluateFormulaCell(c2);
eval.evaluateFormulaCell(c3);
HSSFSheet sheet = wb.getSheetAt(0);
- HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(wb);
row = sheet.getRow(0);
cell = row.getCell(0);
HSSFSheet sheet = wb.getSheetAt(0);
- HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator eva = new HSSFFormulaEvaluator(wb);
// =index(C:C,2,1) -> 2
HSSFRow rowIDX = sheet.getRow(3);
cell.setCellFormula("1=1");
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
try {
fe.evaluateInCell(cell);
} catch (NumberFormatException e) {
int numSheets = wb.getNumberOfSheets();
for (int i = 0; i < numSheets; i++) {
HSSFSheet s = wb.getSheetAt(i);
- HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(s, wb);
+ HSSFFormulaEvaluator eval = new HSSFFormulaEvaluator(wb);
for (Iterator rows = s.rowIterator(); rows.hasNext();) {
HSSFRow r = (HSSFRow) rows.next();
HSSFRow row = sheet.createRow(1);
HSSFCell cell = row.createCell(0);
cell.setCellFormula("na()"); // this formula evaluates to an Excel error code '#N/A'
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
try {
fe.evaluateInCell(cell);
} catch (NumberFormatException e) {
// Choose cell A9, so that the failing test case doesn't take too long to execute.
HSSFCell cell = row.getCell(8);
- HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb);
evaluator.evaluate(cell);
int evalCount = evaluator.getEvaluationCount();
// With caching, the evaluationCount is 8 which is a big improvement
// uses evaluateFormulaCell()
for(int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) {
HSSFSheet sheet = wb.getSheetAt(sheetNum);
- HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb);
for(Iterator rit = sheet.rowIterator(); rit.hasNext();) {
HSSFRow r = (HSSFRow)rit.next();
// uses evaluateInCell()
for(int sheetNum = 0; sheetNum < wb.getNumberOfSheets(); sheetNum++) {
HSSFSheet sheet = wb.getSheetAt(sheetNum);
- HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb);
for(Iterator rit = sheet.rowIterator(); rit.hasNext();) {
HSSFRow r = (HSSFRow)rit.next();
assertEquals("SUM(12.25,12.25)/100", formatter.formatCellValue(cell));
// now with a formula evaluator
- HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb.getSheetAt(0), wb);
+ HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb);
log(formatter.formatCellValue(cell, evaluator) + "\t\t\t (with evaluator)");
assertEquals("24.50%", formatter.formatCellValue(cell,evaluator));
}
Iterator it = row.cellIterator();
Format defaultFormat = new DecimalFormat("Balance $#,#00.00 USD;Balance -$#,#00.00 USD");
formatter.setDefaultNumberFormat(defaultFormat);
- double value = 10d;
+
log("\n==== DEFAULT NUMBER FORMAT ====");
while (it.hasNext()) {
HSSFCell cell = (HSSFCell) it.next();
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("testNames.xls");
HSSFSheet sheet = wb.getSheetAt(0);
HSSFCell cell = sheet.getRow(8).getCell(0);
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
CellValue cv = fe.evaluate(cell);
assertEquals(HSSFCell.CELL_TYPE_NUMERIC, cv.getCellType());
assertEquals(3.72, cv.getNumberValue(), 0.0);
setValue(sheet, 3, 6, 100.0);
- HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(sheet, wb);
+ HSSFFormulaEvaluator fe = new HSSFFormulaEvaluator(wb);
assertEquals(26.0, fe.evaluate(cell0).getNumberValue(), 0.0);
assertEquals(56.0, fe.evaluate(cell1).getNumberValue(), 0.0);
}