📄 hssfformulaevaluator.java
字号:
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 * 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: * <pre> * int evaluatedCellType = evaluator.evaluateInCell(cell).getCellType(); * </pre> * 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(HSSFCell)} * @param cell */ 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.setCellType(HSSFCell.CELL_TYPE_ERROR); cell.setCellValue(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; } /** * Returns a CellValue wrapper around the supplied ValueEval instance. * @param eval */ protected 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 { retval = new CellValue(HSSFCell.CELL_TYPE_ERROR); } } return retval; } /** * 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.) * * @param srcCell * @param srcRow * @param sheet * @param workbook */ protected static ValueEval internalEvaluate(HSSFCell srcCell, HSSFRow srcRow, HSSFSheet sheet, HSSFWorkbook workbook) { int srcRowNum = srcRow.getRowNum(); short srcColNum = srcCell.getCellNum(); FormulaParser parser = new FormulaParser(srcCell.getCellFormula(), workbook.getWorkbook()); parser.parse(); Ptg[] ptgs = parser.getRPNPtg(); // -- parsing over -- Stack stack = new Stack(); for (int i = 0, iSize = ptgs.length; i < iSize; i++) { // since we dont know how to handle these yet :( if (ptgs[i] instanceof ControlPtg) { continue; } if (ptgs[i] instanceof MemErrPtg) { continue; } if (ptgs[i] instanceof MissingArgPtg) { continue; } if (ptgs[i] instanceof NamePtg) { continue; } if (ptgs[i] instanceof NameXPtg) { continue; } if (ptgs[i] instanceof UnknownPtg) { continue; } if (ptgs[i] instanceof OperationPtg) { OperationPtg optg = (OperationPtg) ptgs[i]; // parens can be ignored since we have RPN tokens if (optg instanceof ParenthesisPtg) { continue; } if (optg instanceof AttrPtg) { continue; } if (optg instanceof UnionPtg) { continue; } OperationEval operation = (OperationEval) getOperationEvalForPtg(optg); int numops = operation.getNumberOfOperands(); Eval[] ops = new Eval[numops]; // storing the ops in reverse order since they are popping for (int j = numops - 1; j >= 0; j--) { Eval p = (Eval) stack.pop(); ops[j] = p; } Eval opresult = operation.evaluate(ops, srcRowNum, srcColNum); stack.push(opresult); } else if (ptgs[i] instanceof ReferencePtg) { ReferencePtg ptg = (ReferencePtg) ptgs[i]; short colnum = ptg.getColumn(); short rownum = ptg.getRow(); HSSFRow row = sheet.getRow(rownum); HSSFCell cell = (row != null) ? row.getCell(colnum) : null; pushRef2DEval(ptg, stack, cell, row, sheet, workbook); } else if (ptgs[i] instanceof Ref3DPtg) { Ref3DPtg ptg = (Ref3DPtg) ptgs[i]; short colnum = ptg.getColumn(); short rownum = ptg.getRow(); Workbook wb = workbook.getWorkbook(); HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(ptg.getExternSheetIndex())); HSSFRow row = xsheet.getRow(rownum); HSSFCell cell = (row != null) ? row.getCell(colnum) : null; pushRef3DEval(ptg, stack, cell, row, xsheet, workbook); } else if (ptgs[i] instanceof AreaPtg) { AreaPtg ap = (AreaPtg) ptgs[i]; short row0 = ap.getFirstRow(); short col0 = ap.getFirstColumn(); short row1 = ap.getLastRow(); short col1 = ap.getLastColumn(); ValueEval[] values = new ValueEval[(row1 - row0 + 1) * (col1 - col0 + 1)]; for (short x = row0; sheet != null && x < row1 + 1; x++) { HSSFRow row = sheet.getRow(x); for (short y = col0; row != null && y < col1 + 1; y++) { values[(x - row0) * (col1 - col0 + 1) + (y - col0)] = getEvalForCell(row.getCell(y), row, sheet, workbook); } } AreaEval ae = new Area2DEval(ap, values); stack.push(ae); } else if (ptgs[i] instanceof Area3DPtg) { Area3DPtg a3dp = (Area3DPtg) ptgs[i]; short row0 = a3dp.getFirstRow(); short col0 = a3dp.getFirstColumn(); short row1 = a3dp.getLastRow(); short col1 = a3dp.getLastColumn(); Workbook wb = workbook.getWorkbook(); HSSFSheet xsheet = workbook.getSheetAt(wb.getSheetIndexFromExternSheetIndex(a3dp.getExternSheetIndex())); ValueEval[] values = new ValueEval[(row1 - row0 + 1) * (col1 - col0 + 1)]; for (short x = row0; xsheet != null && x < row1 + 1; x++) { HSSFRow row = xsheet.getRow(x); for (short y = col0; row != null && y < col1 + 1; y++) { values[(x - row0) * (col1 - col0 + 1) + (y - col0)] = getEvalForCell(row.getCell(y), row, xsheet, workbook); } } AreaEval ae = new Area3DEval(a3dp, values); stack.push(ae); } else { Eval ptgEval = getEvalForPtg(ptgs[i]); stack.push(ptgEval); } } ValueEval value = ((ValueEval) stack.pop()); if (value instanceof RefEval) { RefEval rv = (RefEval) value; value = rv.getInnerValueEval(); } else if (value instanceof AreaEval) { AreaEval ae = (AreaEval) value; if (ae.isRow()) value = ae.getValueAt(ae.getFirstRow(), srcColNum); else if (ae.isColumn()) value = ae.getValueAt(srcRowNum, ae.getFirstColumn()); else value = ErrorEval.VALUE_INVALID; } return value; } /** * returns the OperationEval concrete impl instance corresponding * to the suplied operationPtg * @param ptg */ protected static Eval getOperationEvalForPtg(OperationPtg ptg) { Eval retval = null; Class clazz = (Class) OPERATION_EVALS_MAP.get(ptg.getClass()); try { Constructor constructor = clazz.getConstructor(OPERATION_CONSTRUCTOR_CLASS_ARRAY); retval = (OperationEval) 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 <br/>special Note: OperationPtg subtypes cannot be * passed here! * * @param ptg */ 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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -