Currently only implemented for XSSF, as there is no API available for HSSF conditional formatting rule number formats (if it is even in the files). git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1794084 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_17_BETA1
import org.apache.poi.ss.usermodel.ConditionFilterType; | import org.apache.poi.ss.usermodel.ConditionFilterType; | ||||
import org.apache.poi.ss.usermodel.ConditionType; | import org.apache.poi.ss.usermodel.ConditionType; | ||||
import org.apache.poi.ss.usermodel.ConditionalFormattingRule; | import org.apache.poi.ss.usermodel.ConditionalFormattingRule; | ||||
import org.apache.poi.ss.usermodel.ExcelNumberFormat; | |||||
/** | /** | ||||
* | * | ||||
} | } | ||||
return (CFRule12Record)cfRuleRecord; | return (CFRule12Record)cfRuleRecord; | ||||
} | } | ||||
/** | |||||
* Always null for HSSF records, until someone figures out where to find it | |||||
* @see org.apache.poi.ss.usermodel.ConditionalFormattingRule#getNumberFormat() | |||||
*/ | |||||
public ExcelNumberFormat getNumberFormat() { | |||||
return null; | |||||
} | |||||
private HSSFFontFormatting getFontFormatting(boolean create) { | private HSSFFontFormatting getFontFormatting(boolean create) { | ||||
FontFormatting fontFormatting = cfRuleRecord.getFontFormatting(); | FontFormatting fontFormatting = cfRuleRecord.getFontFormatting(); |
import org.apache.poi.ss.usermodel.ConditionType; | import org.apache.poi.ss.usermodel.ConditionType; | ||||
import org.apache.poi.ss.usermodel.ConditionalFormatting; | import org.apache.poi.ss.usermodel.ConditionalFormatting; | ||||
import org.apache.poi.ss.usermodel.ConditionalFormattingRule; | import org.apache.poi.ss.usermodel.ConditionalFormattingRule; | ||||
import org.apache.poi.ss.usermodel.ExcelNumberFormat; | |||||
import org.apache.poi.ss.usermodel.Row; | import org.apache.poi.ss.usermodel.Row; | ||||
import org.apache.poi.ss.usermodel.Sheet; | import org.apache.poi.ss.usermodel.Sheet; | ||||
import org.apache.poi.ss.util.CellRangeAddress; | import org.apache.poi.ss.util.CellRangeAddress; | ||||
* create whatever style objects they need, caching those at the application level. | * create whatever style objects they need, caching those at the application level. | ||||
* Thus this class only caches values needed for evaluation, not display. | * Thus this class only caches values needed for evaluation, not display. | ||||
*/ | */ | ||||
/** | |||||
* | |||||
*/ | |||||
public class EvaluationConditionalFormatRule implements Comparable<EvaluationConditionalFormatRule> { | public class EvaluationConditionalFormatRule implements Comparable<EvaluationConditionalFormatRule> { | ||||
private final WorkbookEvaluator workbookEvaluator; | private final WorkbookEvaluator workbookEvaluator; | ||||
private final String formula2; | private final String formula2; | ||||
private final OperatorEnum operator; | private final OperatorEnum operator; | ||||
private final ConditionType type; | private final ConditionType type; | ||||
// cached for performance, to avoid reading the XMLBean every time a conditinally formatted cell is rendered | |||||
private final ExcelNumberFormat numberFormat; | |||||
/** | /** | ||||
* | * | ||||
this.regions = regions; | this.regions = regions; | ||||
formula1 = rule.getFormula1(); | formula1 = rule.getFormula1(); | ||||
formula2 = rule.getFormula2(); | formula2 = rule.getFormula2(); | ||||
numberFormat = rule.getNumberFormat(); | |||||
operator = OperatorEnum.values()[rule.getComparisonOperation()]; | operator = OperatorEnum.values()[rule.getComparisonOperation()]; | ||||
type = rule.getConditionType(); | type = rule.getConditionType(); | ||||
} | } | ||||
/** | |||||
* @return sheet | |||||
*/ | |||||
public Sheet getSheet() { | public Sheet getSheet() { | ||||
return sheet; | return sheet; | ||||
} | } | ||||
return formatting; | return formatting; | ||||
} | } | ||||
/** | |||||
* @return conditional formatting index | |||||
*/ | |||||
public int getFormattingIndex() { | public int getFormattingIndex() { | ||||
return formattingIndex; | return formattingIndex; | ||||
} | } | ||||
/** | |||||
* @return Excel number format string to apply to matching cells, or null to keep the cell default | |||||
*/ | |||||
public ExcelNumberFormat getNumberFormat() { | |||||
return numberFormat; | |||||
} | |||||
/** | /** | ||||
* @return the rule | * @return the rule | ||||
*/ | */ | ||||
return rule; | return rule; | ||||
} | } | ||||
/** | |||||
* @return rule index | |||||
*/ | |||||
public int getRuleIndex() { | public int getRuleIndex() { | ||||
return ruleIndex; | return ruleIndex; | ||||
} | } |
*/ | */ | ||||
ColorScaleFormatting getColorScaleFormatting(); | ColorScaleFormatting getColorScaleFormatting(); | ||||
/** | |||||
* | |||||
* @return number format defined for this rule, or null if the cell default should be used | |||||
*/ | |||||
ExcelNumberFormat getNumberFormat(); | |||||
/** | /** | ||||
* Type of conditional formatting rule. | * Type of conditional formatting rule. | ||||
* | * |
import org.apache.poi.ss.format.CellFormat; | import org.apache.poi.ss.format.CellFormat; | ||||
import org.apache.poi.ss.format.CellFormatResult; | import org.apache.poi.ss.format.CellFormatResult; | ||||
import org.apache.poi.ss.formula.ConditionalFormattingEvaluator; | |||||
import org.apache.poi.ss.util.DateFormatConverter; | import org.apache.poi.ss.util.DateFormatConverter; | ||||
import org.apache.poi.ss.util.NumberToTextConverter; | import org.apache.poi.ss.util.NumberToTextConverter; | ||||
import org.apache.poi.util.LocaleUtil; | import org.apache.poi.util.LocaleUtil; | ||||
* @return A Format for the format String | * @return A Format for the format String | ||||
*/ | */ | ||||
private Format getFormat(Cell cell) { | private Format getFormat(Cell cell) { | ||||
if ( cell.getCellStyle() == null) { | |||||
return getFormat(cell, null); | |||||
} | |||||
private Format getFormat(Cell cell, ConditionalFormattingEvaluator cfEvaluator) { | |||||
if (cell == null) return null; | |||||
ExcelNumberFormat numFmt = ExcelNumberFormat.from(cell, cfEvaluator); | |||||
if ( numFmt == null) { | |||||
return null; | return null; | ||||
} | } | ||||
int formatIndex = cell.getCellStyle().getDataFormat(); | |||||
String formatStr = cell.getCellStyle().getDataFormatString(); | |||||
int formatIndex = numFmt.getIdx(); | |||||
String formatStr = numFmt.getFormat(); | |||||
if(formatStr == null || formatStr.trim().length() == 0) { | if(formatStr == null || formatStr.trim().length() == 0) { | ||||
return null; | return null; | ||||
} | } | ||||
* Returns the formatted value of an Excel date as a <tt>String</tt> based | * Returns the formatted value of an Excel date as a <tt>String</tt> based | ||||
* on the cell's <code>DataFormat</code>. i.e. "Thursday, January 02, 2003" | * on the cell's <code>DataFormat</code>. i.e. "Thursday, January 02, 2003" | ||||
* , "01/02/2003" , "02-Jan" , etc. | * , "01/02/2003" , "02-Jan" , etc. | ||||
* <p/> | |||||
* If any conditional format rules apply, the highest priority with a number format is used. | |||||
* If no rules contain a number format, or no rules apply, the cell's style format is used. | |||||
* If the style does not have a format, the default date format is applied. | |||||
* | * | ||||
* @param cell The cell | |||||
* @return a formatted date string | |||||
* @param cell | |||||
* @param cfEvaluator ConditionalFormattingEvaluator (if available) | |||||
* @return | |||||
*/ | */ | ||||
private String getFormattedDateString(Cell cell) { | |||||
Format dateFormat = getFormat(cell); | |||||
private String getFormattedDateString(Cell cell, ConditionalFormattingEvaluator cfEvaluator) { | |||||
Format dateFormat = getFormat(cell, cfEvaluator); | |||||
if(dateFormat instanceof ExcelStyleDateFormatter) { | if(dateFormat instanceof ExcelStyleDateFormatter) { | ||||
// Hint about the raw excel value | // Hint about the raw excel value | ||||
((ExcelStyleDateFormatter)dateFormat).setDateToBeFormatted( | ((ExcelStyleDateFormatter)dateFormat).setDateToBeFormatted( | ||||
* based on the cell's <code>DataFormat</code>. Supported formats include | * based on the cell's <code>DataFormat</code>. Supported formats include | ||||
* currency, percents, decimals, phone number, SSN, etc.: | * currency, percents, decimals, phone number, SSN, etc.: | ||||
* "61.54%", "$100.00", "(800) 555-1234". | * "61.54%", "$100.00", "(800) 555-1234". | ||||
* | |||||
* <p/> | |||||
* Format comes from either the highest priority conditional format rule with a | |||||
* specified format, or from the cell style. | |||||
* | |||||
* @param cell The cell | * @param cell The cell | ||||
* @param cfEvaluator if available, or null | |||||
* @return a formatted number string | * @return a formatted number string | ||||
*/ | */ | ||||
private String getFormattedNumberString(Cell cell) { | |||||
private String getFormattedNumberString(Cell cell, ConditionalFormattingEvaluator cfEvaluator) { | |||||
Format numberFormat = getFormat(cell); | |||||
Format numberFormat = getFormat(cell, cfEvaluator); | |||||
double d = cell.getNumericCellValue(); | double d = cell.getNumericCellValue(); | ||||
if (numberFormat == null) { | if (numberFormat == null) { | ||||
return String.valueOf(d); | return String.valueOf(d); | ||||
/** | /** | ||||
* <p> | * <p> | ||||
* Returns the formatted value of a cell as a <tt>String</tt> regardless | * Returns the formatted value of a cell as a <tt>String</tt> regardless | ||||
* of the cell type. If the Excel format pattern cannot be parsed then the | |||||
* of the cell type. If the Excel number format pattern cannot be parsed then the | |||||
* cell value will be formatted using a default format. | * cell value will be formatted using a default format. | ||||
* </p> | * </p> | ||||
* <p>When passed a null or blank cell, this method will return an empty | * <p>When passed a null or blank cell, this method will return an empty | ||||
* @return a string value of the cell | * @return a string value of the cell | ||||
*/ | */ | ||||
public String formatCellValue(Cell cell, FormulaEvaluator evaluator) { | public String formatCellValue(Cell cell, FormulaEvaluator evaluator) { | ||||
return formatCellValue(cell, evaluator, null); | |||||
} | |||||
/** | |||||
* <p> | |||||
* Returns the formatted value of a cell as a <tt>String</tt> regardless | |||||
* of the cell type. If the Excel number format pattern cannot be parsed then the | |||||
* cell value will be formatted using a default format. | |||||
* </p> | |||||
* <p>When passed a null or blank cell, this method will return an empty | |||||
* String (""). Formula cells will be evaluated using the given | |||||
* {@link FormulaEvaluator} if the evaluator is non-null. If the | |||||
* evaluator is null, then the formula String will be returned. The caller | |||||
* is responsible for setting the currentRow on the evaluator | |||||
*</p> | |||||
* <p> | |||||
* When a ConditionalFormattingEvaluator is present, it is checked first to see | |||||
* if there is a number format to apply. If multiple rules apply, the last one is used. | |||||
* If no ConditionalFormattingEvaluator is present, no rules apply, or the applied | |||||
* rules do not define a format, the cell's style format is used. | |||||
* </p> | |||||
* <p> | |||||
* The two evaluators should be from the same context, to avoid inconsistencies in cached values. | |||||
*</p> | |||||
* | |||||
* @param cell The cell (can be null) | |||||
* @param evaluator The FormulaEvaluator (can be null) | |||||
* @param cfEvaluator ConditionalFormattingEvaluator (can be null) | |||||
* @return a string value of the cell | |||||
*/ | |||||
public String formatCellValue(Cell cell, FormulaEvaluator evaluator, ConditionalFormattingEvaluator cfEvaluator) { | |||||
localeChangedObservable.checkForLocaleChange(); | localeChangedObservable.checkForLocaleChange(); | ||||
if (cell == null) { | if (cell == null) { | ||||
switch (cellType) { | switch (cellType) { | ||||
case NUMERIC : | case NUMERIC : | ||||
if (DateUtil.isCellDateFormatted(cell)) { | |||||
return getFormattedDateString(cell); | |||||
if (DateUtil.isCellDateFormatted(cell, cfEvaluator)) { | |||||
return getFormattedDateString(cell, cfEvaluator); | |||||
} | } | ||||
return getFormattedNumberString(cell); | |||||
return getFormattedNumberString(cell, cfEvaluator); | |||||
case STRING : | case STRING : | ||||
return cell.getRichStringCellValue().getString(); | return cell.getRichStringCellValue().getString(); |
package org.apache.poi.ss.usermodel; | package org.apache.poi.ss.usermodel; | ||||
import java.util.Calendar; | import java.util.Calendar; | ||||
import java.util.Collections; | |||||
import java.util.Date; | import java.util.Date; | ||||
import java.util.List; | |||||
import java.util.TimeZone; | import java.util.TimeZone; | ||||
import java.util.regex.Pattern; | import java.util.regex.Pattern; | ||||
import org.apache.poi.ss.formula.ConditionalFormattingEvaluator; | |||||
import org.apache.poi.ss.formula.EvaluationConditionalFormatRule; | |||||
import org.apache.poi.util.LocaleUtil; | import org.apache.poi.util.LocaleUtil; | ||||
/** | /** | ||||
lastCachedResult.set(Boolean.valueOf(cached)); | lastCachedResult.set(Boolean.valueOf(cached)); | ||||
} | } | ||||
/** | |||||
* Given a format ID and its format String, will check to see if the | |||||
* format represents a date format or not. | |||||
* Firstly, it will check to see if the format ID corresponds to an | |||||
* internal excel date format (eg most US date formats) | |||||
* If not, it will check to see if the format string only contains | |||||
* date formatting characters (ymd-/), which covers most | |||||
* non US date formats. | |||||
* | |||||
* @param numFmt The number format index and string expression, or null if not specified | |||||
* @return true if it is a valid date format, false if not or null | |||||
* @see #isInternalDateFormat(int) | |||||
*/ | |||||
public static boolean isADateFormat(ExcelNumberFormat numFmt) { | |||||
if (numFmt == null) return false; | |||||
return isADateFormat(numFmt.getIdx(), numFmt.getFormat()); | |||||
} | |||||
/** | /** | ||||
* Given a format ID and its format String, will check to see if the | * Given a format ID and its format String, will check to see if the | ||||
* format represents a date format or not. | * format represents a date format or not. | ||||
* | * | ||||
* @param formatIndex The index of the format, eg from ExtendedFormatRecord.getFormatIndex | * @param formatIndex The index of the format, eg from ExtendedFormatRecord.getFormatIndex | ||||
* @param formatString The format string, eg from FormatRecord.getFormatString | * @param formatString The format string, eg from FormatRecord.getFormatString | ||||
* @return true if it is a valid date format, false if not or null | |||||
* @see #isInternalDateFormat(int) | * @see #isInternalDateFormat(int) | ||||
*/ | */ | ||||
public static boolean isADateFormat(int formatIndex, String formatString) { | public static boolean isADateFormat(int formatIndex, String formatString) { | ||||
// First up, is this an internal date format? | // First up, is this an internal date format? | ||||
if(isInternalDateFormat(formatIndex)) { | if(isInternalDateFormat(formatIndex)) { | ||||
cache(formatString, formatIndex, true); | cache(formatString, formatIndex, true); | ||||
* Check if a cell contains a date | * Check if a cell contains a date | ||||
* Since dates are stored internally in Excel as double values | * Since dates are stored internally in Excel as double values | ||||
* we infer it is a date if it is formatted as such. | * we infer it is a date if it is formatted as such. | ||||
* @param cell | |||||
* @return true if it looks like a date | |||||
* @see #isADateFormat(int, String) | * @see #isADateFormat(int, String) | ||||
* @see #isInternalDateFormat(int) | * @see #isInternalDateFormat(int) | ||||
*/ | */ | ||||
public static boolean isCellDateFormatted(Cell cell) { | public static boolean isCellDateFormatted(Cell cell) { | ||||
return isCellDateFormatted(cell, null); | |||||
} | |||||
/** | |||||
* Check if a cell contains a date | |||||
* Since dates are stored internally in Excel as double values | |||||
* we infer it is a date if it is formatted as such. | |||||
* Format is determined from applicable conditional formatting, if | |||||
* any, or cell style. | |||||
* @param cell | |||||
* @param cfEvaluator if available, or null | |||||
* @return true if it looks like a date | |||||
* @see #isADateFormat(int, String) | |||||
* @see #isInternalDateFormat(int) | |||||
*/ | |||||
public static boolean isCellDateFormatted(Cell cell, ConditionalFormattingEvaluator cfEvaluator) { | |||||
if (cell == null) return false; | if (cell == null) return false; | ||||
boolean bDate = false; | boolean bDate = false; | ||||
double d = cell.getNumericCellValue(); | double d = cell.getNumericCellValue(); | ||||
if ( DateUtil.isValidExcelDate(d) ) { | if ( DateUtil.isValidExcelDate(d) ) { | ||||
CellStyle style = cell.getCellStyle(); | |||||
if(style==null) return false; | |||||
int i = style.getDataFormat(); | |||||
String f = style.getDataFormatString(); | |||||
bDate = isADateFormat(i, f); | |||||
ExcelNumberFormat nf = ExcelNumberFormat.from(cell, cfEvaluator); | |||||
if(nf==null) return false; | |||||
bDate = isADateFormat(nf); | |||||
} | } | ||||
return bDate; | return bDate; | ||||
} | } | ||||
/** | /** | ||||
* Check if a cell contains a date, checking only for internal | * Check if a cell contains a date, checking only for internal | ||||
* excel date formats. | * excel date formats. |
package org.apache.poi.ss.usermodel; | |||||
import java.util.List; | |||||
import org.apache.poi.ss.formula.ConditionalFormattingEvaluator; | |||||
import org.apache.poi.ss.formula.EvaluationConditionalFormatRule; | |||||
/** | |||||
* Object to hold a number format index and string, for various formatting evaluations | |||||
*/ | |||||
public class ExcelNumberFormat { | |||||
private final int idx; | |||||
private final String format; | |||||
/** | |||||
* @param style | |||||
* @return null if the style is null, instance from style data format values otherwise | |||||
*/ | |||||
public static ExcelNumberFormat from(CellStyle style) { | |||||
if (style == null) return null; | |||||
return new ExcelNumberFormat(style.getDataFormat(), style.getDataFormatString()); | |||||
} | |||||
/** | |||||
* @param cell cell to extract format from | |||||
* @param cfEvaluator ConditionalFormattingEvaluator to use, or null if none in this context | |||||
* @return number format from highest-priority rule with a number format, or the cell style, or null if none of the above apply/are defined | |||||
*/ | |||||
public static ExcelNumberFormat from(Cell cell, ConditionalFormattingEvaluator cfEvaluator) { | |||||
if (cell == null) return null; | |||||
ExcelNumberFormat nf = null; | |||||
if (cfEvaluator != null) { | |||||
// first one wins (priority order, per Excel help) | |||||
List<EvaluationConditionalFormatRule> rules = cfEvaluator.getConditionalFormattingForCell(cell); | |||||
for (EvaluationConditionalFormatRule rule : rules) { | |||||
nf = rule.getNumberFormat(); | |||||
if (nf != null) break; | |||||
} | |||||
} | |||||
if (nf == null) { | |||||
CellStyle style = cell.getCellStyle(); | |||||
nf = ExcelNumberFormat.from(style); | |||||
} | |||||
return nf; | |||||
} | |||||
/** | |||||
* Use this carefully, prefer factory methods to ensure id/format relationships are not broken or confused. | |||||
* Left public so {@link ConditionalFormattingRule#getNumberFormat()} implementations can use it. | |||||
* @param idx Excel number format index, either a built-in or a higher custom # mapped in the workbook style table | |||||
* @param format Excel number format string for the index | |||||
*/ | |||||
public ExcelNumberFormat(int idx, String format) { | |||||
this.idx = idx; | |||||
this.format = format; | |||||
} | |||||
/** | |||||
* | |||||
* @return Excel number format index, either a built-in or a higher custom # mapped in the workbook style table | |||||
*/ | |||||
public int getIdx() { | |||||
return idx; | |||||
} | |||||
/** | |||||
* | |||||
* @return Excel number format string for the index | |||||
*/ | |||||
public String getFormat() { | |||||
return format; | |||||
} | |||||
} |
} | } | ||||
} | } | ||||
/** | |||||
* Return the number format from the dxf style record if present, null if not | |||||
* @see org.apache.poi.ss.usermodel.ConditionalFormattingRule#getNumberFormat() | |||||
*/ | |||||
public ExcelNumberFormat getNumberFormat() { | |||||
CTDxf dxf = getDxf(false); | |||||
if(dxf == null || !dxf.isSetNumFmt()) return null; | |||||
CTNumFmt numFmt = dxf.getNumFmt(); | |||||
return new ExcelNumberFormat((int) numFmt.getNumFmtId(), numFmt.getFormatCode()); | |||||
} | |||||
/** | /** | ||||
* Type of conditional formatting rule. | * Type of conditional formatting rule. | ||||
*/ | */ |
import java.io.IOException; | import java.io.IOException; | ||||
import org.apache.poi.hssf.HSSFTestDataSamples; | |||||
import org.apache.poi.ss.formula.ConditionalFormattingEvaluator; | |||||
import org.apache.poi.ss.formula.WorkbookEvaluatorProvider; | |||||
import org.apache.poi.ss.usermodel.BaseTestDataFormat; | import org.apache.poi.ss.usermodel.BaseTestDataFormat; | ||||
import org.apache.poi.ss.usermodel.BuiltinFormats; | import org.apache.poi.ss.usermodel.BuiltinFormats; | ||||
import org.apache.poi.ss.usermodel.Cell; | import org.apache.poi.ss.usermodel.Cell; | ||||
import org.apache.poi.ss.usermodel.CellStyle; | import org.apache.poi.ss.usermodel.CellStyle; | ||||
import org.apache.poi.ss.usermodel.CellType; | |||||
import org.apache.poi.ss.usermodel.DataFormat; | import org.apache.poi.ss.usermodel.DataFormat; | ||||
import org.apache.poi.ss.usermodel.DataFormatter; | |||||
import org.apache.poi.ss.usermodel.FormulaEvaluator; | |||||
import org.apache.poi.ss.usermodel.Workbook; | |||||
import org.apache.poi.ss.util.CellReference; | |||||
import org.apache.poi.xssf.XSSFITestDataProvider; | import org.apache.poi.xssf.XSSFITestDataProvider; | ||||
import org.apache.poi.xssf.XSSFTestDataSamples; | import org.apache.poi.xssf.XSSFTestDataSamples; | ||||
import org.junit.Test; | import org.junit.Test; | ||||
wb2.close(); | wb2.close(); | ||||
wb1.close(); | wb1.close(); | ||||
} | } | ||||
@Test | |||||
public void testConditionalFormattingEvaluation() throws IOException { | |||||
final Workbook wb = XSSFTestDataSamples.openSampleWorkbook("61060-conditional-number-formatting.xlsx"); | |||||
final DataFormatter formatter = new DataFormatter(); | |||||
final FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); | |||||
final ConditionalFormattingEvaluator cfEvaluator = new ConditionalFormattingEvaluator(wb, (WorkbookEvaluatorProvider) evaluator); | |||||
CellReference ref = new CellReference("A1"); | |||||
Cell cell = wb.getSheetAt(0).getRow(ref.getRow()).getCell(ref.getCol()); | |||||
assertEquals("0.10", formatter.formatCellValue(cell, evaluator, cfEvaluator)); | |||||
// verify cell format without the conditional rule applied | |||||
assertEquals("0.1", formatter.formatCellValue(cell, evaluator)); | |||||
ref = new CellReference("A3"); | |||||
cell = wb.getSheetAt(0).getRow(ref.getRow()).getCell(ref.getCol()); | |||||
assertEquals("-2.00E+03", formatter.formatCellValue(cell, evaluator, cfEvaluator)); | |||||
// verify cell format without the conditional rule applied | |||||
assertEquals("-2000", formatter.formatCellValue(cell, evaluator)); | |||||
ref = new CellReference("A4"); | |||||
cell = wb.getSheetAt(0).getRow(ref.getRow()).getCell(ref.getCol()); | |||||
assertEquals("100", formatter.formatCellValue(cell, evaluator, cfEvaluator)); | |||||
ref = new CellReference("A5"); | |||||
cell = wb.getSheetAt(0).getRow(ref.getRow()).getCell(ref.getCol()); | |||||
assertEquals("$1,000", formatter.formatCellValue(cell, evaluator, cfEvaluator)); | |||||
// verify cell format without the conditional rule applied | |||||
assertEquals("1000", formatter.formatCellValue(cell, evaluator)); | |||||
wb.close(); | |||||
} | |||||
} | } |