diff --git a/src/documentation/content/xdocs/changes.xml b/src/documentation/content/xdocs/changes.xml
index 42497beb12..4b1b5566d0 100644
--- a/src/documentation/content/xdocs/changes.xml
+++ b/src/documentation/content/xdocs/changes.xml
@@ -37,6 +37,7 @@
Both HSSFWorkbook and XSSFWorkbook are supported, so you can evaluate formulas on both .xls and .xlsx files.
Note that user-defined functions are not supported, and is not likely to done @@ -66,38 +64,37 @@ without affecting the cell
+Thus using the retrieved value (of type FormulaEvaluator.CellValue - a nested class) returned by FormulaEvaluator is similar to using a Cell object @@ -117,39 +114,38 @@ switch (cellValue.getCellType()) { formula remains in the cell, just with a new value
The return of the function is the type of the formula result, such as Cell.CELL_TYPE_BOOLEAN
-+ * Syntax: COUNTIF ( range, criteria ) *
range | is the range of cells to be counted based on the criteria |
---|---|
criteria | is used to determine which cells to count |
* Syntax:
- * ERROR.TYPE(errorValue)
* Returns a number corresponding to the error type of the supplied argument.
- * + **
errorValue | Return Value |
#NULL! | 1 |
column_num | selects column within the array or area reference. default is 1 |
---|---|
area_num | used when reference is a union of areas |
*
* Syntax :
* SUMPRODUCT ( array1[, array2[, array3[, ...]]])
@@ -49,7 +49,7 @@ import org.apache.poi.hssf.record.formula.eval.ValueEval;
* An(i,j)
* )
* )
- *
+ *
null
signifying that the cell is not present (or blank)
- * @return null
if the supplied cell is null
or blank
- */
- public CellValue evaluate(Cell cell) {
- if (cell == null) {
- return null;
- }
+ /**
+ * Should be called whenever there are major changes (e.g. moving sheets) to input cells
+ * in the evaluated workbook. If performance is not critical, a single call to this method
+ * may be used instead of many specific calls to the notify~ methods.
+ *
+ * Failure to call this method after changing cell values will cause incorrect behaviour
+ * of the evaluate~ methods of this class
+ */
+ public void clearAllCachedResultValues() {
+ _bookEvaluator.clearAllCachedResultValues();
+ }
+ /**
+ * Should be called to tell the cell value cache that the specified (value or formula) cell
+ * has changed.
+ * Failure to call this method after changing cell values will cause incorrect behaviour
+ * of the evaluate~ methods of this class
+ */
+ public void notifyUpdateCell(HSSFCell cell) {
+ _bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell(cell));
+ }
+ /**
+ * Should be called to tell the cell value cache that the specified cell has just been
+ * deleted.
+ * Failure to call this method after changing cell values will cause incorrect behaviour
+ * of the evaluate~ methods of this class
+ */
+ public void notifyDeleteCell(HSSFCell cell) {
+ _bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell(cell));
+ }
+ public void notifyDeleteCell(Cell cell) {
+ _bookEvaluator.notifyDeleteCell(new HSSFEvaluationCell((HSSFCell)cell));
+ }
- switch (cell.getCellType()) {
- case HSSFCell.CELL_TYPE_BOOLEAN:
- return CellValue.valueOf(cell.getBooleanCellValue());
- case HSSFCell.CELL_TYPE_ERROR:
- return CellValue.getError(cell.getErrorCellValue());
- case HSSFCell.CELL_TYPE_FORMULA:
- return evaluateFormulaCellValue(cell);
- case HSSFCell.CELL_TYPE_NUMERIC:
- return new CellValue(cell.getNumericCellValue());
- case HSSFCell.CELL_TYPE_STRING:
- return new CellValue(cell.getRichStringCellValue().getString());
- case HSSFCell.CELL_TYPE_BLANK:
- return null;
- }
- throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")");
- }
+ /**
+ * Should be called to tell the cell value cache that the specified (value or formula) cell
+ * has changed.
+ * Failure to call this method after changing cell values will cause incorrect behaviour
+ * of the evaluate~ methods of this class
+ */
+ public void notifySetFormula(Cell cell) {
+ _bookEvaluator.notifyUpdateCell(new HSSFEvaluationCell((HSSFCell)cell));
+ }
+
+ /**
+ * If cell contains a formula, the formula is evaluated and returned,
+ * else the CellValue simply copies the appropriate cell value from
+ * the cell and also its cell type. This method should be preferred over
+ * evaluateInCell() when the call should not modify the contents of the
+ * original cell.
+ *
+ * @param cell may be null
signifying that the cell is not present (or blank)
+ * @return null
if the supplied cell is null
or blank
+ */
+ public CellValue evaluate(Cell cell) {
+ if (cell == null) {
+ return null;
+ }
+
+ switch (cell.getCellType()) {
+ case HSSFCell.CELL_TYPE_BOOLEAN:
+ return CellValue.valueOf(cell.getBooleanCellValue());
+ case HSSFCell.CELL_TYPE_ERROR:
+ return CellValue.getError(cell.getErrorCellValue());
+ case HSSFCell.CELL_TYPE_FORMULA:
+ return evaluateFormulaCellValue(cell);
+ case HSSFCell.CELL_TYPE_NUMERIC:
+ return new CellValue(cell.getNumericCellValue());
+ case HSSFCell.CELL_TYPE_STRING:
+ return new CellValue(cell.getRichStringCellValue().getString());
+ case HSSFCell.CELL_TYPE_BLANK:
+ return null;
+ }
+ throw new IllegalStateException("Bad cell type (" + cell.getCellType() + ")");
+ }
- /**
- * If cell contains formula, it evaluates the formula, and saves the result of the formula. The
- * cell remains as a formula cell. If the cell does not contain formula, this method returns -1
- * and leaves the cell unchanged.
- *
- * Note that the type of the formula result is returned, so you know what kind of
- * cached formula result is also stored with the formula.
- * - * int evaluatedCellType = evaluator.evaluateFormulaCell(cell); - *- * Be aware that your cell will hold both the formula, and the result. If you want the cell - * replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)} - * @param cell The cell to evaluate - * @return -1 for non-formula cells, or the type of the formula result - */ - public int evaluateFormulaCell(Cell cell) { - if (cell == null || cell.getCellType() != HSSFCell.CELL_TYPE_FORMULA) { - return -1; - } - CellValue cv = evaluateFormulaCellValue(cell); - // cell remains a formula cell, but the cached value is changed - setCellValue(cell, cv); - return cv.getCellType(); - } + /** + * If cell contains formula, it evaluates the formula, and saves the result of the formula. The + * cell remains as a formula cell. If the cell does not contain formula, this method returns -1 + * and leaves the cell unchanged. + * + * Note that the type of the formula result is returned, so you know what kind of + * cached formula result is also stored with the formula. + *
+ * int evaluatedCellType = evaluator.evaluateFormulaCell(cell); + *+ * Be aware that your cell will hold both the formula, and the result. If you want the cell + * replaced with the result of the formula, use {@link #evaluateInCell(org.apache.poi.ss.usermodel.Cell)} + * @param cell The cell to evaluate + * @return -1 for non-formula cells, or the type of the formula result + */ + public int evaluateFormulaCell(Cell cell) { + if (cell == null || cell.getCellType() != HSSFCell.CELL_TYPE_FORMULA) { + return -1; + } + CellValue cv = evaluateFormulaCellValue(cell); + // cell remains a formula cell, but the cached value is changed + setCellValue(cell, cv); + return cv.getCellType(); + } - /** - * If cell contains formula, it evaluates the formula, and - * puts the formula result back into the cell, in place - * of the old formula. - * Else if cell does not contain formula, this method leaves - * the cell unchanged. - * Note that the same instance of HSSFCell is returned to - * allow chained calls like: - *
- * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType(); - *- * Be aware that your cell value will be changed to hold the - * result of the formula. If you simply want the formula - * value computed for you, use {@link #evaluateFormulaCell(org.apache.poi.ss.usermodel.Cell)}} - * @param cell - */ - public HSSFCell evaluateInCell(Cell cell) { - if (cell == null) { - return null; - } - HSSFCell result = (HSSFCell) cell; - 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 result; - } - private static void setCellType(Cell 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 + ")"); - } + /** + * If cell contains formula, it evaluates the formula, and + * puts the formula result back into the cell, in place + * of the old formula. + * Else if cell does not contain formula, this method leaves + * the cell unchanged. + * Note that the same instance of HSSFCell is returned to + * allow chained calls like: + *
+ * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType(); + *+ * Be aware that your cell value will be changed to hold the + * result of the formula. If you simply want the formula + * value computed for you, use {@link #evaluateFormulaCell(org.apache.poi.ss.usermodel.Cell)}} + * @param cell + */ + public HSSFCell evaluateInCell(Cell cell) { + if (cell == null) { + return null; + } + HSSFCell result = (HSSFCell) cell; + 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 result; + } + private static void setCellType(Cell 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(Cell 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(new HSSFRichTextString(cv.getStringValue())); - 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 + ")"); - } - } + private static void setCellValue(Cell 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(new HSSFRichTextString(cv.getStringValue())); + 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 - * workbook. - * For cells that contain formulas, their formulas are - * evaluated, and the results are saved. These cells - * remain as formula cells. - * For cells that do not contain formulas, no changes - * are made. - * This is a helpful wrapper around looping over all - * cells, and calling evaluateFormulaCell on each one. - */ - public static void evaluateAllFormulaCells(HSSFWorkbook wb) { - HSSFFormulaEvaluator evaluator = new HSSFFormulaEvaluator(wb); - for(int i=0; i