| Method from org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator Detail: |
public HSSFFormulaEvaluator.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;
case HSSFCell.CELL_TYPE_BOOLEAN:
retval = new CellValue(HSSFCell.CELL_TYPE_BOOLEAN);
retval.setBooleanValue(cell.getBooleanCellValue());
break;
case HSSFCell.CELL_TYPE_ERROR:
retval = new CellValue(HSSFCell.CELL_TYPE_ERROR);
retval.setErrorValue(cell.getErrorCellValue());
break;
case HSSFCell.CELL_TYPE_FORMULA:
retval = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook));
break;
case HSSFCell.CELL_TYPE_NUMERIC:
retval = new CellValue(HSSFCell.CELL_TYPE_NUMERIC);
retval.setNumberValue(cell.getNumericCellValue());
break;
case HSSFCell.CELL_TYPE_STRING:
retval = new CellValue(HSSFCell.CELL_TYPE_STRING);
retval.setRichTextStringValue(cell.getRichStringCellValue());
break;
}
}
return retval;
}
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. |
public static void evaluateAllFormulaCells(HSSFWorkbook 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();
evaluator.setCurrentRow(r);
for (Iterator cit = r.cellIterator(); cit.hasNext();) {
HSSFCell c = (HSSFCell)cit.next();
if (c.getCellType() == HSSFCell.CELL_TYPE_FORMULA)
evaluator.evaluateFormulaCell(c);
}
}
}
}
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 AreaEval evaluateArea3dPtg(HSSFWorkbook workbook,
Area3DPtg a3dp) {
int row0 = a3dp.getFirstRow();
int col0 = a3dp.getFirstColumn();
int row1 = a3dp.getLastRow();
int col1 = a3dp.getLastColumn();
Workbook wb = workbook.getWorkbook();
HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(a3dp.getExternSheetIndex()));
// If the last row is -1, then the
// reference is for the rest of the column
// (eg C:C)
// TODO: Handle whole column ranges properly
if(row1 == -1 && row0 >= 0) {
row1 = (short)xsheet.getLastRowNum();
}
ValueEval[] values = evalArea(workbook, xsheet, row0, col0, row1, col1);
return new Area3DEval(a3dp, values);
}
|
public static AreaEval evaluateAreaPtg(HSSFSheet sheet,
HSSFWorkbook workbook,
AreaPtg ap) {
int row0 = ap.getFirstRow();
int col0 = ap.getFirstColumn();
int row1 = ap.getLastRow();
int col1 = ap.getLastColumn();
// If the last row is -1, then the
// reference is for the rest of the column
// (eg C:C)
// TODO: Handle whole column ranges properly
if(row1 == -1 && row0 >= 0) {
row1 = (short)sheet.getLastRowNum();
}
ValueEval[] values = evalArea(workbook, sheet, row0, col0, row1, col1);
return new Area2DEval(ap, values);
}
|
public int evaluateFormulaCell(HSSFCell cell) {
if (cell != null) {
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_FORMULA:
CellValue cv = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook));
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();
}
}
return -1;
}
If cell contains formula, it evaluates the formula,
and saves the result of the formula. The cell
remains as a formula cell.
Else if cell does not contain formula, this method leaves
the cell unchanged.
Note that the type of the formula result is returned,
so you know what kind of value 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 #evaluateInCell(HSSFCell) |
public HSSFCell evaluateInCell(HSSFCell cell) {
if (cell != null) {
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_FORMULA:
CellValue cv = getCellValueForEval(internalEvaluate(cell, row, sheet, workbook));
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;
}
}
}
return cell;
}
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 #evaluateFormulaCell(HSSFCell) |
protected static HSSFFormulaEvaluator.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);
}
}
return retval;
}
Returns a CellValue wrapper around the supplied ValueEval instance. |
protected static ValueEval getEvalForCell(HSSFCell cell,
HSSFRow row,
HSSFSheet sheet,
HSSFWorkbook workbook) {
if (cell == null) {
return BlankEval.INSTANCE;
}
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_NUMERIC:
return new NumberEval(cell.getNumericCellValue());
case HSSFCell.CELL_TYPE_STRING:
return new StringEval(cell.getRichStringCellValue().getString());
case HSSFCell.CELL_TYPE_FORMULA:
return internalEvaluate(cell, row, sheet, workbook);
case HSSFCell.CELL_TYPE_BOOLEAN:
return BoolEval.valueOf(cell.getBooleanCellValue());
case HSSFCell.CELL_TYPE_BLANK:
return BlankEval.INSTANCE;
case HSSFCell.CELL_TYPE_ERROR:
return ErrorEval.valueOf(cell.getErrorCellValue());
}
throw new RuntimeException("Unexpected cell type (" + cell.getCellType() + ")");
}
Given a cell, find its type and from that create an appropriate ValueEval
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. |
protected static Eval getEvalForPtg(Ptg ptg) {
Eval retval = null;
Class clazz = (Class) VALUE_EVALS_MAP.get(ptg.getClass());
try {
if (ptg instanceof Area3DPtg) {
Constructor constructor = clazz.getConstructor(AREA3D_CONSTRUCTOR_CLASS_ARRAY);
retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
}
else if (ptg instanceof AreaPtg) {
Constructor constructor = clazz.getConstructor(AREA3D_CONSTRUCTOR_CLASS_ARRAY);
retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
}
else if (ptg instanceof RefPtg) {
Constructor constructor = clazz.getConstructor(REFERENCE_CONSTRUCTOR_CLASS_ARRAY);
retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
}
else if (ptg instanceof Ref3DPtg) {
Constructor constructor = clazz.getConstructor(REF3D_CONSTRUCTOR_CLASS_ARRAY);
retval = (OperationEval) constructor.newInstance(new Ptg[] { ptg });
}
else {
if (ptg instanceof IntPtg || ptg instanceof NumberPtg || ptg instanceof StringPtg
|| ptg instanceof BoolPtg) {
Constructor constructor = clazz.getConstructor(VALUE_CONTRUCTOR_CLASS_ARRAY);
retval = (ValueEval) constructor.newInstance(new Ptg[] { ptg });
}
}
}
catch (Exception e) {
throw new RuntimeException("Fatal Error: ", e);
}
return retval;
}
returns an appropriate Eval impl instance for the Ptg. The Ptg must be
one of: Area3DPtg, AreaPtg, ReferencePtg, Ref3DPtg, IntPtg, NumberPtg,
StringPtg, BoolPtg special Note: OperationPtg subtypes cannot be
passed here! |
public static FormulaParser getUnderlyingParser(HSSFWorkbook workbook,
String formula) {
return new FormulaParser(formula, workbook);
}
Returns an underlying FormulaParser, for the specified
Formula String and HSSFWorkbook.
This will allow you to generate the Ptgs yourself, if
your needs are more complex than just having the
formula evaluated. |
void inspectPtgs(String formula) {
FormulaParser fp = new FormulaParser(formula, workbook);
fp.parse();
Ptg[] ptgs = fp.getRPNPtg();
System.out.println("< ptg-group >");
for (int i = 0, iSize = ptgs.length; i < iSize; i++) {
System.out.println("< ptg >");
System.out.println(ptgs[i]);
if (ptgs[i] instanceof OperationPtg) {
System.out.println("numoperands: " + ((OperationPtg) ptgs[i]).getNumberOfOperands());
}
System.out.println("< /ptg >");
}
System.out.println("< /ptg-group >");
}
|
public void setCurrentRow(HSSFRow row) {
this.row = row;
}
|