diff --git a/src/java/org/apache/poi/ss/formula/ConditionalFormattingEvaluator.java b/src/java/org/apache/poi/ss/formula/ConditionalFormattingEvaluator.java index 21508caaba..fcc35c8f15 100644 --- a/src/java/org/apache/poi/ss/formula/ConditionalFormattingEvaluator.java +++ b/src/java/org/apache/poi/ss/formula/ConditionalFormattingEvaluator.java @@ -150,21 +150,39 @@ public class ConditionalFormattingEvaluator { * or null if none apply */ public List getConditionalFormattingForCell(final CellReference cellRef) { - String sheetName = cellRef.getSheetName(); - Sheet sheet = null; - if (sheetName == null) { - sheet = workbook.getSheetAt(workbook.getActiveSheetIndex()); - } else { - sheet = workbook.getSheet(sheetName); + List rules = values.get(cellRef); + + if (rules == null) { + // compute and cache them + rules = new ArrayList(); + + Sheet sheet = null; + if (cellRef.getSheetName() != null) sheet = workbook.getSheet(cellRef.getSheetName()); + else sheet = workbook.getSheetAt(workbook.getActiveSheetIndex()); + + /* + * Per Excel help: + * https://support.office.com/en-us/article/Manage-conditional-formatting-rule-precedence-e09711a3-48df-4bcb-b82c-9d8b8b22463d#__toc269129417 + * stopIfTrue is true for all rules from HSSF files, and an explicit value for XSSF files. + * thus the explicit ordering of the rule lists in #getFormattingRulesForSheet(Sheet) + */ + boolean stopIfTrue = false; + for (EvaluationConditionalFormatRule rule : getRules(sheet)) { + + if (stopIfTrue) { + continue; // a previous rule matched and wants no more evaluations + } + + if (rule.matches(cellRef)) { + rules.add(rule); + stopIfTrue = rule.getRule().getStopIfTrue(); + } + } + Collections.sort(rules); + values.put(cellRef, rules); } - final Cell cell = SheetUtil.getCell(sheet, cellRef.getRow(), cellRef.getCol()); - - if (cell == null) { - return Collections.emptyList(); - } - - return getConditionalFormattingForCell(cell, cellRef); + return Collections.unmodifiableList(rules); } /** @@ -185,45 +203,7 @@ public class ConditionalFormattingEvaluator { * or null if none apply */ public List getConditionalFormattingForCell(Cell cell) { - return getConditionalFormattingForCell(cell, getRef(cell)); - } - - /** - * We need both, and can derive one from the other, but this is to avoid duplicate work - * - * @param cell - * @param ref - * @return unmodifiable list of matching rules - */ - private List getConditionalFormattingForCell(Cell cell, CellReference ref) { - List rules = values.get(ref); - - if (rules == null) { - // compute and cache them - rules = new ArrayList(); - /* - * Per Excel help: - * https://support.office.com/en-us/article/Manage-conditional-formatting-rule-precedence-e09711a3-48df-4bcb-b82c-9d8b8b22463d#__toc269129417 - * stopIfTrue is true for all rules from HSSF files, and an explicit value for XSSF files. - * thus the explicit ordering of the rule lists in #getFormattingRulesForSheet(Sheet) - */ - boolean stopIfTrue = false; - for (EvaluationConditionalFormatRule rule : getRules(cell.getSheet())) { - - if (stopIfTrue) { - continue; // a previous rule matched and wants no more evaluations - } - - if (rule.matches(cell)) { - rules.add(rule); - stopIfTrue = rule.getRule().getStopIfTrue(); - } - } - Collections.sort(rules); - values.put(ref, rules); - } - - return Collections.unmodifiableList(rules); + return getConditionalFormattingForCell(getRef(cell)); } public static CellReference getRef(Cell cell) { diff --git a/src/java/org/apache/poi/ss/formula/EvaluationConditionalFormatRule.java b/src/java/org/apache/poi/ss/formula/EvaluationConditionalFormatRule.java index 48b7243e96..56c19472fc 100644 --- a/src/java/org/apache/poi/ss/formula/EvaluationConditionalFormatRule.java +++ b/src/java/org/apache/poi/ss/formula/EvaluationConditionalFormatRule.java @@ -45,6 +45,7 @@ import org.apache.poi.ss.usermodel.ExcelNumberFormat; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellReference; /** * Abstracted and cached version of a Conditional Format rule for use with a @@ -262,14 +263,14 @@ public class EvaluationConditionalFormatRule implements Comparable(allValues.subList(0, limit)); } - }).contains(cv10); + }).contains(cv); case UNIQUE_VALUES: // Per Excel help, "duplicate" means matching value AND format // https://support.office.com/en-us/article/Filter-for-unique-values-or-remove-duplicate-values-ccf664b0-81d6-449b-bbe1-8daaec1e83c2 @@ -455,7 +465,7 @@ public class EvaluationConditionalFormatRule implements Comparable 0; } catch (Exception e) { @@ -575,7 +584,7 @@ public class EvaluationConditionalFormatRule implements Comparable getRulesFor(int row, int col) { ref = new CellReference(sheet.getSheetName(), row, col, false, false); diff --git a/test-data/spreadsheet/conditional_formatting_with_formula_on_second_sheet.xlsx b/test-data/spreadsheet/conditional_formatting_with_formula_on_second_sheet.xlsx new file mode 100644 index 0000000000..c9a2c8660e Binary files /dev/null and b/test-data/spreadsheet/conditional_formatting_with_formula_on_second_sheet.xlsx differ