package org.apache.poi.hssf.model;
import org.apache.poi.ss.formula.ptg.Ptg;
+import org.apache.poi.util.Internal;
import org.apache.poi.hssf.usermodel.HSSFEvaluationWorkbook;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.FormulaParseException;
/**
* HSSF wrapper for the {@link FormulaParser} and {@link FormulaRenderer}
*/
+@Internal
public final class HSSFFormulaParser {
private static FormulaParsingWorkbook createParsingWorkbook(HSSFWorkbook book) {
}
/**
- * Convenience method for parsing cell formulas. see {@link #parse(String, HSSFWorkbook, int, int)}
+ * Convenience method for parsing cell formulas. see {@link #parse(String, HSSFWorkbook, FormulaType, int)}
+ * @param formula The formula to parse, excluding the leading equals sign
+ * @param workbook The parent workbook
+ * @return the parsed formula tokens
+ * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid
*/
public static Ptg[] parse(String formula, HSSFWorkbook workbook) throws FormulaParseException {
return parse(formula, workbook, FormulaType.CELL);
}
/**
+ * @param formula The formula to parse, excluding the leading equals sign
+ * @param workbook The parent workbook
* @param formulaType a constant from {@link FormulaType}
* @return the parsed formula tokens
* @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid
+ *
+ * @deprecated POI 3.15 beta 3. Use {@link #parse(String, HSSFWorkbook, FormulaType)} instead.
*/
public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType) throws FormulaParseException {
+ return parse(formula, workbook, FormulaType.forInt(formulaType));
+ }
+ /**
+ * @param formula The formula to parse, excluding the leading equals sign
+ * @param workbook The parent workbook
+ * @param formulaType The type of formula
+ * @return The parsed formula tokens
+ * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid
+ */
+ public static Ptg[] parse(String formula, HSSFWorkbook workbook, FormulaType formulaType) throws FormulaParseException {
return parse(formula, workbook, formulaType, -1);
}
*
* @return the parsed formula tokens
* @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid
+ * @deprecated POI 3.15 beta 3. Use {@link #parse(String, HSSFWorkbook, FormulaType, int)} instead.
*/
public static Ptg[] parse(String formula, HSSFWorkbook workbook, int formulaType, int sheetIndex) throws FormulaParseException {
+ return parse(formula, workbook, FormulaType.forInt(formulaType), sheetIndex);
+ }
+ /**
+ * @param formula The formula to parse
+ * @param workbook The parent workbook
+ * @param formulaType The type of formula
+ * @param sheetIndex The 0-based index of the sheet this formula belongs to.
+ * The sheet index is required to resolve sheet-level names. <code>-1</code> means that
+ * the scope of the name will be ignored and the parser will match named ranges only by name
+ *
+ * @return the parsed formula tokens
+ * @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid
+ */
+ public static Ptg[] parse(String formula, HSSFWorkbook workbook, FormulaType formulaType, int sheetIndex) throws FormulaParseException {
return FormulaParser.parse(formula, createParsingWorkbook(workbook), formulaType, sheetIndex);
}
*/
public class HSSFFormulaEvaluator implements FormulaEvaluator, WorkbookEvaluatorProvider {
- private WorkbookEvaluator _bookEvaluator;
- private HSSFWorkbook _book;
+ private final WorkbookEvaluator _bookEvaluator;
+ private final HSSFWorkbook _book;
public HSSFFormulaEvaluator(HSSFWorkbook workbook) {
this(workbook, null);
- this._book = workbook;
}
/**
+ * @param workbook The workbook to perform the formula evaluations in
* @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
* for the (conservative) assumption that any cell may have its definition changed after
* evaluation begins.
}
/**
+ * @param workbook The workbook to perform the formula evaluations in
+ * @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
+ * for the (conservative) assumption that any cell may have its definition changed after
+ * evaluation begins.
* @param udfFinder pass <code>null</code> for default (AnalysisToolPak only)
*/
private HSSFFormulaEvaluator(HSSFWorkbook workbook, IStabilityClassifier stabilityClassifier, UDFFinder udfFinder) {
+ _book = workbook;
_bookEvaluator = new WorkbookEvaluator(HSSFEvaluationWorkbook.create(workbook), stabilityClassifier, udfFinder);
}
/**
+ * @param workbook The workbook to perform the formula evaluations in
* @param stabilityClassifier used to optimise caching performance. Pass <code>null</code>
* for the (conservative) assumption that any cell may have its definition changed after
* evaluation begins.
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.util.CellReference.NameType;
+import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
* For POI internal use only
* <p/>
*/
+@Internal
public final class FormulaParser {
private final static POILogger log = POILogFactory.getLogger(FormulaParser.class);
private final String _formulaString;
private char look;
/**
- * Tracks whether the run of whitespace preceeding "look" could be an
+ * Tracks whether the run of whitespace preceding "look" could be an
* intersection operator. See GetChar.
*/
private boolean _inIntersection = false;
* parse results.
* This class is recommended only for single threaded use.
*
- * If you only have a usermodel.HSSFWorkbook, and not a
- * model.Workbook, then use the convenience method on
- * usermodel.HSSFFormulaEvaluator
+ * If you have a {@link org.apache.poi.hssf.usermodel.HSSFWorkbook}, and not a
+ * {@link org.apache.poi.hssf.model.Workbook}, then use the convenience method on
+ * {@link org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator}
*/
- private FormulaParser(String formula, FormulaParsingWorkbook book, int sheetIndex, int rowIndex){
+ private FormulaParser(String formula, FormulaParsingWorkbook book, int sheetIndex, int rowIndex) {
_formulaString = formula;
_pointer=0;
_book = book;
*
* @param formula the formula to parse
* @param workbook the parent workbook
- * @param formulaType the type of the formula, see {@link FormulaType}
+ * @param formulaType the type of the formula
* @param sheetIndex the 0-based index of the sheet this formula belongs to.
* The sheet index is required to resolve sheet-level names. <code>-1</code> means that
* the scope of the name will be ignored and the parser will match names only by name
* @return array of parsed tokens
* @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid
*/
- public static Ptg[] parse(String formula, FormulaParsingWorkbook workbook, int formulaType, int sheetIndex, int rowIndex) {
+ public static Ptg[] parse(String formula, FormulaParsingWorkbook workbook, FormulaType formulaType, int sheetIndex, int rowIndex) {
FormulaParser fp = new FormulaParser(formula, workbook, sheetIndex, rowIndex);
fp.parse();
return fp.getRPNPtg(formulaType);
*
* @param formula the formula to parse
* @param workbook the parent workbook
- * @param formulaType the type of the formula, see {@link FormulaType}
+ * @param formulaType the type of the formula
* @param sheetIndex the 0-based index of the sheet this formula belongs to.
* The sheet index is required to resolve sheet-level names. <code>-1</code> means that
* the scope of the name will be ignored and the parser will match names only by name
* @return array of parsed tokens
* @throws FormulaParseException if the formula has incorrect syntax or is otherwise invalid
*/
- public static Ptg[] parse(String formula, FormulaParsingWorkbook workbook, int formulaType, int sheetIndex) {
+ public static Ptg[] parse(String formula, FormulaParsingWorkbook workbook, FormulaType formulaType, int sheetIndex) {
return parse(formula, workbook, formulaType, sheetIndex, -1);
}
return null;
}
} else if (hasLetters) {
- if (!CellReference.isColumnWithnRange(rep.replace("$", ""), _ssVersion)) {
+ if (!CellReference.isColumnWithinRange(rep.replace("$", ""), _ssVersion)) {
return null;
}
} else if (hasDigits) {
}
}
- private Ptg[] getRPNPtg(int formulaType) {
+ private Ptg[] getRPNPtg(FormulaType formulaType) {
OperandClassTransformer oct = new OperandClassTransformer(formulaType);
// RVA is for 'operand class': 'reference', 'value', 'array'
oct.transformFormula(_rootNode);
package org.apache.poi.ss.formula;
+import org.apache.poi.util.Internal;
+
/**
- * Enumeration of various formula types.<br/>
- *
- * For POI internal use only
- *
- * @author Josh Micich
+ * Enumeration of various formula types.
+ *
+ * See Sections 3 and 4.8 of https://www.openoffice.org/sc/excelfileformat.pdf
*/
-public final class FormulaType {
- private FormulaType() {
- // no instances of this class
- }
- public static final int CELL = 0;
- public static final int SHARED = 1;
- public static final int ARRAY =2;
- public static final int CONDFORMAT = 3;
- public static final int NAMEDRANGE = 4;
- // this constant is currently very specific. The exact differences from general data
- // validation formulas or conditional format formulas is not known yet
- public static final int DATAVALIDATION_LIST = 5;
-
+@Internal
+public enum FormulaType {
+ /** Regular cell formula */
+ CELL(0),
+
+ /**
+ * A Shared Formula ("{=SUM(A1:E1*{1,2,3,4,5}}")
+ *
+ * Similar to an array formula, but stored in a SHAREDFMLA instead of ARRAY record as a file size optimization.
+ * See Section 4.8 of https://www.openoffice.org/sc/excelfileformat.pdf
+ */
+ SHARED(1),
+
+ /**
+ * An Array formula ("{=SUM(A1:E1*{1,2,3,4,5}}")
+ * https://support.office.com/en-us/article/Guidelines-and-examples-of-array-formulas-7D94A64E-3FF3-4686-9372-ECFD5CAA57C7
+ */
+ ARRAY(2),
+
+ /** Conditional formatting */
+ CONDFORMAT(3),
+
+ /** Named range */
+ NAMEDRANGE(4),
+
+ /**
+ * This constant is currently very specific. The exact differences from general data
+ * validation formulas or conditional format formulas is not known yet
+ */
+ DATAVALIDATION_LIST(5);
+
+ /** @deprecated POI 3.15 beta 3. */
+ private final int code;
+ /** @deprecated POI 3.15 beta 3.
+ * Formula type code doesn't mean anything. Only in this class for transitioning from a class with int constants to a true enum.
+ * Remove hard-coded numbers from the enums above. */
+ private FormulaType(int code) {
+ this.code = code;
+ }
+
+ /** @deprecated POI 3.15 beta 3. Used to transition code from <code>int</code>s to <code>FormulaType</code>s. */
+ public static FormulaType forInt(int code) {
+ for (FormulaType type : values()) {
+ if (type.code == code) {
+ return type;
+ }
+ }
+ throw new IllegalArgumentException("Invalid FormulaType code: " + code);
+ }
}
*/
final class OperandClassTransformer {
- private final int _formulaType;
+ private final FormulaType _formulaType;
+ /** @deprecated POI 3.15 beta 3. */
public OperandClassTransformer(int formulaType) {
+ this(FormulaType.forInt(formulaType));
+ }
+ public OperandClassTransformer(FormulaType formulaType) {
_formulaType = formulaType;
}
public void transformFormula(ParseNode rootNode) {
byte rootNodeOperandClass;
switch (_formulaType) {
- case FormulaType.CELL:
+ case CELL:
rootNodeOperandClass = Ptg.CLASS_VALUE;
break;
- case FormulaType.ARRAY:
+ case ARRAY:
rootNodeOperandClass = Ptg.CLASS_ARRAY;
break;
- case FormulaType.NAMEDRANGE:
- case FormulaType.DATAVALIDATION_LIST:
+ case NAMEDRANGE:
+ case DATAVALIDATION_LIST:
rootNodeOperandClass = Ptg.CLASS_REF;
break;
default:
cellFormula.setRef(range.formatAsString());
}
- @SuppressWarnings("resource")
- private void setFormula(String formula, int formulaType) {
+ private void setFormula(String formula, FormulaType formulaType) {
XSSFWorkbook wb = _row.getSheet().getWorkbook();
if (formula == null) {
wb.onDeleteFormula(this);