git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@944869 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_7_BETA1
<changes> | <changes> | ||||
<release version="3.7-SNAPSHOT" date="2010-??-??"> | <release version="3.7-SNAPSHOT" date="2010-??-??"> | ||||
<action dev="POI-DEVELOPERS" type="add">49244 -Support for data validation for OOXML format</action> | |||||
<action dev="POI-DEVELOPERS" type="add">49066 - Worksheet/cell formatting, with view and HTML converter</action> | <action dev="POI-DEVELOPERS" type="add">49066 - Worksheet/cell formatting, with view and HTML converter</action> | ||||
<action dev="POI-DEVELOPERS" type="fix">49020 - Workaround Excel outputting invalid XML in button definitions by not closing BR tags</action> | <action dev="POI-DEVELOPERS" type="fix">49020 - Workaround Excel outputting invalid XML in button definitions by not closing BR tags</action> | ||||
<action dev="POI-DEVELOPERS" type="fix">49050 - Improve performance of AbstractEscherHolderRecord when there are lots of Continue Records</action> | <action dev="POI-DEVELOPERS" type="fix">49050 - Improve performance of AbstractEscherHolderRecord when there are lots of Continue Records</action> |
import org.apache.poi.hssf.record.formula.Ptg; | import org.apache.poi.hssf.record.formula.Ptg; | ||||
import org.apache.poi.hssf.record.formula.StringPtg; | import org.apache.poi.hssf.record.formula.StringPtg; | ||||
import org.apache.poi.ss.formula.FormulaType; | import org.apache.poi.ss.formula.FormulaType; | ||||
import org.apache.poi.ss.usermodel.DataValidationConstraint; | |||||
/** | /** | ||||
* | * | ||||
* @author Josh Micich | * @author Josh Micich | ||||
*/ | */ | ||||
public class DVConstraint { | |||||
/** | |||||
* ValidationType enum | |||||
*/ | |||||
public static final class ValidationType { | |||||
private ValidationType() { | |||||
// no instances of this class | |||||
} | |||||
/** 'Any value' type - value not restricted */ | |||||
public static final int ANY = 0x00; | |||||
/** Integer ('Whole number') type */ | |||||
public static final int INTEGER = 0x01; | |||||
/** Decimal type */ | |||||
public static final int DECIMAL = 0x02; | |||||
/** List type ( combo box type ) */ | |||||
public static final int LIST = 0x03; | |||||
/** Date type */ | |||||
public static final int DATE = 0x04; | |||||
/** Time type */ | |||||
public static final int TIME = 0x05; | |||||
/** String length type */ | |||||
public static final int TEXT_LENGTH = 0x06; | |||||
/** Formula ( 'Custom' ) type */ | |||||
public static final int FORMULA = 0x07; | |||||
} | |||||
/** | |||||
* Condition operator enum | |||||
*/ | |||||
public static final class OperatorType { | |||||
private OperatorType() { | |||||
// no instances of this class | |||||
} | |||||
public static final int BETWEEN = 0x00; | |||||
public static final int NOT_BETWEEN = 0x01; | |||||
public static final int EQUAL = 0x02; | |||||
public static final int NOT_EQUAL = 0x03; | |||||
public static final int GREATER_THAN = 0x04; | |||||
public static final int LESS_THAN = 0x05; | |||||
public static final int GREATER_OR_EQUAL = 0x06; | |||||
public static final int LESS_OR_EQUAL = 0x07; | |||||
/** default value to supply when the operator type is not used */ | |||||
public static final int IGNORED = BETWEEN; | |||||
/* package */ static void validateSecondArg(int comparisonOperator, String paramValue) { | |||||
switch (comparisonOperator) { | |||||
case BETWEEN: | |||||
case NOT_BETWEEN: | |||||
if (paramValue == null) { | |||||
throw new IllegalArgumentException("expr2 must be supplied for 'between' comparisons"); | |||||
} | |||||
// all other operators don't need second arg | |||||
} | |||||
} | |||||
} | |||||
/* package */ static final class FormulaPair { | |||||
public class DVConstraint implements DataValidationConstraint { | |||||
/* package */ public static final class FormulaPair { | |||||
private final Ptg[] _formula1; | private final Ptg[] _formula1; | ||||
private final Ptg[] _formula2; | private final Ptg[] _formula2; | ||||
String formula2 = getFormulaFromTextExpression(expr2); | String formula2 = getFormulaFromTextExpression(expr2); | ||||
Double value2 = formula2 == null ? convertTime(expr2) : null; | Double value2 = formula2 == null ? convertTime(expr2) : null; | ||||
return new DVConstraint(VT.TIME, comparisonOperator, formula1, formula2, value1, value2, null); | return new DVConstraint(VT.TIME, comparisonOperator, formula1, formula2, value1, value2, null); | ||||
} | } | ||||
/** | /** | ||||
* Creates a date based data validation constraint. The text values entered for expr1 and expr2 | * Creates a date based data validation constraint. The text values entered for expr1 and expr2 | ||||
* can be either standard Excel formulas or formatted date values. If the expression starts | * can be either standard Excel formulas or formatted date values. If the expression starts | ||||
return new DVConstraint(VT.FORMULA, OperatorType.IGNORED, formula, null, null, null, null); | return new DVConstraint(VT.FORMULA, OperatorType.IGNORED, formula, null, null, null, null); | ||||
} | } | ||||
/** | |||||
* @return both parsed formulas (for expression 1 and 2). | |||||
*/ | |||||
/* package */ FormulaPair createFormulas(HSSFSheet sheet) { | |||||
Ptg[] formula1; | |||||
Ptg[] formula2; | |||||
if (isListValidationType()) { | |||||
formula1 = createListFormula(sheet); | |||||
formula2 = Ptg.EMPTY_PTG_ARRAY; | |||||
} else { | |||||
formula1 = convertDoubleFormula(_formula1, _value1, sheet); | |||||
formula2 = convertDoubleFormula(_formula2, _value2, sheet); | |||||
} | |||||
return new FormulaPair(formula1, formula2); | |||||
} | |||||
private Ptg[] createListFormula(HSSFSheet sheet) { | |||||
if (_explicitListValues == null) { | |||||
HSSFWorkbook wb = sheet.getWorkbook(); | |||||
// formula is parsed with slightly different RVA rules: (root node type must be 'reference') | |||||
return HSSFFormulaParser.parse(_formula1, wb, FormulaType.DATAVALIDATION_LIST, wb.getSheetIndex(sheet)); | |||||
// To do: Excel places restrictions on the available operations within a list formula. | |||||
// Some things like union and intersection are not allowed. | |||||
} | |||||
// explicit list was provided | |||||
StringBuffer sb = new StringBuffer(_explicitListValues.length * 16); | |||||
for (int i = 0; i < _explicitListValues.length; i++) { | |||||
if (i > 0) { | |||||
sb.append('\0'); // list delimiter is the nul char | |||||
} | |||||
sb.append(_explicitListValues[i]); | |||||
} | |||||
return new Ptg[] { new StringPtg(sb.toString()), }; | |||||
} | |||||
/** | |||||
* @return The parsed token array representing the formula or value specified. | |||||
* Empty array if both formula and value are <code>null</code> | |||||
*/ | |||||
private static Ptg[] convertDoubleFormula(String formula, Double value, HSSFSheet sheet) { | |||||
if (formula == null) { | |||||
if (value == null) { | |||||
return Ptg.EMPTY_PTG_ARRAY; | |||||
} | |||||
return new Ptg[] { new NumberPtg(value.doubleValue()), }; | |||||
} | |||||
if (value != null) { | |||||
throw new IllegalStateException("Both formula and value cannot be present"); | |||||
} | |||||
HSSFWorkbook wb = sheet.getWorkbook(); | |||||
return HSSFFormulaParser.parse(formula, wb, FormulaType.CELL, wb.getSheetIndex(sheet)); | |||||
} | |||||
/** | |||||
* @return data validation type of this constraint | |||||
* @see ValidationType | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidationConstraint#getValidationType() | |||||
*/ | */ | ||||
public int getValidationType() { | public int getValidationType() { | ||||
return _validationType; | return _validationType; | ||||
public boolean isExplicitList() { | public boolean isExplicitList() { | ||||
return _validationType == VT.LIST && _explicitListValues != null; | return _validationType == VT.LIST && _explicitListValues != null; | ||||
} | } | ||||
/** | |||||
* @return the operator used for this constraint | |||||
* @see OperatorType | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidationConstraint#getOperator() | |||||
*/ | */ | ||||
public int getOperator() { | public int getOperator() { | ||||
return _operator; | return _operator; | ||||
} | } | ||||
/** | |||||
* Sets the comparison operator for this constraint | |||||
* @see OperatorType | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidationConstraint#setOperator(int) | |||||
*/ | */ | ||||
public void setOperator(int operator) { | public void setOperator(int operator) { | ||||
_operator = operator; | _operator = operator; | ||||
} | } | ||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidationConstraint#getExplicitListValues() | |||||
*/ | |||||
public String[] getExplicitListValues() { | public String[] getExplicitListValues() { | ||||
return _explicitListValues; | return _explicitListValues; | ||||
} | } | ||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidationConstraint#setExplicitListValues(java.lang.String[]) | |||||
*/ | |||||
public void setExplicitListValues(String[] explicitListValues) { | public void setExplicitListValues(String[] explicitListValues) { | ||||
if (_validationType != VT.LIST) { | if (_validationType != VT.LIST) { | ||||
throw new RuntimeException("Cannot setExplicitListValues on non-list constraint"); | throw new RuntimeException("Cannot setExplicitListValues on non-list constraint"); | ||||
_explicitListValues = explicitListValues; | _explicitListValues = explicitListValues; | ||||
} | } | ||||
/** | |||||
* @return the formula for expression 1. May be <code>null</code> | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidationConstraint#getFormula1() | |||||
*/ | */ | ||||
public String getFormula1() { | public String getFormula1() { | ||||
return _formula1; | return _formula1; | ||||
} | } | ||||
/** | |||||
* Sets a formula for expression 1. | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidationConstraint#setFormula1(java.lang.String) | |||||
*/ | */ | ||||
public void setFormula1(String formula1) { | public void setFormula1(String formula1) { | ||||
_value1 = null; | _value1 = null; | ||||
_formula1 = formula1; | _formula1 = formula1; | ||||
} | } | ||||
/** | |||||
* @return the formula for expression 2. May be <code>null</code> | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidationConstraint#getFormula2() | |||||
*/ | */ | ||||
public String getFormula2() { | public String getFormula2() { | ||||
return _formula2; | return _formula2; | ||||
} | } | ||||
/** | |||||
* Sets a formula for expression 2. | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidationConstraint#setFormula2(java.lang.String) | |||||
*/ | */ | ||||
public void setFormula2(String formula2) { | public void setFormula2(String formula2) { | ||||
_value2 = null; | _value2 = null; | ||||
_formula2 = null; | _formula2 = null; | ||||
_value2 = new Double(value2); | _value2 = new Double(value2); | ||||
} | } | ||||
/** | |||||
* @return both parsed formulas (for expression 1 and 2). | |||||
*/ | |||||
/* package */ FormulaPair createFormulas(HSSFSheet sheet) { | |||||
Ptg[] formula1; | |||||
Ptg[] formula2; | |||||
if (isListValidationType()) { | |||||
formula1 = createListFormula(sheet); | |||||
formula2 = Ptg.EMPTY_PTG_ARRAY; | |||||
} else { | |||||
formula1 = convertDoubleFormula(_formula1, _value1, sheet); | |||||
formula2 = convertDoubleFormula(_formula2, _value2, sheet); | |||||
} | |||||
return new FormulaPair(formula1, formula2); | |||||
} | |||||
private Ptg[] createListFormula(HSSFSheet sheet) { | |||||
if (_explicitListValues == null) { | |||||
HSSFWorkbook wb = sheet.getWorkbook(); | |||||
// formula is parsed with slightly different RVA rules: (root node type must be 'reference') | |||||
return HSSFFormulaParser.parse(_formula1, wb, FormulaType.DATAVALIDATION_LIST, wb.getSheetIndex(sheet)); | |||||
// To do: Excel places restrictions on the available operations within a list formula. | |||||
// Some things like union and intersection are not allowed. | |||||
} | |||||
// explicit list was provided | |||||
StringBuffer sb = new StringBuffer(_explicitListValues.length * 16); | |||||
for (int i = 0; i < _explicitListValues.length; i++) { | |||||
if (i > 0) { | |||||
sb.append('\0'); // list delimiter is the nul char | |||||
} | |||||
sb.append(_explicitListValues[i]); | |||||
} | |||||
return new Ptg[] { new StringPtg(sb.toString()), }; | |||||
} | |||||
/** | |||||
* @return The parsed token array representing the formula or value specified. | |||||
* Empty array if both formula and value are <code>null</code> | |||||
*/ | |||||
private static Ptg[] convertDoubleFormula(String formula, Double value, HSSFSheet sheet) { | |||||
if (formula == null) { | |||||
if (value == null) { | |||||
return Ptg.EMPTY_PTG_ARRAY; | |||||
} | |||||
return new Ptg[] { new NumberPtg(value.doubleValue()), }; | |||||
} | |||||
if (value != null) { | |||||
throw new IllegalStateException("Both formula and value cannot be present"); | |||||
} | |||||
HSSFWorkbook wb = sheet.getWorkbook(); | |||||
return HSSFFormulaParser.parse(formula, wb, FormulaType.CELL, wb.getSheetIndex(sheet)); | |||||
} | |||||
} | } |
import org.apache.poi.hssf.record.DVRecord; | import org.apache.poi.hssf.record.DVRecord; | ||||
import org.apache.poi.hssf.usermodel.DVConstraint.FormulaPair; | import org.apache.poi.hssf.usermodel.DVConstraint.FormulaPair; | ||||
import org.apache.poi.ss.usermodel.DataValidation; | |||||
import org.apache.poi.ss.usermodel.DataValidationConstraint; | |||||
import org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType; | |||||
import org.apache.poi.ss.util.CellRangeAddressList; | import org.apache.poi.ss.util.CellRangeAddressList; | ||||
/** | /** | ||||
* | * | ||||
* @author Dragos Buleandra (dragos.buleandra@trade2b.ro) | * @author Dragos Buleandra (dragos.buleandra@trade2b.ro) | ||||
*/ | */ | ||||
public final class HSSFDataValidation { | |||||
/** | |||||
* Error style constants for error box | |||||
*/ | |||||
public static final class ErrorStyle { | |||||
/** STOP style */ | |||||
public static final int STOP = 0x00; | |||||
/** WARNING style */ | |||||
public static final int WARNING = 0x01; | |||||
/** INFO style */ | |||||
public static final int INFO = 0x02; | |||||
} | |||||
public final class HSSFDataValidation implements DataValidation { | |||||
private String _prompt_title; | private String _prompt_title; | ||||
private String _prompt_text; | private String _prompt_text; | ||||
private String _error_title; | private String _error_title; | ||||
private boolean _suppress_dropdown_arrow = false; | private boolean _suppress_dropdown_arrow = false; | ||||
private boolean _showPromptBox = true; | private boolean _showPromptBox = true; | ||||
private boolean _showErrorBox = true; | private boolean _showErrorBox = true; | ||||
private final CellRangeAddressList _regions; | |||||
private CellRangeAddressList _regions; | |||||
private DVConstraint _constraint; | private DVConstraint _constraint; | ||||
/** | /** | ||||
* applied | * applied | ||||
* @param constraint | * @param constraint | ||||
*/ | */ | ||||
public HSSFDataValidation(CellRangeAddressList regions, DVConstraint constraint) { | |||||
public HSSFDataValidation(CellRangeAddressList regions, DataValidationConstraint constraint) { | |||||
_regions = regions; | _regions = regions; | ||||
_constraint = constraint; | |||||
//FIXME: This cast can be avoided. | |||||
_constraint = (DVConstraint)constraint; | |||||
} | } | ||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#getConstraint() | |||||
*/ | |||||
public DataValidationConstraint getValidationConstraint() { | |||||
return _constraint; | |||||
} | |||||
public DVConstraint getConstraint() { | public DVConstraint getConstraint() { | ||||
return _constraint; | return _constraint; | ||||
} | } | ||||
public CellRangeAddressList getRegions() { | |||||
return _regions; | |||||
} | |||||
/** | |||||
* Sets the error style for error box | |||||
* @see ErrorStyle | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#setErrorStyle(int) | |||||
*/ | */ | ||||
public void setErrorStyle(int error_style) { | public void setErrorStyle(int error_style) { | ||||
_errorStyle = error_style; | _errorStyle = error_style; | ||||
} | } | ||||
/** | |||||
* @return the error style of error box | |||||
* @see ErrorStyle | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#getErrorStyle() | |||||
*/ | */ | ||||
public int getErrorStyle() { | public int getErrorStyle() { | ||||
return _errorStyle; | return _errorStyle; | ||||
} | } | ||||
/** | |||||
* Sets if this object allows empty as a valid value | |||||
* | |||||
* @param allowed <code>true</code> if this object should treats empty as valid value , <code>false</code> | |||||
* otherwise | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#setEmptyCellAllowed(boolean) | |||||
*/ | */ | ||||
public void setEmptyCellAllowed(boolean allowed) { | public void setEmptyCellAllowed(boolean allowed) { | ||||
_emptyCellAllowed = allowed; | _emptyCellAllowed = allowed; | ||||
} | } | ||||
/** | |||||
* Retrieve the settings for empty cells allowed | |||||
* | |||||
* @return True if this object should treats empty as valid value , false | |||||
* otherwise | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#getEmptyCellAllowed() | |||||
*/ | */ | ||||
public boolean getEmptyCellAllowed() { | public boolean getEmptyCellAllowed() { | ||||
return _emptyCellAllowed; | return _emptyCellAllowed; | ||||
} | } | ||||
/** | |||||
* Useful for list validation objects . | |||||
* | |||||
* @param suppress | |||||
* True if a list should display the values into a drop down list , | |||||
* false otherwise . In other words , if a list should display | |||||
* the arrow sign on its right side | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#setSuppressDropDownArrow(boolean) | |||||
*/ | */ | ||||
public void setSuppressDropDownArrow(boolean suppress) { | public void setSuppressDropDownArrow(boolean suppress) { | ||||
_suppress_dropdown_arrow = suppress; | _suppress_dropdown_arrow = suppress; | ||||
} | } | ||||
/** | |||||
* Useful only list validation objects . This method always returns false if | |||||
* the object isn't a list validation object | |||||
* | |||||
* @return <code>true</code> if a list should display the values into a drop down list , | |||||
* <code>false</code> otherwise . | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#getSuppressDropDownArrow() | |||||
*/ | */ | ||||
public boolean getSuppressDropDownArrow() { | public boolean getSuppressDropDownArrow() { | ||||
if (_constraint.isListValidationType()) { | |||||
if (_constraint.getValidationType()==ValidationType.LIST) { | |||||
return _suppress_dropdown_arrow; | return _suppress_dropdown_arrow; | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
/** | |||||
* Sets the behaviour when a cell which belongs to this object is selected | |||||
* | |||||
* @param show <code>true</code> if an prompt box should be displayed , <code>false</code> otherwise | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#setShowPromptBox(boolean) | |||||
*/ | */ | ||||
public void setShowPromptBox(boolean show) { | public void setShowPromptBox(boolean show) { | ||||
_showPromptBox = show; | _showPromptBox = show; | ||||
} | } | ||||
/** | |||||
* @return <code>true</code> if an prompt box should be displayed , <code>false</code> otherwise | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#getShowPromptBox() | |||||
*/ | */ | ||||
public boolean getShowPromptBox() { | public boolean getShowPromptBox() { | ||||
return _showPromptBox; | return _showPromptBox; | ||||
} | } | ||||
/** | |||||
* Sets the behaviour when an invalid value is entered | |||||
* | |||||
* @param show <code>true</code> if an error box should be displayed , <code>false</code> otherwise | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#setShowErrorBox(boolean) | |||||
*/ | */ | ||||
public void setShowErrorBox(boolean show) { | public void setShowErrorBox(boolean show) { | ||||
_showErrorBox = show; | _showErrorBox = show; | ||||
} | } | ||||
/** | |||||
* @return <code>true</code> if an error box should be displayed , <code>false</code> otherwise | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#getShowErrorBox() | |||||
*/ | */ | ||||
public boolean getShowErrorBox() { | public boolean getShowErrorBox() { | ||||
return _showErrorBox; | return _showErrorBox; | ||||
} | } | ||||
/** | |||||
* Sets the title and text for the prompt box . Prompt box is displayed when | |||||
* the user selects a cell which belongs to this validation object . In | |||||
* order for a prompt box to be displayed you should also use method | |||||
* setShowPromptBox( boolean show ) | |||||
* | |||||
* @param title The prompt box's title | |||||
* @param text The prompt box's text | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#createPromptBox(java.lang.String, java.lang.String) | |||||
*/ | */ | ||||
public void createPromptBox(String title, String text) { | public void createPromptBox(String title, String text) { | ||||
_prompt_title = title; | _prompt_title = title; | ||||
this.setShowPromptBox(true); | this.setShowPromptBox(true); | ||||
} | } | ||||
/** | |||||
* @return Prompt box's title or <code>null</code> | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#getPromptBoxTitle() | |||||
*/ | */ | ||||
public String getPromptBoxTitle() { | public String getPromptBoxTitle() { | ||||
return _prompt_title; | return _prompt_title; | ||||
} | } | ||||
/** | |||||
* @return Prompt box's text or <code>null</code> | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#getPromptBoxText() | |||||
*/ | */ | ||||
public String getPromptBoxText() { | public String getPromptBoxText() { | ||||
return _prompt_text; | return _prompt_text; | ||||
} | } | ||||
/** | |||||
* Sets the title and text for the error box . Error box is displayed when | |||||
* the user enters an invalid value int o a cell which belongs to this | |||||
* validation object . In order for an error box to be displayed you should | |||||
* also use method setShowErrorBox( boolean show ) | |||||
* | |||||
* @param title The error box's title | |||||
* @param text The error box's text | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#createErrorBox(java.lang.String, java.lang.String) | |||||
*/ | */ | ||||
public void createErrorBox(String title, String text) { | public void createErrorBox(String title, String text) { | ||||
_error_title = title; | _error_title = title; | ||||
this.setShowErrorBox(true); | this.setShowErrorBox(true); | ||||
} | } | ||||
/** | |||||
* @return Error box's title or <code>null</code> | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#getErrorBoxTitle() | |||||
*/ | */ | ||||
public String getErrorBoxTitle() { | public String getErrorBoxTitle() { | ||||
return _error_title; | return _error_title; | ||||
} | } | ||||
/** | |||||
* @return Error box's text or <code>null</code> | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.hssf.usermodel.DataValidation#getErrorBoxText() | |||||
*/ | */ | ||||
public String getErrorBoxText() { | public String getErrorBoxText() { | ||||
return _error_text; | return _error_text; | ||||
return new DVRecord(_constraint.getValidationType(), | return new DVRecord(_constraint.getValidationType(), | ||||
_constraint.getOperator(), | _constraint.getOperator(), | ||||
_errorStyle, _emptyCellAllowed, getSuppressDropDownArrow(), | _errorStyle, _emptyCellAllowed, getSuppressDropDownArrow(), | ||||
_constraint.isExplicitList(), | |||||
_constraint.getValidationType()==ValidationType.LIST && _constraint.getExplicitListValues()!=null, | |||||
_showPromptBox, _prompt_title, _prompt_text, | _showPromptBox, _prompt_title, _prompt_text, | ||||
_showErrorBox, _error_title, _error_text, | _showErrorBox, _error_title, _error_text, | ||||
fp.getFormula1(), fp.getFormula2(), | fp.getFormula1(), fp.getFormula2(), |
/** | |||||
* | |||||
*/ | |||||
package org.apache.poi.hssf.usermodel; | |||||
import org.apache.poi.ss.usermodel.DataValidation; | |||||
import org.apache.poi.ss.usermodel.DataValidationConstraint; | |||||
import org.apache.poi.ss.usermodel.DataValidationHelper; | |||||
import org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType; | |||||
import org.apache.poi.ss.util.CellRangeAddressList; | |||||
/** | |||||
* @author <a href="rjankiraman@emptoris.com">Radhakrishnan J</a> | |||||
* | |||||
*/ | |||||
public class HSSFDataValidationHelper implements DataValidationHelper { | |||||
@SuppressWarnings("unused") | |||||
private HSSFSheet sheet; | |||||
public HSSFDataValidationHelper(HSSFSheet sheet) { | |||||
super(); | |||||
this.sheet = sheet; | |||||
} | |||||
/* | |||||
* (non-Javadoc) | |||||
* | |||||
* @see | |||||
* org.apache.poi.ss.usermodel.DataValidationHelper#createDateConstraint | |||||
* (int, java.lang.String, java.lang.String, java.lang.String) | |||||
*/ | |||||
public DataValidationConstraint createDateConstraint(int operatorType, String formula1, String formula2, String dateFormat) { | |||||
return DVConstraint.createDateConstraint(operatorType, formula1, formula2, dateFormat); | |||||
} | |||||
/* | |||||
* (non-Javadoc) | |||||
* | |||||
* @see | |||||
* org.apache.poi.ss.usermodel.DataValidationHelper#createExplicitListConstraint | |||||
* (java.lang.String[]) | |||||
*/ | |||||
public DataValidationConstraint createExplicitListConstraint(String[] listOfValues) { | |||||
return DVConstraint.createExplicitListConstraint(listOfValues); | |||||
} | |||||
/* | |||||
* (non-Javadoc) | |||||
* | |||||
* @see | |||||
* org.apache.poi.ss.usermodel.DataValidationHelper#createFormulaListConstraint | |||||
* (java.lang.String) | |||||
*/ | |||||
public DataValidationConstraint createFormulaListConstraint(String listFormula) { | |||||
return DVConstraint.createFormulaListConstraint(listFormula); | |||||
} | |||||
public DataValidationConstraint createNumericConstraint(int validationType,int operatorType, String formula1, String formula2) { | |||||
return DVConstraint.createNumericConstraint(validationType, operatorType, formula1, formula2); | |||||
} | |||||
public DataValidationConstraint createIntegerConstraint(int operatorType, String formula1, String formula2) { | |||||
return DVConstraint.createNumericConstraint(ValidationType.INTEGER, operatorType, formula1, formula2); | |||||
} | |||||
/* | |||||
* (non-Javadoc) | |||||
* | |||||
* @see | |||||
* org.apache.poi.ss.usermodel.DataValidationHelper#createNumericConstraint | |||||
* (int, java.lang.String, java.lang.String) | |||||
*/ | |||||
public DataValidationConstraint createDecimalConstraint(int operatorType, String formula1, String formula2) { | |||||
return DVConstraint.createNumericConstraint(ValidationType.DECIMAL, operatorType, formula1, formula2); | |||||
} | |||||
/* | |||||
* (non-Javadoc) | |||||
* | |||||
* @see | |||||
* org.apache.poi.ss.usermodel.DataValidationHelper#createTextLengthConstraint | |||||
* (int, java.lang.String, java.lang.String) | |||||
*/ | |||||
public DataValidationConstraint createTextLengthConstraint(int operatorType, String formula1, String formula2) { | |||||
return DVConstraint.createNumericConstraint(ValidationType.TEXT_LENGTH, operatorType, formula1, formula2); | |||||
} | |||||
/* | |||||
* (non-Javadoc) | |||||
* | |||||
* @see | |||||
* org.apache.poi.ss.usermodel.DataValidationHelper#createTimeConstraint | |||||
* (int, java.lang.String, java.lang.String, java.lang.String) | |||||
*/ | |||||
public DataValidationConstraint createTimeConstraint(int operatorType, String formula1, String formula2) { | |||||
return DVConstraint.createTimeConstraint(operatorType, formula1, formula2); | |||||
} | |||||
public DataValidationConstraint createCustomConstraint(String formula) { | |||||
return DVConstraint.createCustomFormulaConstraint(formula); | |||||
} | |||||
/* | |||||
* (non-Javadoc) | |||||
* | |||||
* @see | |||||
* org.apache.poi.ss.usermodel.DataValidationHelper#createValidation(org | |||||
* .apache.poi.ss.usermodel.DataValidationConstraint, | |||||
* org.apache.poi.ss.util.CellRangeAddressList) | |||||
*/ | |||||
public DataValidation createValidation(DataValidationConstraint constraint, CellRangeAddressList cellRangeAddressList) { | |||||
return new HSSFDataValidation(cellRangeAddressList, constraint); | |||||
} | |||||
} |
import org.apache.poi.hssf.record.formula.Ptg; | import org.apache.poi.hssf.record.formula.Ptg; | ||||
import org.apache.poi.hssf.util.PaneInformation; | import org.apache.poi.hssf.util.PaneInformation; | ||||
import org.apache.poi.hssf.util.Region; | import org.apache.poi.hssf.util.Region; | ||||
import org.apache.poi.ss.SpreadsheetVersion; | |||||
import org.apache.poi.ss.formula.FormulaType; | import org.apache.poi.ss.formula.FormulaType; | ||||
import org.apache.poi.ss.usermodel.Cell; | import org.apache.poi.ss.usermodel.Cell; | ||||
import org.apache.poi.ss.usermodel.CellRange; | import org.apache.poi.ss.usermodel.CellRange; | ||||
import org.apache.poi.ss.usermodel.CellStyle; | import org.apache.poi.ss.usermodel.CellStyle; | ||||
import org.apache.poi.ss.usermodel.DataValidation; | |||||
import org.apache.poi.ss.usermodel.DataValidationHelper; | |||||
import org.apache.poi.ss.usermodel.Row; | import org.apache.poi.ss.usermodel.Row; | ||||
import org.apache.poi.ss.util.CellRangeAddress; | import org.apache.poi.ss.util.CellRangeAddress; | ||||
import org.apache.poi.ss.util.CellReference; | import org.apache.poi.ss.util.CellReference; | ||||
import org.apache.poi.ss.util.SSCellRange; | import org.apache.poi.ss.util.SSCellRange; | ||||
import org.apache.poi.ss.SpreadsheetVersion; | |||||
import org.apache.poi.util.POILogFactory; | import org.apache.poi.util.POILogFactory; | ||||
import org.apache.poi.util.POILogger; | import org.apache.poi.util.POILogger; | ||||
* Creates a data validation object | * Creates a data validation object | ||||
* @param dataValidation The Data validation object settings | * @param dataValidation The Data validation object settings | ||||
*/ | */ | ||||
public void addValidationData(HSSFDataValidation dataValidation) { | |||||
public void addValidationData(DataValidation dataValidation) { | |||||
if (dataValidation == null) { | if (dataValidation == null) { | ||||
throw new IllegalArgumentException("objValidation must not be null"); | throw new IllegalArgumentException("objValidation must not be null"); | ||||
} | } | ||||
HSSFDataValidation hssfDataValidation = (HSSFDataValidation)dataValidation; | |||||
DataValidityTable dvt = _sheet.getOrCreateDataValidityTable(); | DataValidityTable dvt = _sheet.getOrCreateDataValidityTable(); | ||||
DVRecord dvRecord = dataValidation.createDVRecord(this); | |||||
DVRecord dvRecord = hssfDataValidation.createDVRecord(this); | |||||
dvt.addDataValidation(dvRecord); | dvt.addDataValidation(dvRecord); | ||||
} | } | ||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
public DataValidationHelper getDataValidationHelper() { | |||||
return new HSSFDataValidationHelper(this); | |||||
} | |||||
} | } |
/* ==================================================================== | |||||
Licensed to the Apache Software Foundation (ASF) under one or more | |||||
contributor license agreements. See the NOTICE file distributed with | |||||
this work for additional information regarding copyright ownership. | |||||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
(the "License"); you may not use this file except in compliance with | |||||
the License. You may obtain a copy of the License at | |||||
http://www.apache.org/licenses/LICENSE-2.0 | |||||
Unless required by applicable law or agreed to in writing, software | |||||
distributed under the License is distributed on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
See the License for the specific language governing permissions and | |||||
limitations under the License. | |||||
==================================================================== */ | |||||
package org.apache.poi.ss.usermodel; | |||||
import org.apache.poi.ss.util.CellRangeAddressList; | |||||
public interface DataValidation { | |||||
/** | |||||
* Error style constants for error box | |||||
*/ | |||||
public static final class ErrorStyle { | |||||
/** STOP style */ | |||||
public static final int STOP = 0x00; | |||||
/** WARNING style */ | |||||
public static final int WARNING = 0x01; | |||||
/** INFO style */ | |||||
public static final int INFO = 0x02; | |||||
} | |||||
public abstract DataValidationConstraint getValidationConstraint(); | |||||
/** | |||||
* Sets the error style for error box | |||||
* @see ErrorStyle | |||||
*/ | |||||
public abstract void setErrorStyle(int error_style); | |||||
/**o | |||||
* @return the error style of error box | |||||
* @see ErrorStyle | |||||
*/ | |||||
public abstract int getErrorStyle(); | |||||
/** | |||||
* Sets if this object allows empty as a valid value | |||||
* | |||||
* @param allowed <code>true</code> if this object should treats empty as valid value , <code>false</code> | |||||
* otherwise | |||||
*/ | |||||
public abstract void setEmptyCellAllowed(boolean allowed); | |||||
/** | |||||
* Retrieve the settings for empty cells allowed | |||||
* | |||||
* @return True if this object should treats empty as valid value , false | |||||
* otherwise | |||||
*/ | |||||
public abstract boolean getEmptyCellAllowed(); | |||||
/** | |||||
* Useful for list validation objects . | |||||
* | |||||
* @param suppress | |||||
* True if a list should display the values into a drop down list , | |||||
* false otherwise . In other words , if a list should display | |||||
* the arrow sign on its right side | |||||
*/ | |||||
public abstract void setSuppressDropDownArrow(boolean suppress); | |||||
/** | |||||
* Useful only list validation objects . This method always returns false if | |||||
* the object isn't a list validation object | |||||
* | |||||
* @return <code>true</code> if a list should display the values into a drop down list , | |||||
* <code>false</code> otherwise . | |||||
*/ | |||||
public abstract boolean getSuppressDropDownArrow(); | |||||
/** | |||||
* Sets the behaviour when a cell which belongs to this object is selected | |||||
* | |||||
* @param show <code>true</code> if an prompt box should be displayed , <code>false</code> otherwise | |||||
*/ | |||||
public abstract void setShowPromptBox(boolean show); | |||||
/** | |||||
* @return <code>true</code> if an prompt box should be displayed , <code>false</code> otherwise | |||||
*/ | |||||
public abstract boolean getShowPromptBox(); | |||||
/** | |||||
* Sets the behaviour when an invalid value is entered | |||||
* | |||||
* @param show <code>true</code> if an error box should be displayed , <code>false</code> otherwise | |||||
*/ | |||||
public abstract void setShowErrorBox(boolean show); | |||||
/** | |||||
* @return <code>true</code> if an error box should be displayed , <code>false</code> otherwise | |||||
*/ | |||||
public abstract boolean getShowErrorBox(); | |||||
/** | |||||
* Sets the title and text for the prompt box . Prompt box is displayed when | |||||
* the user selects a cell which belongs to this validation object . In | |||||
* order for a prompt box to be displayed you should also use method | |||||
* setShowPromptBox( boolean show ) | |||||
* | |||||
* @param title The prompt box's title | |||||
* @param text The prompt box's text | |||||
*/ | |||||
public abstract void createPromptBox(String title, String text); | |||||
/** | |||||
* @return Prompt box's title or <code>null</code> | |||||
*/ | |||||
public abstract String getPromptBoxTitle(); | |||||
/** | |||||
* @return Prompt box's text or <code>null</code> | |||||
*/ | |||||
public abstract String getPromptBoxText(); | |||||
/** | |||||
* Sets the title and text for the error box . Error box is displayed when | |||||
* the user enters an invalid value int o a cell which belongs to this | |||||
* validation object . In order for an error box to be displayed you should | |||||
* also use method setShowErrorBox( boolean show ) | |||||
* | |||||
* @param title The error box's title | |||||
* @param text The error box's text | |||||
*/ | |||||
public abstract void createErrorBox(String title, String text); | |||||
/** | |||||
* @return Error box's title or <code>null</code> | |||||
*/ | |||||
public abstract String getErrorBoxTitle(); | |||||
/** | |||||
* @return Error box's text or <code>null</code> | |||||
*/ | |||||
public abstract String getErrorBoxText(); | |||||
public abstract CellRangeAddressList getRegions(); | |||||
} |
/* ==================================================================== | |||||
Licensed to the Apache Software Foundation (ASF) under one or more | |||||
contributor license agreements. See the NOTICE file distributed with | |||||
this work for additional information regarding copyright ownership. | |||||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
(the "License"); you may not use this file except in compliance with | |||||
the License. You may obtain a copy of the License at | |||||
http://www.apache.org/licenses/LICENSE-2.0 | |||||
Unless required by applicable law or agreed to in writing, software | |||||
distributed under the License is distributed on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
See the License for the specific language governing permissions and | |||||
limitations under the License. | |||||
==================================================================== */ | |||||
package org.apache.poi.ss.usermodel; | |||||
public interface DataValidationConstraint { | |||||
/** | |||||
* @return data validation type of this constraint | |||||
* @see ValidationType | |||||
*/ | |||||
public abstract int getValidationType(); | |||||
/** | |||||
* @return the operator used for this constraint | |||||
* @see OperatorType | |||||
*/ | |||||
public abstract int getOperator(); | |||||
/** | |||||
* Sets the comparison operator for this constraint | |||||
* @see OperatorType | |||||
*/ | |||||
public abstract void setOperator(int operator); | |||||
public abstract String[] getExplicitListValues(); | |||||
public abstract void setExplicitListValues(String[] explicitListValues); | |||||
/** | |||||
* @return the formula for expression 1. May be <code>null</code> | |||||
*/ | |||||
public abstract String getFormula1(); | |||||
/** | |||||
* Sets a formula for expression 1. | |||||
*/ | |||||
public abstract void setFormula1(String formula1); | |||||
/** | |||||
* @return the formula for expression 2. May be <code>null</code> | |||||
*/ | |||||
public abstract String getFormula2(); | |||||
/** | |||||
* Sets a formula for expression 2. | |||||
*/ | |||||
public abstract void setFormula2(String formula2); | |||||
/** | |||||
* ValidationType enum | |||||
*/ | |||||
public static final class ValidationType { | |||||
private ValidationType() { | |||||
// no instances of this class | |||||
} | |||||
/** 'Any value' type - value not restricted */ | |||||
public static final int ANY = 0x00; | |||||
/** Integer ('Whole number') type */ | |||||
public static final int INTEGER = 0x01; | |||||
/** Decimal type */ | |||||
public static final int DECIMAL = 0x02; | |||||
/** List type ( combo box type ) */ | |||||
public static final int LIST = 0x03; | |||||
/** Date type */ | |||||
public static final int DATE = 0x04; | |||||
/** Time type */ | |||||
public static final int TIME = 0x05; | |||||
/** String length type */ | |||||
public static final int TEXT_LENGTH = 0x06; | |||||
/** Formula ( 'Custom' ) type */ | |||||
public static final int FORMULA = 0x07; | |||||
} | |||||
/** | |||||
* Condition operator enum | |||||
*/ | |||||
public static final class OperatorType { | |||||
private OperatorType() { | |||||
// no instances of this class | |||||
} | |||||
public static final int BETWEEN = 0x00; | |||||
public static final int NOT_BETWEEN = 0x01; | |||||
public static final int EQUAL = 0x02; | |||||
public static final int NOT_EQUAL = 0x03; | |||||
public static final int GREATER_THAN = 0x04; | |||||
public static final int LESS_THAN = 0x05; | |||||
public static final int GREATER_OR_EQUAL = 0x06; | |||||
public static final int LESS_OR_EQUAL = 0x07; | |||||
/** default value to supply when the operator type is not used */ | |||||
public static final int IGNORED = BETWEEN; | |||||
/* package */ public static void validateSecondArg(int comparisonOperator, String paramValue) { | |||||
switch (comparisonOperator) { | |||||
case BETWEEN: | |||||
case NOT_BETWEEN: | |||||
if (paramValue == null) { | |||||
throw new IllegalArgumentException("expr2 must be supplied for 'between' comparisons"); | |||||
} | |||||
// all other operators don't need second arg | |||||
} | |||||
} | |||||
} | |||||
} |
/* ==================================================================== | |||||
Licensed to the Apache Software Foundation (ASF) under one or more | |||||
contributor license agreements. See the NOTICE file distributed with | |||||
this work for additional information regarding copyright ownership. | |||||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
(the "License"); you may not use this file except in compliance with | |||||
the License. You may obtain a copy of the License at | |||||
http://www.apache.org/licenses/LICENSE-2.0 | |||||
Unless required by applicable law or agreed to in writing, software | |||||
distributed under the License is distributed on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
See the License for the specific language governing permissions and | |||||
limitations under the License. | |||||
==================================================================== */ | |||||
package org.apache.poi.ss.usermodel; | |||||
import org.apache.poi.ss.util.CellRangeAddressList; | |||||
/** | |||||
* @author <a href="rjankiraman@emptoris.com">Radhakrishnan J</a> | |||||
* | |||||
*/ | |||||
public interface DataValidationHelper { | |||||
DataValidationConstraint createFormulaListConstraint(String listFormula); | |||||
DataValidationConstraint createExplicitListConstraint(String[] listOfValues); | |||||
DataValidationConstraint createNumericConstraint(int validationType,int operatorType, String formula1, String formula2); | |||||
DataValidationConstraint createTextLengthConstraint(int operatorType, String formula1, String formula2); | |||||
DataValidationConstraint createDecimalConstraint(int operatorType, String formula1, String formula2); | |||||
DataValidationConstraint createIntegerConstraint(int operatorType, String formula1, String formula2); | |||||
DataValidationConstraint createDateConstraint(int operatorType, String formula1, String formula2,String dateFormat); | |||||
DataValidationConstraint createTimeConstraint(int operatorType, String formula1, String formula2); | |||||
DataValidationConstraint createCustomConstraint(String formula); | |||||
DataValidation createValidation(DataValidationConstraint constraint,CellRangeAddressList cellRangeAddressList); | |||||
} |
* @return the {@link CellRange} of cells affected by this change | * @return the {@link CellRange} of cells affected by this change | ||||
*/ | */ | ||||
CellRange<? extends Cell> removeArrayFormula(Cell cell); | CellRange<? extends Cell> removeArrayFormula(Cell cell); | ||||
public DataValidationHelper getDataValidationHelper(); | |||||
/** | |||||
* Creates a data validation object | |||||
* @param dataValidation The Data validation object settings | |||||
*/ | |||||
public void addValidationData(DataValidation dataValidation); | |||||
} | } |
/** | |||||
* | |||||
*/ | |||||
package org.apache.poi.xssf.usermodel; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import org.apache.poi.ss.usermodel.DataValidation; | |||||
import org.apache.poi.ss.usermodel.DataValidationConstraint; | |||||
import org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType; | |||||
import org.apache.poi.ss.util.CellRangeAddress; | |||||
import org.apache.poi.ss.util.CellRangeAddressList; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidation; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationErrorStyle; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationOperator; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationType; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationOperator.Enum; | |||||
/** | |||||
* @author <a href="rjankiraman@emptoris.com">Radhakrishnan J</a> | |||||
* | |||||
*/ | |||||
public class XSSFDataValidation implements DataValidation { | |||||
private CTDataValidation ctDdataValidation; | |||||
private XSSFDataValidationConstraint validationConstraint; | |||||
private CellRangeAddressList regions; | |||||
static Map<Integer,STDataValidationOperator.Enum> operatorTypeMappings = new HashMap<Integer,STDataValidationOperator.Enum>(); | |||||
static Map<STDataValidationOperator.Enum,Integer> operatorTypeReverseMappings = new HashMap<STDataValidationOperator.Enum,Integer>(); | |||||
static Map<Integer,STDataValidationType.Enum> validationTypeMappings = new HashMap<Integer,STDataValidationType.Enum>(); | |||||
static Map<STDataValidationType.Enum,Integer> validationTypeReverseMappings = new HashMap<STDataValidationType.Enum,Integer>(); | |||||
static Map<Integer,STDataValidationErrorStyle.Enum> errorStyleMappings = new HashMap<Integer,STDataValidationErrorStyle.Enum>(); | |||||
static { | |||||
errorStyleMappings.put(DataValidation.ErrorStyle.INFO, STDataValidationErrorStyle.INFORMATION); | |||||
errorStyleMappings.put(DataValidation.ErrorStyle.STOP, STDataValidationErrorStyle.STOP); | |||||
errorStyleMappings.put(DataValidation.ErrorStyle.WARNING, STDataValidationErrorStyle.WARNING); | |||||
} | |||||
static { | |||||
operatorTypeMappings.put(DataValidationConstraint.OperatorType.BETWEEN,STDataValidationOperator.BETWEEN); | |||||
operatorTypeMappings.put(DataValidationConstraint.OperatorType.NOT_BETWEEN,STDataValidationOperator.NOT_BETWEEN); | |||||
operatorTypeMappings.put(DataValidationConstraint.OperatorType.EQUAL,STDataValidationOperator.EQUAL); | |||||
operatorTypeMappings.put(DataValidationConstraint.OperatorType.NOT_EQUAL,STDataValidationOperator.NOT_EQUAL); | |||||
operatorTypeMappings.put(DataValidationConstraint.OperatorType.GREATER_THAN,STDataValidationOperator.GREATER_THAN); | |||||
operatorTypeMappings.put(DataValidationConstraint.OperatorType.GREATER_OR_EQUAL,STDataValidationOperator.GREATER_THAN_OR_EQUAL); | |||||
operatorTypeMappings.put(DataValidationConstraint.OperatorType.LESS_THAN,STDataValidationOperator.LESS_THAN); | |||||
operatorTypeMappings.put(DataValidationConstraint.OperatorType.LESS_OR_EQUAL,STDataValidationOperator.LESS_THAN_OR_EQUAL); | |||||
for( Map.Entry<Integer,STDataValidationOperator.Enum> entry : operatorTypeMappings.entrySet() ) { | |||||
operatorTypeReverseMappings.put(entry.getValue(),entry.getKey()); | |||||
} | |||||
} | |||||
static { | |||||
validationTypeMappings.put(DataValidationConstraint.ValidationType.FORMULA,STDataValidationType.CUSTOM); | |||||
validationTypeMappings.put(DataValidationConstraint.ValidationType.DATE,STDataValidationType.DATE); | |||||
validationTypeMappings.put(DataValidationConstraint.ValidationType.DECIMAL,STDataValidationType.DECIMAL); | |||||
validationTypeMappings.put(DataValidationConstraint.ValidationType.LIST,STDataValidationType.LIST); | |||||
validationTypeMappings.put(DataValidationConstraint.ValidationType.ANY,STDataValidationType.NONE); | |||||
validationTypeMappings.put(DataValidationConstraint.ValidationType.TEXT_LENGTH,STDataValidationType.TEXT_LENGTH); | |||||
validationTypeMappings.put(DataValidationConstraint.ValidationType.TIME,STDataValidationType.TIME); | |||||
validationTypeMappings.put(DataValidationConstraint.ValidationType.INTEGER,STDataValidationType.WHOLE); | |||||
for( Map.Entry<Integer,STDataValidationType.Enum> entry : validationTypeMappings.entrySet() ) { | |||||
validationTypeReverseMappings.put(entry.getValue(),entry.getKey()); | |||||
} | |||||
} | |||||
XSSFDataValidation(CellRangeAddressList regions,CTDataValidation ctDataValidation) { | |||||
super(); | |||||
this.validationConstraint = getConstraint(ctDataValidation); | |||||
this.ctDdataValidation = ctDataValidation; | |||||
this.regions = regions; | |||||
this.ctDdataValidation.setErrorStyle(STDataValidationErrorStyle.STOP); | |||||
this.ctDdataValidation.setAllowBlank(true); | |||||
} | |||||
public XSSFDataValidation(XSSFDataValidationConstraint constraint,CellRangeAddressList regions,CTDataValidation ctDataValidation) { | |||||
super(); | |||||
this.validationConstraint = constraint; | |||||
this.ctDdataValidation = ctDataValidation; | |||||
this.regions = regions; | |||||
this.ctDdataValidation.setErrorStyle(STDataValidationErrorStyle.STOP); | |||||
this.ctDdataValidation.setAllowBlank(true); | |||||
} | |||||
CTDataValidation getCtDdataValidation() { | |||||
return ctDdataValidation; | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#createErrorBox(java.lang.String, java.lang.String) | |||||
*/ | |||||
public void createErrorBox(String title, String text) { | |||||
ctDdataValidation.setErrorTitle(title); | |||||
ctDdataValidation.setError(text); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#createPromptBox(java.lang.String, java.lang.String) | |||||
*/ | |||||
public void createPromptBox(String title, String text) { | |||||
ctDdataValidation.setPromptTitle(title); | |||||
ctDdataValidation.setPrompt(text); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#getEmptyCellAllowed() | |||||
*/ | |||||
public boolean getEmptyCellAllowed() { | |||||
return ctDdataValidation.getAllowBlank(); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#getErrorBoxText() | |||||
*/ | |||||
public String getErrorBoxText() { | |||||
return ctDdataValidation.getError(); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#getErrorBoxTitle() | |||||
*/ | |||||
public String getErrorBoxTitle() { | |||||
return ctDdataValidation.getErrorTitle(); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#getErrorStyle() | |||||
*/ | |||||
public int getErrorStyle() { | |||||
return ctDdataValidation.getErrorStyle().intValue(); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#getPromptBoxText() | |||||
*/ | |||||
public String getPromptBoxText() { | |||||
return ctDdataValidation.getPrompt(); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#getPromptBoxTitle() | |||||
*/ | |||||
public String getPromptBoxTitle() { | |||||
return ctDdataValidation.getPromptTitle(); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#getShowErrorBox() | |||||
*/ | |||||
public boolean getShowErrorBox() { | |||||
return ctDdataValidation.getShowErrorMessage(); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#getShowPromptBox() | |||||
*/ | |||||
public boolean getShowPromptBox() { | |||||
return ctDdataValidation.getShowInputMessage(); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#getSuppressDropDownArrow() | |||||
*/ | |||||
public boolean getSuppressDropDownArrow() { | |||||
return !ctDdataValidation.getShowDropDown(); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#getValidationConstraint() | |||||
*/ | |||||
public DataValidationConstraint getValidationConstraint() { | |||||
return validationConstraint; | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#setEmptyCellAllowed(boolean) | |||||
*/ | |||||
public void setEmptyCellAllowed(boolean allowed) { | |||||
ctDdataValidation.setAllowBlank(allowed); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#setErrorStyle(int) | |||||
*/ | |||||
public void setErrorStyle(int errorStyle) { | |||||
ctDdataValidation.setErrorStyle(errorStyleMappings.get(errorStyle)); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#setShowErrorBox(boolean) | |||||
*/ | |||||
public void setShowErrorBox(boolean show) { | |||||
ctDdataValidation.setShowErrorMessage(show); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#setShowPromptBox(boolean) | |||||
*/ | |||||
public void setShowPromptBox(boolean show) { | |||||
ctDdataValidation.setShowInputMessage(show); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidation#setSuppressDropDownArrow(boolean) | |||||
*/ | |||||
public void setSuppressDropDownArrow(boolean suppress) { | |||||
if (validationConstraint.getValidationType()==ValidationType.LIST) { | |||||
ctDdataValidation.setShowDropDown(!suppress); | |||||
} | |||||
} | |||||
public CellRangeAddressList getRegions() { | |||||
return regions; | |||||
} | |||||
public String prettyPrint() { | |||||
StringBuilder builder = new StringBuilder(); | |||||
for(CellRangeAddress address : regions.getCellRangeAddresses()) { | |||||
builder.append(address.formatAsString()); | |||||
} | |||||
builder.append(" => "); | |||||
builder.append(this.validationConstraint.prettyPrint()); | |||||
return builder.toString(); | |||||
} | |||||
private XSSFDataValidationConstraint getConstraint(CTDataValidation ctDataValidation) { | |||||
XSSFDataValidationConstraint constraint = null; | |||||
String formula1 = ctDataValidation.getFormula1(); | |||||
String formula2 = ctDataValidation.getFormula2(); | |||||
Enum operator = ctDataValidation.getOperator(); | |||||
org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationType.Enum type = ctDataValidation.getType(); | |||||
Integer validationType = XSSFDataValidation.validationTypeReverseMappings.get(type); | |||||
Integer operatorType = XSSFDataValidation.operatorTypeReverseMappings.get(operator); | |||||
constraint = new XSSFDataValidationConstraint(validationType,operatorType, formula1,formula2); | |||||
return constraint; | |||||
} | |||||
} |
/** | |||||
* | |||||
*/ | |||||
package org.apache.poi.xssf.usermodel; | |||||
import java.util.Arrays; | |||||
import org.apache.poi.ss.usermodel.DataValidationConstraint; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationType; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationOperator.Enum; | |||||
/** | |||||
* @author <a href="rjankiraman@emptoris.com">Radhakrishnan J</a> | |||||
* | |||||
*/ | |||||
public class XSSFDataValidationConstraint implements DataValidationConstraint { | |||||
private String formula1; | |||||
private String formula2; | |||||
private int validationType = -1; | |||||
private int operator = -1; | |||||
private String[] explicitListOfValues; | |||||
public XSSFDataValidationConstraint(String[] explicitListOfValues) { | |||||
if( explicitListOfValues==null || explicitListOfValues.length==0) { | |||||
throw new IllegalArgumentException("List validation with explicit values must specify at least one value"); | |||||
} | |||||
this.validationType = ValidationType.LIST; | |||||
setExplicitListValues(explicitListOfValues); | |||||
validate(); | |||||
} | |||||
public XSSFDataValidationConstraint(int validationType,String formula1) { | |||||
super(); | |||||
setFormula1(formula1); | |||||
this.validationType = validationType; | |||||
validate(); | |||||
} | |||||
public XSSFDataValidationConstraint(int validationType, int operator,String formula1) { | |||||
super(); | |||||
setFormula1(formula1); | |||||
this.validationType = validationType; | |||||
this.operator = operator; | |||||
validate(); | |||||
} | |||||
public XSSFDataValidationConstraint(int validationType, int operator,String formula1, String formula2) { | |||||
super(); | |||||
setFormula1(formula1); | |||||
setFormula2(formula2); | |||||
this.validationType = validationType; | |||||
this.operator = operator; | |||||
validate(); | |||||
//FIXME: Need to confirm if this is not a formula. | |||||
if( ValidationType.LIST==validationType) { | |||||
explicitListOfValues = formula1.split(","); | |||||
} | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationConstraint#getExplicitListValues() | |||||
*/ | |||||
public String[] getExplicitListValues() { | |||||
return explicitListOfValues; | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationConstraint#getFormula1() | |||||
*/ | |||||
public String getFormula1() { | |||||
return formula1; | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationConstraint#getFormula2() | |||||
*/ | |||||
public String getFormula2() { | |||||
return formula2; | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationConstraint#getOperator() | |||||
*/ | |||||
public int getOperator() { | |||||
return operator; | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationConstraint#getValidationType() | |||||
*/ | |||||
public int getValidationType() { | |||||
return validationType; | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationConstraint#setExplicitListValues(java.lang.String[]) | |||||
*/ | |||||
public void setExplicitListValues(String[] explicitListValues) { | |||||
this.explicitListOfValues = explicitListValues; | |||||
if( explicitListOfValues!=null && explicitListOfValues.length > 0 ) { | |||||
StringBuilder builder = new StringBuilder("\""); | |||||
for (int i = 0; i < explicitListValues.length; i++) { | |||||
String string = explicitListValues[i]; | |||||
if( builder.length() > 1) { | |||||
builder.append(","); | |||||
} | |||||
builder.append(string); | |||||
} | |||||
builder.append("\""); | |||||
setFormula1(builder.toString()); | |||||
} | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationConstraint#setFormula1(java.lang.String) | |||||
*/ | |||||
public void setFormula1(String formula1) { | |||||
this.formula1 = removeLeadingEquals(formula1); | |||||
} | |||||
protected String removeLeadingEquals(String formula1) { | |||||
return isFormulaEmpty(formula1) ? formula1 : formula1.charAt(0)=='=' ? formula1.substring(1) : formula1; | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationConstraint#setFormula2(java.lang.String) | |||||
*/ | |||||
public void setFormula2(String formula2) { | |||||
this.formula2 = removeLeadingEquals(formula2); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationConstraint#setOperator(int) | |||||
*/ | |||||
public void setOperator(int operator) { | |||||
this.operator = operator; | |||||
} | |||||
public void validate() { | |||||
if (validationType==ValidationType.ANY) { | |||||
return; | |||||
} | |||||
if (validationType==ValidationType.LIST ) { | |||||
if (isFormulaEmpty(formula1)) { | |||||
throw new IllegalArgumentException("A valid formula or a list of values must be specified for list validation."); | |||||
} | |||||
} else { | |||||
if( isFormulaEmpty(formula1) ) { | |||||
throw new IllegalArgumentException("Formula is not specified. Formula is required for all validation types except explicit list validation."); | |||||
} | |||||
if( validationType!= ValidationType.FORMULA ) { | |||||
if (operator==-1) { | |||||
throw new IllegalArgumentException("This validation type requires an operator to be specified."); | |||||
} else if (( operator==OperatorType.BETWEEN || operator==OperatorType.NOT_BETWEEN) && isFormulaEmpty(formula2)) { | |||||
throw new IllegalArgumentException("Between and not between comparisons require two formulae to be specified."); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
protected boolean isFormulaEmpty(String formula1) { | |||||
return formula1 == null || formula1.trim().length()==0; | |||||
} | |||||
public String prettyPrint() { | |||||
StringBuilder builder = new StringBuilder(); | |||||
STDataValidationType.Enum vt = XSSFDataValidation.validationTypeMappings.get(validationType); | |||||
Enum ot = XSSFDataValidation.operatorTypeMappings.get(operator); | |||||
builder.append(vt); | |||||
builder.append(' '); | |||||
if (validationType!=ValidationType.ANY) { | |||||
if (validationType != ValidationType.LIST && validationType != ValidationType.ANY && validationType != ValidationType.FORMULA) { | |||||
builder.append(",").append(ot).append(", "); | |||||
} | |||||
final String QUOTE = ""; | |||||
if (validationType == ValidationType.LIST && explicitListOfValues != null) { | |||||
builder.append(QUOTE).append(Arrays.asList(explicitListOfValues)).append(QUOTE).append(' '); | |||||
} else { | |||||
builder.append(QUOTE).append(formula1).append(QUOTE).append(' '); | |||||
} | |||||
if (formula2 != null) { | |||||
builder.append(QUOTE).append(formula2).append(QUOTE).append(' '); | |||||
} | |||||
} | |||||
return builder.toString(); | |||||
} | |||||
} |
/** | |||||
* | |||||
*/ | |||||
package org.apache.poi.xssf.usermodel; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import org.apache.poi.ss.usermodel.DataValidation; | |||||
import org.apache.poi.ss.usermodel.DataValidationConstraint; | |||||
import org.apache.poi.ss.usermodel.DataValidationHelper; | |||||
import org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType; | |||||
import org.apache.poi.ss.util.CellRangeAddress; | |||||
import org.apache.poi.ss.util.CellRangeAddressList; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidation; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STDataValidationType; | |||||
/** | |||||
* @author <a href="rjankiraman@emptoris.com">Radhakrishnan J</a> | |||||
* | |||||
*/ | |||||
public class XSSFDataValidationHelper implements DataValidationHelper { | |||||
private XSSFSheet xssfSheet; | |||||
public XSSFDataValidationHelper(XSSFSheet xssfSheet) { | |||||
super(); | |||||
this.xssfSheet = xssfSheet; | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationHelper#createDateConstraint(int, java.lang.String, java.lang.String, java.lang.String) | |||||
*/ | |||||
public DataValidationConstraint createDateConstraint(int operatorType, String formula1, String formula2, String dateFormat) { | |||||
return new XSSFDataValidationConstraint(ValidationType.DATE, operatorType,formula1, formula2); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationHelper#createDecimalConstraint(int, java.lang.String, java.lang.String) | |||||
*/ | |||||
public DataValidationConstraint createDecimalConstraint(int operatorType, String formula1, String formula2) { | |||||
return new XSSFDataValidationConstraint(ValidationType.DECIMAL, operatorType,formula1, formula2); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationHelper#createExplicitListConstraint(java.lang.String[]) | |||||
*/ | |||||
public DataValidationConstraint createExplicitListConstraint(String[] listOfValues) { | |||||
return new XSSFDataValidationConstraint(listOfValues); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationHelper#createFormulaListConstraint(java.lang.String) | |||||
*/ | |||||
public DataValidationConstraint createFormulaListConstraint(String listFormula) { | |||||
return new XSSFDataValidationConstraint(ValidationType.LIST, listFormula); | |||||
} | |||||
public DataValidationConstraint createNumericConstraint(int validationType, int operatorType, String formula1, String formula2) { | |||||
if( validationType==ValidationType.INTEGER) { | |||||
return createIntegerConstraint(operatorType, formula1, formula2); | |||||
} else if ( validationType==ValidationType.DECIMAL) { | |||||
return createDecimalConstraint(operatorType, formula1, formula2); | |||||
} else if ( validationType==ValidationType.TEXT_LENGTH) { | |||||
return createTextLengthConstraint(operatorType, formula1, formula2); | |||||
} | |||||
return null; | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationHelper#createIntegerConstraint(int, java.lang.String, java.lang.String) | |||||
*/ | |||||
public DataValidationConstraint createIntegerConstraint(int operatorType, String formula1, String formula2) { | |||||
return new XSSFDataValidationConstraint(ValidationType.INTEGER, operatorType,formula1,formula2); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationHelper#createTextLengthConstraint(int, java.lang.String, java.lang.String) | |||||
*/ | |||||
public DataValidationConstraint createTextLengthConstraint(int operatorType, String formula1, String formula2) { | |||||
return new XSSFDataValidationConstraint(ValidationType.TEXT_LENGTH, operatorType,formula1,formula2); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationHelper#createTimeConstraint(int, java.lang.String, java.lang.String, java.lang.String) | |||||
*/ | |||||
public DataValidationConstraint createTimeConstraint(int operatorType, String formula1, String formula2) { | |||||
return new XSSFDataValidationConstraint(ValidationType.TIME, operatorType,formula1,formula2); | |||||
} | |||||
public DataValidationConstraint createCustomConstraint(String formula) { | |||||
return new XSSFDataValidationConstraint(ValidationType.FORMULA, formula); | |||||
} | |||||
/* (non-Javadoc) | |||||
* @see org.apache.poi.ss.usermodel.DataValidationHelper#createValidation(org.apache.poi.ss.usermodel.DataValidationConstraint, org.apache.poi.ss.util.CellRangeAddressList) | |||||
*/ | |||||
public DataValidation createValidation(DataValidationConstraint constraint, CellRangeAddressList cellRangeAddressList) { | |||||
XSSFDataValidationConstraint dataValidationConstraint = (XSSFDataValidationConstraint)constraint; | |||||
CTDataValidation newDataValidation = CTDataValidation.Factory.newInstance(); | |||||
int validationType = constraint.getValidationType(); | |||||
switch(validationType) { | |||||
case DataValidationConstraint.ValidationType.LIST: | |||||
newDataValidation.setType(STDataValidationType.LIST); | |||||
newDataValidation.setFormula1(constraint.getFormula1()); | |||||
break; | |||||
case DataValidationConstraint.ValidationType.ANY: | |||||
newDataValidation.setType(STDataValidationType.NONE); | |||||
break; | |||||
case DataValidationConstraint.ValidationType.TEXT_LENGTH: | |||||
newDataValidation.setType(STDataValidationType.TEXT_LENGTH); | |||||
break; | |||||
case DataValidationConstraint.ValidationType.DATE: | |||||
newDataValidation.setType(STDataValidationType.DATE); | |||||
break; | |||||
case DataValidationConstraint.ValidationType.INTEGER: | |||||
newDataValidation.setType(STDataValidationType.WHOLE); | |||||
break; | |||||
case DataValidationConstraint.ValidationType.DECIMAL: | |||||
newDataValidation.setType(STDataValidationType.DECIMAL); | |||||
break; | |||||
case DataValidationConstraint.ValidationType.TIME: | |||||
newDataValidation.setType(STDataValidationType.TIME); | |||||
break; | |||||
case DataValidationConstraint.ValidationType.FORMULA: | |||||
newDataValidation.setType(STDataValidationType.CUSTOM); | |||||
break; | |||||
default: | |||||
newDataValidation.setType(STDataValidationType.NONE); | |||||
} | |||||
if (validationType!=ValidationType.ANY && validationType!=ValidationType.LIST) { | |||||
newDataValidation.setOperator(XSSFDataValidation.operatorTypeMappings.get(constraint.getOperator())); | |||||
if (constraint.getFormula1() != null) { | |||||
newDataValidation.setFormula1(constraint.getFormula1()); | |||||
} | |||||
if (constraint.getFormula2() != null) { | |||||
newDataValidation.setFormula2(constraint.getFormula2()); | |||||
} | |||||
} | |||||
CellRangeAddress[] cellRangeAddresses = cellRangeAddressList.getCellRangeAddresses(); | |||||
List<String> sqref = new ArrayList<String>(); | |||||
for (int i = 0; i < cellRangeAddresses.length; i++) { | |||||
CellRangeAddress cellRangeAddress = cellRangeAddresses[i]; | |||||
sqref.add(cellRangeAddress.formatAsString()); | |||||
} | |||||
newDataValidation.setSqref(sqref); | |||||
return new XSSFDataValidation(dataValidationConstraint,cellRangeAddressList,newDataValidation); | |||||
} | |||||
} |
import org.apache.poi.ss.usermodel.Cell; | import org.apache.poi.ss.usermodel.Cell; | ||||
import org.apache.poi.ss.usermodel.CellRange; | import org.apache.poi.ss.usermodel.CellRange; | ||||
import org.apache.poi.ss.usermodel.CellStyle; | import org.apache.poi.ss.usermodel.CellStyle; | ||||
import org.apache.poi.ss.usermodel.DataValidation; | |||||
import org.apache.poi.ss.usermodel.DataValidationHelper; | |||||
import org.apache.poi.ss.usermodel.Footer; | import org.apache.poi.ss.usermodel.Footer; | ||||
import org.apache.poi.ss.usermodel.Header; | import org.apache.poi.ss.usermodel.Header; | ||||
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; | ||||
import org.apache.poi.ss.util.CellRangeAddressList; | |||||
import org.apache.poi.ss.util.CellReference; | import org.apache.poi.ss.util.CellReference; | ||||
import org.apache.poi.ss.util.SSCellRange; | import org.apache.poi.ss.util.SSCellRange; | ||||
import org.apache.poi.util.Internal; | import org.apache.poi.util.Internal; | ||||
import org.apache.xmlbeans.XmlException; | import org.apache.xmlbeans.XmlException; | ||||
import org.apache.xmlbeans.XmlOptions; | import org.apache.xmlbeans.XmlOptions; | ||||
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; | import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; | ||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBreak; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCellFormula; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCommentList; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidation; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDataValidations; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDrawing; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHeaderFooter; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTLegacyDrawing; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCell; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTMergeCells; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTOutlinePr; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageBreak; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageMargins; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPageSetUpPr; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPane; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPrintOptions; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSelection; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheet; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetPr; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetProtection; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetView; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetViews; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STCellFormulaType; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPaneState; | |||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorksheetDocument; | |||||
/** | /** | ||||
* High level representation of a SpreadsheetML worksheet. | * High level representation of a SpreadsheetML worksheet. | ||||
private CommentsTable sheetComments; | private CommentsTable sheetComments; | ||||
private Map<Integer, XSSFCell> sharedFormulas; | private Map<Integer, XSSFCell> sharedFormulas; | ||||
private List<CellRangeAddress> arrayFormulas; | private List<CellRangeAddress> arrayFormulas; | ||||
private XSSFDataValidationHelper dataValidationHelper; | |||||
/** | /** | ||||
* Creates new XSSFSheet - called by XSSFWorkbook to create a sheet from scratch. | * Creates new XSSFSheet - called by XSSFWorkbook to create a sheet from scratch. | ||||
*/ | */ | ||||
protected XSSFSheet() { | protected XSSFSheet() { | ||||
super(); | super(); | ||||
dataValidationHelper = new XSSFDataValidationHelper(this); | |||||
onDocumentCreate(); | onDocumentCreate(); | ||||
} | } | ||||
*/ | */ | ||||
protected XSSFSheet(PackagePart part, PackageRelationship rel) { | protected XSSFSheet(PackagePart part, PackageRelationship rel) { | ||||
super(part, rel); | super(part, rel); | ||||
dataValidationHelper = new XSSFDataValidationHelper(this); | |||||
} | } | ||||
/** | /** | ||||
String ref = ((XSSFCell)cell).getCTCell().getR(); | String ref = ((XSSFCell)cell).getCTCell().getR(); | ||||
throw new IllegalArgumentException("Cell " + ref + " is not part of an array formula."); | throw new IllegalArgumentException("Cell " + ref + " is not part of an array formula."); | ||||
} | } | ||||
public DataValidationHelper getDataValidationHelper() { | |||||
return dataValidationHelper; | |||||
} | |||||
public List<XSSFDataValidation> getDataValidations() { | |||||
List<XSSFDataValidation> xssfValidations = new ArrayList<XSSFDataValidation>(); | |||||
CTDataValidations dataValidations = this.worksheet.getDataValidations(); | |||||
if( dataValidations!=null && dataValidations.getCount() > 0 ) { | |||||
CTDataValidation[] dataValidationList = dataValidations.getDataValidationArray(); | |||||
for (CTDataValidation ctDataValidation : dataValidationList) { | |||||
CellRangeAddressList addressList = new CellRangeAddressList(); | |||||
@SuppressWarnings("unchecked") | |||||
List<String> sqref = ctDataValidation.getSqref(); | |||||
for (String stRef : sqref) { | |||||
String[] regions = stRef.split(" "); | |||||
for (int i = 0; i < regions.length; i++) { | |||||
String[] parts = regions[i].split(":"); | |||||
CellReference begin = new CellReference(parts[0]); | |||||
CellReference end = parts.length > 1 ? new CellReference(parts[1]) : begin; | |||||
CellRangeAddress cellRangeAddress = new CellRangeAddress(begin.getRow(), end.getRow(), begin.getCol(), end.getCol()); | |||||
addressList.addCellRangeAddress(cellRangeAddress); | |||||
} | |||||
} | |||||
XSSFDataValidation xssfDataValidation = new XSSFDataValidation(addressList, ctDataValidation); | |||||
xssfValidations.add(xssfDataValidation); | |||||
} | |||||
} | |||||
return xssfValidations; | |||||
} | |||||
public void addValidationData(DataValidation dataValidation) { | |||||
XSSFDataValidation xssfDataValidation = (XSSFDataValidation)dataValidation; | |||||
CTDataValidations dataValidations = worksheet.getDataValidations(); | |||||
if( dataValidations==null ) { | |||||
dataValidations = worksheet.addNewDataValidations(); | |||||
} | |||||
int currentCount = dataValidations.getDataValidationArray().length; | |||||
CTDataValidation newval = dataValidations.addNewDataValidation(); | |||||
newval.set(xssfDataValidation.getCtDdataValidation()); | |||||
dataValidations.setCount(currentCount + 1); | |||||
} | |||||
} | } |
/* ==================================================================== | |||||
Licensed to the Apache Software Foundation (ASF) under one or more | |||||
contributor license agreements. See the NOTICE file distributed with | |||||
this work for additional information regarding copyright ownership. | |||||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
(the "License"); you may not use this file except in compliance with | |||||
the License. You may obtain a copy of the License at | |||||
http://www.apache.org/licenses/LICENSE-2.0 | |||||
Unless required by applicable law or agreed to in writing, software | |||||
distributed under the License is distributed on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
See the License for the specific language governing permissions and | |||||
limitations under the License. | |||||
==================================================================== */ | |||||
package org.apache.poi.xssf.usermodel; | |||||
import java.math.BigDecimal; | |||||
import java.util.List; | |||||
import org.apache.poi.ss.usermodel.*; | |||||
import org.apache.poi.ss.usermodel.DataValidationConstraint.OperatorType; | |||||
import org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType; | |||||
import org.apache.poi.ss.util.CellRangeAddress; | |||||
import org.apache.poi.ss.util.CellRangeAddressList; | |||||
import org.apache.poi.ss.util.CellReference; | |||||
import org.apache.poi.xssf.XSSFITestDataProvider; | |||||
import org.apache.poi.xssf.XSSFTestDataSamples; | |||||
public class TestXSSFDataValidation extends BaseTestDataValidation { | |||||
public TestXSSFDataValidation(){ | |||||
super(XSSFITestDataProvider.instance); | |||||
} | |||||
public void testAddValidations() throws Exception { | |||||
XSSFWorkbook workbook = XSSFTestDataSamples.openSampleWorkbook("DataValidations-49244.xlsx"); | |||||
Sheet sheet = workbook.getSheetAt(0); | |||||
List<XSSFDataValidation> dataValidations = ((XSSFSheet)sheet).getDataValidations(); | |||||
/** | |||||
* For each validation type, there are two cells with the same validation. This tests | |||||
* application of a single validation definition to multiple cells. | |||||
* | |||||
* For list ( 3 validations for explicit and 3 for formula ) | |||||
* - one validation that allows blank. | |||||
* - one that does not allow blank. | |||||
* - one that does not show the drop down arrow. | |||||
* = 2 | |||||
* | |||||
* For number validations ( integer/decimal and text length ) with 8 different types of operators. | |||||
* = 50 | |||||
* | |||||
* = 52 ( Total ) | |||||
*/ | |||||
assertEquals(52,dataValidations.size()); | |||||
DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper(); | |||||
int[] validationTypes = new int[]{ValidationType.INTEGER,ValidationType.DECIMAL,ValidationType.TEXT_LENGTH}; | |||||
int[] singleOperandOperatorTypes = new int[]{ | |||||
OperatorType.LESS_THAN,OperatorType.LESS_OR_EQUAL, | |||||
OperatorType.GREATER_THAN,OperatorType.GREATER_OR_EQUAL, | |||||
OperatorType.EQUAL,OperatorType.NOT_EQUAL | |||||
} ; | |||||
int[] doubleOperandOperatorTypes = new int[]{ | |||||
OperatorType.BETWEEN,OperatorType.NOT_BETWEEN | |||||
}; | |||||
BigDecimal value = new BigDecimal("10"),value2 = new BigDecimal("20"); | |||||
BigDecimal dvalue = new BigDecimal("10.001"),dvalue2 = new BigDecimal("19.999"); | |||||
final int lastRow = sheet.getLastRowNum(); | |||||
int offset = lastRow + 3; | |||||
int lastKnownNumValidations = dataValidations.size(); | |||||
Row row = sheet.createRow(offset++); | |||||
Cell cell = row.createCell(0); | |||||
DataValidationConstraint explicitListValidation = dataValidationHelper.createExplicitListConstraint(new String[]{"MA","MI","CA"}); | |||||
CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(); | |||||
cellRangeAddressList.addCellRangeAddress(cell.getRowIndex(), cell.getColumnIndex(), cell.getRowIndex(), cell.getColumnIndex()); | |||||
DataValidation dataValidation = dataValidationHelper.createValidation(explicitListValidation, cellRangeAddressList); | |||||
setOtherValidationParameters(dataValidation); | |||||
sheet.addValidationData(dataValidation); | |||||
lastKnownNumValidations++; | |||||
row = sheet.createRow(offset++); | |||||
cell = row.createCell(0); | |||||
cellRangeAddressList = new CellRangeAddressList(); | |||||
cellRangeAddressList.addCellRangeAddress(cell.getRowIndex(), cell.getColumnIndex(), cell.getRowIndex(), cell.getColumnIndex()); | |||||
Cell firstCell = row.createCell(1);firstCell.setCellValue("UT"); | |||||
Cell secondCell = row.createCell(2);secondCell.setCellValue("MN"); | |||||
Cell thirdCell = row.createCell(3);thirdCell.setCellValue("IL"); | |||||
int rowNum = row.getRowNum() + 1; | |||||
String listFormula = new StringBuilder("$B$").append(rowNum).append(":").append("$D$").append(rowNum).toString(); | |||||
DataValidationConstraint formulaListValidation = dataValidationHelper.createFormulaListConstraint(listFormula); | |||||
dataValidation = dataValidationHelper.createValidation(formulaListValidation, cellRangeAddressList); | |||||
setOtherValidationParameters(dataValidation); | |||||
sheet.addValidationData(dataValidation); | |||||
lastKnownNumValidations++; | |||||
offset++; | |||||
offset++; | |||||
for (int i = 0; i < validationTypes.length; i++) { | |||||
int validationType = validationTypes[i]; | |||||
offset = offset + 2; | |||||
final Row row0 = sheet.createRow(offset++); | |||||
Cell cell_10 = row0.createCell(0); | |||||
cell_10.setCellValue(validationType==ValidationType.DECIMAL ? "Decimal " : validationType==ValidationType.INTEGER ? "Integer" : "Text Length"); | |||||
offset++; | |||||
for (int j = 0; j < singleOperandOperatorTypes.length; j++) { | |||||
int operatorType = singleOperandOperatorTypes[j]; | |||||
final Row row1 = sheet.createRow(offset++); | |||||
//For Integer (> and >=) we add 1 extra cell for validations whose formulae reference other cells. | |||||
final Row row2 = i==0 && j < 2 ? sheet.createRow(offset++) : null; | |||||
cell_10 = row1.createCell(0); | |||||
cell_10.setCellValue(XSSFDataValidation.operatorTypeMappings.get(operatorType).toString()); | |||||
Cell cell_11 = row1.createCell(1); | |||||
Cell cell_21 = row1.createCell(2); | |||||
Cell cell_22 = i==0 && j < 2 ? row2.createCell(2) : null; | |||||
Cell cell_13 = row1.createCell(3); | |||||
cell_13.setCellType(Cell.CELL_TYPE_NUMERIC); | |||||
cell_13.setCellValue(validationType==ValidationType.DECIMAL ? dvalue.doubleValue() : value.intValue()); | |||||
//First create value based validation; | |||||
DataValidationConstraint constraint = dataValidationHelper.createNumericConstraint(validationType,operatorType, value.toString(), null); | |||||
cellRangeAddressList = new CellRangeAddressList(); | |||||
cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_11.getRowIndex(),cell_11.getRowIndex(),cell_11.getColumnIndex(),cell_11.getColumnIndex())); | |||||
DataValidation validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); | |||||
setOtherValidationParameters(validation); | |||||
sheet.addValidationData(validation); | |||||
assertEquals(++lastKnownNumValidations,((XSSFSheet)sheet).getDataValidations().size()); | |||||
//Now create real formula based validation. | |||||
String formula1 = new CellReference(cell_13.getRowIndex(),cell_13.getColumnIndex()).formatAsString(); | |||||
constraint = dataValidationHelper.createNumericConstraint(validationType,operatorType, formula1, null); | |||||
if (i==0 && j==0) { | |||||
cellRangeAddressList = new CellRangeAddressList(); | |||||
cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_21.getRowIndex(), cell_21.getRowIndex(), cell_21.getColumnIndex(), cell_21.getColumnIndex())); | |||||
validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); | |||||
setOtherValidationParameters(validation); | |||||
sheet.addValidationData(validation); | |||||
assertEquals(++lastKnownNumValidations, ((XSSFSheet) sheet).getDataValidations().size()); | |||||
cellRangeAddressList = new CellRangeAddressList(); | |||||
cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_22.getRowIndex(), cell_22.getRowIndex(), cell_22.getColumnIndex(), cell_22.getColumnIndex())); | |||||
validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); | |||||
setOtherValidationParameters( validation); | |||||
sheet.addValidationData(validation); | |||||
assertEquals(++lastKnownNumValidations, ((XSSFSheet) sheet).getDataValidations().size()); | |||||
} else if(i==0 && j==1 ){ | |||||
cellRangeAddressList = new CellRangeAddressList(); | |||||
cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_21.getRowIndex(), cell_21.getRowIndex(), cell_21.getColumnIndex(), cell_21.getColumnIndex())); | |||||
cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_22.getRowIndex(), cell_22.getRowIndex(), cell_22.getColumnIndex(), cell_22.getColumnIndex())); | |||||
validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); | |||||
setOtherValidationParameters( validation); | |||||
sheet.addValidationData(validation); | |||||
assertEquals(++lastKnownNumValidations, ((XSSFSheet) sheet).getDataValidations().size()); | |||||
} else { | |||||
cellRangeAddressList = new CellRangeAddressList(); | |||||
cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_21.getRowIndex(), cell_21.getRowIndex(), cell_21.getColumnIndex(), cell_21.getColumnIndex())); | |||||
validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); | |||||
setOtherValidationParameters(validation); | |||||
sheet.addValidationData(validation); | |||||
assertEquals(++lastKnownNumValidations, ((XSSFSheet) sheet).getDataValidations().size()); | |||||
} | |||||
} | |||||
for (int j = 0; j < doubleOperandOperatorTypes.length; j++) { | |||||
int operatorType = doubleOperandOperatorTypes[j]; | |||||
final Row row1 = sheet.createRow(offset++); | |||||
cell_10 = row1.createCell(0); | |||||
cell_10.setCellValue(XSSFDataValidation.operatorTypeMappings.get(operatorType).toString()); | |||||
Cell cell_11 = row1.createCell(1); | |||||
Cell cell_21 = row1.createCell(2); | |||||
Cell cell_13 = row1.createCell(3); | |||||
Cell cell_14 = row1.createCell(4); | |||||
String value1String = validationType==ValidationType.DECIMAL ? dvalue.toString() : value.toString(); | |||||
cell_13.setCellType(Cell.CELL_TYPE_NUMERIC); | |||||
cell_13.setCellValue(validationType==ValidationType.DECIMAL ? dvalue.doubleValue() : value.intValue()); | |||||
String value2String = validationType==ValidationType.DECIMAL ? dvalue2.toString() : value2.toString(); | |||||
cell_14.setCellType(Cell.CELL_TYPE_NUMERIC); | |||||
cell_14.setCellValue(validationType==ValidationType.DECIMAL ? dvalue2.doubleValue() : value2.intValue()); | |||||
//First create value based validation; | |||||
DataValidationConstraint constraint = dataValidationHelper.createNumericConstraint(validationType,operatorType, value1String, value2String); | |||||
cellRangeAddressList = new CellRangeAddressList(); | |||||
cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_11.getRowIndex(),cell_11.getRowIndex(),cell_11.getColumnIndex(),cell_11.getColumnIndex())); | |||||
DataValidation validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); | |||||
setOtherValidationParameters(validation); | |||||
sheet.addValidationData(validation); | |||||
assertEquals(++lastKnownNumValidations,((XSSFSheet)sheet).getDataValidations().size()); | |||||
//Now create real formula based validation. | |||||
String formula1 = new CellReference(cell_13.getRowIndex(),cell_13.getColumnIndex()).formatAsString(); | |||||
String formula2 = new CellReference(cell_14.getRowIndex(),cell_14.getColumnIndex()).formatAsString(); | |||||
constraint = dataValidationHelper.createNumericConstraint(validationType,operatorType, formula1, formula2); | |||||
cellRangeAddressList = new CellRangeAddressList(); | |||||
cellRangeAddressList.addCellRangeAddress(new CellRangeAddress(cell_21.getRowIndex(),cell_21.getRowIndex(),cell_21.getColumnIndex(),cell_21.getColumnIndex())); | |||||
validation = dataValidationHelper.createValidation(constraint, cellRangeAddressList); | |||||
setOtherValidationParameters(validation); | |||||
sheet.addValidationData(validation); | |||||
assertEquals(++lastKnownNumValidations,((XSSFSheet)sheet).getDataValidations().size()); | |||||
} | |||||
} | |||||
workbook = XSSFTestDataSamples.writeOutAndReadBack(workbook); | |||||
Sheet sheetAt = workbook.getSheetAt(0); | |||||
assertEquals(lastKnownNumValidations,((XSSFSheet)sheetAt).getDataValidations().size()); | |||||
} | |||||
protected void setOtherValidationParameters(DataValidation validation) { | |||||
boolean yesNo = true; | |||||
validation.setEmptyCellAllowed(yesNo); | |||||
validation.setShowErrorBox(yesNo); | |||||
validation.setShowPromptBox(yesNo); | |||||
validation.createErrorBox("Error Message Title", "Error Message"); | |||||
validation.createPromptBox("Prompt", "Enter some value"); | |||||
validation.setSuppressDropDownArrow(yesNo); | |||||
} | |||||
} |
import junit.framework.AssertionFailedError; | import junit.framework.AssertionFailedError; | ||||
import junit.framework.TestCase; | import junit.framework.TestCase; | ||||
import org.apache.poi.hssf.HSSFITestDataProvider; | |||||
import org.apache.poi.hssf.HSSFTestDataSamples; | import org.apache.poi.hssf.HSSFTestDataSamples; | ||||
import org.apache.poi.hssf.eventmodel.ERFListener; | import org.apache.poi.hssf.eventmodel.ERFListener; | ||||
import org.apache.poi.hssf.eventmodel.EventRecordFactory; | import org.apache.poi.hssf.eventmodel.EventRecordFactory; | ||||
import org.apache.poi.hssf.record.RecordFormatException; | import org.apache.poi.hssf.record.RecordFormatException; | ||||
import org.apache.poi.hssf.util.HSSFColor; | import org.apache.poi.hssf.util.HSSFColor; | ||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem; | import org.apache.poi.poifs.filesystem.POIFSFileSystem; | ||||
import org.apache.poi.ss.usermodel.*; | |||||
import org.apache.poi.ss.util.CellRangeAddress; | import org.apache.poi.ss.util.CellRangeAddress; | ||||
import org.apache.poi.ss.util.CellRangeAddressList; | import org.apache.poi.ss.util.CellRangeAddressList; | ||||
* | * | ||||
* @author Dragos Buleandra ( dragos.buleandra@trade2b.ro ) | * @author Dragos Buleandra ( dragos.buleandra@trade2b.ro ) | ||||
*/ | */ | ||||
public final class TestDataValidation extends TestCase { | |||||
public final class TestDataValidation extends BaseTestDataValidation { | |||||
/** Convenient access to ERROR_STYLE constants */ | |||||
/*package*/ static final HSSFDataValidation.ErrorStyle ES = null; | |||||
/** Convenient access to OPERATOR constants */ | |||||
/*package*/ static final DVConstraint.ValidationType VT = null; | |||||
/** Convenient access to OPERATOR constants */ | |||||
/*package*/ static final DVConstraint.OperatorType OP = null; | |||||
public TestDataValidation(){ | |||||
super(HSSFITestDataProvider.instance); | |||||
} | |||||
private static void log(String msg) { | |||||
if (false) { // successful tests should be silent | |||||
System.out.println(msg); | |||||
} | |||||
} | |||||
private static final class ValidationAdder { | |||||
private final HSSFCellStyle _style_1; | |||||
private final HSSFCellStyle _style_2; | |||||
private final int _validationType; | |||||
private final HSSFSheet _sheet; | |||||
private int _currentRowIndex; | |||||
private final HSSFCellStyle _cellStyle; | |||||
public ValidationAdder(HSSFSheet fSheet, HSSFCellStyle style_1, HSSFCellStyle style_2, | |||||
HSSFCellStyle cellStyle, int validationType) { | |||||
_sheet = fSheet; | |||||
_style_1 = style_1; | |||||
_style_2 = style_2; | |||||
_cellStyle = cellStyle; | |||||
_validationType = validationType; | |||||
_currentRowIndex = fSheet.getPhysicalNumberOfRows(); | |||||
} | |||||
public void addValidation(int operatorType, String firstFormula, String secondFormula, | |||||
int errorStyle, String ruleDescr, String promptDescr, | |||||
boolean allowEmpty, boolean inputBox, boolean errorBox) { | |||||
String[] explicitListValues = null; | |||||
addValidationInternal(operatorType, firstFormula, secondFormula, errorStyle, ruleDescr, | |||||
promptDescr, allowEmpty, inputBox, errorBox, true, | |||||
explicitListValues); | |||||
} | |||||
private void addValidationInternal(int operatorType, String firstFormula, | |||||
String secondFormula, int errorStyle, String ruleDescr, String promptDescr, | |||||
boolean allowEmpty, boolean inputBox, boolean errorBox, boolean suppressDropDown, | |||||
String[] explicitListValues) { | |||||
int rowNum = _currentRowIndex++; | |||||
DVConstraint dc = createConstraint(operatorType, firstFormula, secondFormula, explicitListValues); | |||||
HSSFDataValidation dv = new HSSFDataValidation(new CellRangeAddressList(rowNum, rowNum, 0, 0), dc); | |||||
dv.setEmptyCellAllowed(allowEmpty); | |||||
dv.setErrorStyle(errorStyle); | |||||
dv.createErrorBox("Invalid Input", "Something is wrong - check condition!"); | |||||
dv.createPromptBox("Validated Cell", "Allowable values have been restricted"); | |||||
dv.setShowPromptBox(inputBox); | |||||
dv.setShowErrorBox(errorBox); | |||||
dv.setSuppressDropDownArrow(suppressDropDown); | |||||
_sheet.addValidationData(dv); | |||||
writeDataValidationSettings(_sheet, _style_1, _style_2, ruleDescr, allowEmpty, | |||||
inputBox, errorBox); | |||||
if (_cellStyle != null) { | |||||
HSSFRow row = _sheet.getRow(_sheet.getPhysicalNumberOfRows() - 1); | |||||
HSSFCell cell = row.createCell(0); | |||||
cell.setCellStyle(_cellStyle); | |||||
} | |||||
writeOtherSettings(_sheet, _style_1, promptDescr); | |||||
} | |||||
private DVConstraint createConstraint(int operatorType, String firstFormula, | |||||
String secondFormula, String[] explicitListValues) { | |||||
if (_validationType == VT.LIST) { | |||||
if (explicitListValues != null) { | |||||
return DVConstraint.createExplicitListConstraint(explicitListValues); | |||||
} | |||||
return DVConstraint.createFormulaListConstraint(firstFormula); | |||||
} | |||||
if (_validationType == VT.TIME) { | |||||
return DVConstraint.createTimeConstraint(operatorType, firstFormula, secondFormula); | |||||
} | |||||
if (_validationType == VT.DATE) { | |||||
return DVConstraint.createDateConstraint(operatorType, firstFormula, secondFormula, null); | |||||
} | |||||
if (_validationType == VT.FORMULA) { | |||||
return DVConstraint.createCustomFormulaConstraint(firstFormula); | |||||
} | |||||
return DVConstraint.createNumericConstraint(_validationType, operatorType, firstFormula, secondFormula); | |||||
} | |||||
/** | |||||
* writes plain text values into cells in a tabular format to form comments readable from within | |||||
* the spreadsheet. | |||||
*/ | |||||
private static void writeDataValidationSettings(HSSFSheet sheet, HSSFCellStyle style_1, | |||||
HSSFCellStyle style_2, String strCondition, boolean allowEmpty, boolean inputBox, | |||||
boolean errorBox) { | |||||
HSSFRow row = sheet.createRow(sheet.getPhysicalNumberOfRows()); | |||||
// condition's string | |||||
HSSFCell cell = row.createCell(1); | |||||
cell.setCellStyle(style_1); | |||||
setCellValue(cell, strCondition); | |||||
// allow empty cells | |||||
cell = row.createCell(2); | |||||
cell.setCellStyle(style_2); | |||||
setCellValue(cell, ((allowEmpty) ? "yes" : "no")); | |||||
// show input box | |||||
cell = row.createCell(3); | |||||
cell.setCellStyle(style_2); | |||||
setCellValue(cell, ((inputBox) ? "yes" : "no")); | |||||
// show error box | |||||
cell = row.createCell(4); | |||||
cell.setCellStyle(style_2); | |||||
setCellValue(cell, ((errorBox) ? "yes" : "no")); | |||||
} | |||||
private static void writeOtherSettings(HSSFSheet sheet, HSSFCellStyle style, | |||||
String strStettings) { | |||||
HSSFRow row = sheet.getRow(sheet.getPhysicalNumberOfRows() - 1); | |||||
HSSFCell cell = row.createCell(5); | |||||
cell.setCellStyle(style); | |||||
setCellValue(cell, strStettings); | |||||
} | |||||
public void addListValidation(String[] explicitListValues, String listFormula, String listValsDescr, | |||||
boolean allowEmpty, boolean suppressDropDown) { | |||||
String promptDescr = (allowEmpty ? "empty ok" : "not empty") | |||||
+ ", " + (suppressDropDown ? "no drop-down" : "drop-down"); | |||||
addValidationInternal(VT.LIST, listFormula, null, ES.STOP, listValsDescr, promptDescr, | |||||
allowEmpty, false, true, suppressDropDown, explicitListValues); | |||||
} | |||||
} | |||||
/** | |||||
* Manages the cell styles used for formatting the output spreadsheet | |||||
*/ | |||||
private static final class WorkbookFormatter { | |||||
private final HSSFWorkbook _wb; | |||||
private final HSSFCellStyle _style_1; | |||||
private final HSSFCellStyle _style_2; | |||||
private final HSSFCellStyle _style_3; | |||||
private final HSSFCellStyle _style_4; | |||||
private HSSFSheet _currentSheet; | |||||
public WorkbookFormatter(HSSFWorkbook wb) { | |||||
_wb = wb; | |||||
_style_1 = createStyle( wb, HSSFCellStyle.ALIGN_LEFT ); | |||||
_style_2 = createStyle( wb, HSSFCellStyle.ALIGN_CENTER ); | |||||
_style_3 = createStyle( wb, HSSFCellStyle.ALIGN_CENTER, HSSFColor.GREY_25_PERCENT.index, true ); | |||||
_style_4 = createHeaderStyle(wb); | |||||
} | |||||
private static HSSFCellStyle createStyle(HSSFWorkbook wb, short h_align, short color, | |||||
boolean bold) { | |||||
HSSFFont font = wb.createFont(); | |||||
if (bold) { | |||||
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); | |||||
} | |||||
HSSFCellStyle cellStyle = wb.createCellStyle(); | |||||
cellStyle.setFont(font); | |||||
cellStyle.setFillForegroundColor(color); | |||||
cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); | |||||
cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); | |||||
cellStyle.setAlignment(h_align); | |||||
cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); | |||||
cellStyle.setLeftBorderColor(HSSFColor.BLACK.index); | |||||
cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); | |||||
cellStyle.setTopBorderColor(HSSFColor.BLACK.index); | |||||
cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); | |||||
cellStyle.setRightBorderColor(HSSFColor.BLACK.index); | |||||
cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); | |||||
cellStyle.setBottomBorderColor(HSSFColor.BLACK.index); | |||||
return cellStyle; | |||||
} | |||||
private static HSSFCellStyle createStyle(HSSFWorkbook wb, short h_align) { | |||||
return createStyle(wb, h_align, HSSFColor.WHITE.index, false); | |||||
} | |||||
private static HSSFCellStyle createHeaderStyle(HSSFWorkbook wb) { | |||||
HSSFFont font = wb.createFont(); | |||||
font.setColor( HSSFColor.WHITE.index ); | |||||
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); | |||||
HSSFCellStyle cellStyle = wb.createCellStyle(); | |||||
cellStyle.setFillForegroundColor(HSSFColor.BLUE_GREY.index); | |||||
cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); | |||||
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); | |||||
cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); | |||||
cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); | |||||
cellStyle.setLeftBorderColor(HSSFColor.WHITE.index); | |||||
cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); | |||||
cellStyle.setTopBorderColor(HSSFColor.WHITE.index); | |||||
cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); | |||||
cellStyle.setRightBorderColor(HSSFColor.WHITE.index); | |||||
cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); | |||||
cellStyle.setBottomBorderColor(HSSFColor.WHITE.index); | |||||
cellStyle.setFont(font); | |||||
return cellStyle; | |||||
} | |||||
public HSSFSheet createSheet(String sheetName) { | |||||
_currentSheet = _wb.createSheet(sheetName); | |||||
return _currentSheet; | |||||
} | |||||
public void createDVTypeRow(String strTypeDescription) { | |||||
HSSFSheet sheet = _currentSheet; | |||||
HSSFRow row = sheet.createRow(sheet.getPhysicalNumberOfRows()); | |||||
row = sheet.createRow(sheet.getPhysicalNumberOfRows()); | |||||
sheet.addMergedRegion(new CellRangeAddress(sheet.getPhysicalNumberOfRows()-1, sheet.getPhysicalNumberOfRows()-1, 0, 5)); | |||||
HSSFCell cell = row.createCell(0); | |||||
setCellValue(cell, strTypeDescription); | |||||
cell.setCellStyle(_style_3); | |||||
row = sheet.createRow(sheet.getPhysicalNumberOfRows()); | |||||
} | |||||
public void createHeaderRow() { | |||||
HSSFSheet sheet = _currentSheet; | |||||
HSSFRow row = sheet.createRow(sheet.getPhysicalNumberOfRows()); | |||||
row.setHeight((short) 400); | |||||
for (int i = 0; i < 6; i++) { | |||||
row.createCell(i).setCellStyle(_style_4); | |||||
if (i == 2 || i == 3 || i == 4) { | |||||
sheet.setColumnWidth(i, 3500); | |||||
} else if (i == 5) { | |||||
sheet.setColumnWidth(i, 10000); | |||||
} else { | |||||
sheet.setColumnWidth(i, 8000); | |||||
} | |||||
} | |||||
HSSFCell cell = row.getCell(0); | |||||
setCellValue(cell, "Data validation cells"); | |||||
cell = row.getCell(1); | |||||
setCellValue(cell, "Condition"); | |||||
cell = row.getCell(2); | |||||
setCellValue(cell, "Allow blank"); | |||||
cell = row.getCell(3); | |||||
setCellValue(cell, "Prompt box"); | |||||
cell = row.getCell(4); | |||||
setCellValue(cell, "Error box"); | |||||
cell = row.getCell(5); | |||||
setCellValue(cell, "Other settings"); | |||||
} | |||||
public ValidationAdder createValidationAdder(HSSFCellStyle cellStyle, int dataValidationType) { | |||||
return new ValidationAdder(_currentSheet, _style_1, _style_2, cellStyle, dataValidationType); | |||||
} | |||||
public void createDVDescriptionRow(String strTypeDescription) { | |||||
HSSFSheet sheet = _currentSheet; | |||||
HSSFRow row = sheet.getRow(sheet.getPhysicalNumberOfRows()-1); | |||||
sheet.addMergedRegion(new CellRangeAddress(sheet.getPhysicalNumberOfRows()-1, sheet.getPhysicalNumberOfRows()-1, 0, 5)); | |||||
HSSFCell cell = row.createCell(0); | |||||
setCellValue(cell, strTypeDescription); | |||||
cell.setCellStyle(_style_3); | |||||
row = sheet.createRow(sheet.getPhysicalNumberOfRows()); | |||||
} | |||||
} | |||||
private void addCustomValidations(WorkbookFormatter wf) { | |||||
wf.createSheet("Custom"); | |||||
wf.createHeaderRow(); | |||||
ValidationAdder va = wf.createValidationAdder(null, VT.FORMULA); | |||||
va.addValidation(OP.BETWEEN, "ISNUMBER($A2)", null, ES.STOP, "ISNUMBER(A2)", "Error box type = STOP", true, true, true); | |||||
va.addValidation(OP.BETWEEN, "IF(SUM(A2:A3)=5,TRUE,FALSE)", null, ES.WARNING, "IF(SUM(A2:A3)=5,TRUE,FALSE)", "Error box type = WARNING", false, false, true); | |||||
} | |||||
private static void addSimpleNumericValidations(WorkbookFormatter wf) { | |||||
// data validation's number types | |||||
wf.createSheet("Numbers"); | |||||
// "Whole number" validation type | |||||
wf.createDVTypeRow("Whole number"); | |||||
wf.createHeaderRow(); | |||||
ValidationAdder va = wf.createValidationAdder(null, VT.INTEGER); | |||||
va.addValidation(OP.BETWEEN, "2", "6", ES.STOP, "Between 2 and 6 ", "Error box type = STOP", true, true, true); | |||||
va.addValidation(OP.NOT_BETWEEN, "2", "6", ES.INFO, "Not between 2 and 6 ", "Error box type = INFO", false, true, true); | |||||
va.addValidation(OP.EQUAL, "=3+2", null, ES.WARNING, "Equal to (3+2)", "Error box type = WARNING", false, false, true); | |||||
va.addValidation(OP.NOT_EQUAL, "3", null, ES.WARNING, "Not equal to 3", "-", false, false, false); | |||||
va.addValidation(OP.GREATER_THAN, "3", null, ES.WARNING, "Greater than 3", "-", true, false, false); | |||||
va.addValidation(OP.LESS_THAN, "3", null, ES.WARNING, "Less than 3", "-", true, true, false); | |||||
va.addValidation(OP.GREATER_OR_EQUAL, "4", null, ES.STOP, "Greater than or equal to 4", "Error box type = STOP", true, false, true); | |||||
va.addValidation(OP.LESS_OR_EQUAL, "4", null, ES.STOP, "Less than or equal to 4", "-", false, true, false); | |||||
// "Decimal" validation type | |||||
wf.createDVTypeRow("Decimal"); | |||||
wf.createHeaderRow(); | |||||
va = wf.createValidationAdder(null, VT.DECIMAL); | |||||
va.addValidation(OP.BETWEEN, "2", "6", ES.STOP, "Between 2 and 6 ", "Error box type = STOP", true, true, true); | |||||
va.addValidation(OP.NOT_BETWEEN, "2", "6", ES.INFO, "Not between 2 and 6 ", "Error box type = INFO", false, true, true); | |||||
va.addValidation(OP.EQUAL, "3", null, ES.WARNING, "Equal to 3", "Error box type = WARNING", false, false, true); | |||||
va.addValidation(OP.NOT_EQUAL, "3", null, ES.WARNING, "Not equal to 3", "-", false, false, false); | |||||
va.addValidation(OP.GREATER_THAN, "=12/6", null, ES.WARNING, "Greater than (12/6)", "-", true, false, false); | |||||
va.addValidation(OP.LESS_THAN, "3", null, ES.WARNING, "Less than 3", "-", true, true, false); | |||||
va.addValidation(OP.GREATER_OR_EQUAL, "4", null, ES.STOP, "Greater than or equal to 4", "Error box type = STOP", true, false, true); | |||||
va.addValidation(OP.LESS_OR_EQUAL, "4", null, ES.STOP, "Less than or equal to 4", "-", false, true, false); | |||||
} | |||||
private static void addListValidations(WorkbookFormatter wf, HSSFWorkbook wb) { | |||||
final String cellStrValue | |||||
= "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 " | |||||
+ "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 " | |||||
+ "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 " | |||||
+ "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 "; | |||||
final String dataSheetName = "list_data"; | |||||
// "List" Data Validation type | |||||
HSSFSheet fSheet = wf.createSheet("Lists"); | |||||
HSSFSheet dataSheet = wb.createSheet(dataSheetName); | |||||
wf.createDVTypeRow("Explicit lists - list items are explicitly provided"); | |||||
wf.createDVDescriptionRow("Disadvantage - sum of item's length should be less than 255 characters"); | |||||
wf.createHeaderRow(); | |||||
ValidationAdder va = wf.createValidationAdder(null, VT.LIST); | |||||
String listValsDescr = "POIFS,HSSF,HWPF,HPSF"; | |||||
String[] listVals = listValsDescr.split(","); | |||||
va.addListValidation(listVals, null, listValsDescr, false, false); | |||||
va.addListValidation(listVals, null, listValsDescr, false, true); | |||||
va.addListValidation(listVals, null, listValsDescr, true, false); | |||||
va.addListValidation(listVals, null, listValsDescr, true, true); | |||||
wf.createDVTypeRow("Reference lists - list items are taken from others cells"); | |||||
wf.createDVDescriptionRow("Advantage - no restriction regarding the sum of item's length"); | |||||
wf.createHeaderRow(); | |||||
va = wf.createValidationAdder(null, VT.LIST); | |||||
String strFormula = "$A$30:$A$39"; | |||||
va.addListValidation(null, strFormula, strFormula, false, false); | |||||
strFormula = dataSheetName + "!$A$1:$A$10"; | |||||
va.addListValidation(null, strFormula, strFormula, false, false); | |||||
HSSFName namedRange = wb.createName(); | |||||
namedRange.setNameName("myName"); | |||||
namedRange.setRefersToFormula(dataSheetName + "!$A$2:$A$7"); | |||||
strFormula = "myName"; | |||||
va.addListValidation(null, strFormula, strFormula, false, false); | |||||
strFormula = "offset(myName, 2, 1, 4, 2)"; // Note about last param '2': | |||||
// - Excel expects single row or single column when entered in UI, but process this OK otherwise | |||||
va.addListValidation(null, strFormula, strFormula, false, false); | |||||
// add list data on same sheet | |||||
for (int i = 0; i < 10; i++) { | |||||
HSSFRow currRow = fSheet.createRow(i + 29); | |||||
setCellValue(currRow.createCell(0), cellStrValue); | |||||
} | |||||
// add list data on another sheet | |||||
for (int i = 0; i < 10; i++) { | |||||
HSSFRow currRow = dataSheet.createRow(i + 0); | |||||
setCellValue(currRow.createCell(0), "Data a" + i); | |||||
setCellValue(currRow.createCell(1), "Data b" + i); | |||||
setCellValue(currRow.createCell(2), "Data c" + i); | |||||
} | |||||
} | |||||
private static void addDateTimeValidations(WorkbookFormatter wf, HSSFWorkbook wb) { | |||||
wf.createSheet("Dates and Times"); | |||||
HSSFDataFormat dataFormat = wb.createDataFormat(); | |||||
short fmtDate = dataFormat.getFormat("m/d/yyyy"); | |||||
short fmtTime = dataFormat.getFormat("h:mm"); | |||||
HSSFCellStyle cellStyle_date = wb.createCellStyle(); | |||||
cellStyle_date.setDataFormat(fmtDate); | |||||
HSSFCellStyle cellStyle_time = wb.createCellStyle(); | |||||
cellStyle_time.setDataFormat(fmtTime); | |||||
wf.createDVTypeRow("Date ( cells are already formated as date - m/d/yyyy)"); | |||||
wf.createHeaderRow(); | |||||
ValidationAdder va = wf.createValidationAdder(cellStyle_date, VT.DATE); | |||||
va.addValidation(OP.BETWEEN, "2004/01/02", "2004/01/06", ES.STOP, "Between 1/2/2004 and 1/6/2004 ", "Error box type = STOP", true, true, true); | |||||
va.addValidation(OP.NOT_BETWEEN, "2004/01/01", "2004/01/06", ES.INFO, "Not between 1/2/2004 and 1/6/2004 ", "Error box type = INFO", false, true, true); | |||||
va.addValidation(OP.EQUAL, "2004/03/02", null, ES.WARNING, "Equal to 3/2/2004", "Error box type = WARNING", false, false, true); | |||||
va.addValidation(OP.NOT_EQUAL, "2004/03/02", null, ES.WARNING, "Not equal to 3/2/2004", "-", false, false, false); | |||||
va.addValidation(OP.GREATER_THAN,"=DATEVALUE(\"4-Jul-2001\")", null, ES.WARNING, "Greater than DATEVALUE('4-Jul-2001')", "-", true, false, false); | |||||
va.addValidation(OP.LESS_THAN, "2004/03/02", null, ES.WARNING, "Less than 3/2/2004", "-", true, true, false); | |||||
va.addValidation(OP.GREATER_OR_EQUAL, "2004/03/02", null, ES.STOP, "Greater than or equal to 3/2/2004", "Error box type = STOP", true, false, true); | |||||
va.addValidation(OP.LESS_OR_EQUAL, "2004/03/04", null, ES.STOP, "Less than or equal to 3/4/2004", "-", false, true, false); | |||||
// "Time" validation type | |||||
wf.createDVTypeRow("Time ( cells are already formated as time - h:mm)"); | |||||
wf.createHeaderRow(); | |||||
va = wf.createValidationAdder(cellStyle_time, VT.TIME); | |||||
va.addValidation(OP.BETWEEN, "12:00", "16:00", ES.STOP, "Between 12:00 and 16:00 ", "Error box type = STOP", true, true, true); | |||||
va.addValidation(OP.NOT_BETWEEN, "12:00", "16:00", ES.INFO, "Not between 12:00 and 16:00 ", "Error box type = INFO", false, true, true); | |||||
va.addValidation(OP.EQUAL, "13:35", null, ES.WARNING, "Equal to 13:35", "Error box type = WARNING", false, false, true); | |||||
va.addValidation(OP.NOT_EQUAL, "13:35", null, ES.WARNING, "Not equal to 13:35", "-", false, false, false); | |||||
va.addValidation(OP.GREATER_THAN,"12:00", null, ES.WARNING, "Greater than 12:00", "-", true, false, false); | |||||
va.addValidation(OP.LESS_THAN, "=1/2", null, ES.WARNING, "Less than (1/2) -> 12:00", "-", true, true, false); | |||||
va.addValidation(OP.GREATER_OR_EQUAL, "14:00", null, ES.STOP, "Greater than or equal to 14:00", "Error box type = STOP", true, false, true); | |||||
va.addValidation(OP.LESS_OR_EQUAL,"14:00", null, ES.STOP, "Less than or equal to 14:00", "-", false, true, false); | |||||
} | |||||
private static void addTextLengthValidations(WorkbookFormatter wf) { | |||||
wf.createSheet("Text lengths"); | |||||
wf.createHeaderRow(); | |||||
ValidationAdder va = wf.createValidationAdder(null, VT.TEXT_LENGTH); | |||||
va.addValidation(OP.BETWEEN, "2", "6", ES.STOP, "Between 2 and 6 ", "Error box type = STOP", true, true, true); | |||||
va.addValidation(OP.NOT_BETWEEN, "2", "6", ES.INFO, "Not between 2 and 6 ", "Error box type = INFO", false, true, true); | |||||
va.addValidation(OP.EQUAL, "3", null, ES.WARNING, "Equal to 3", "Error box type = WARNING", false, false, true); | |||||
va.addValidation(OP.NOT_EQUAL, "3", null, ES.WARNING, "Not equal to 3", "-", false, false, false); | |||||
va.addValidation(OP.GREATER_THAN, "3", null, ES.WARNING, "Greater than 3", "-", true, false, false); | |||||
va.addValidation(OP.LESS_THAN, "3", null, ES.WARNING, "Less than 3", "-", true, true, false); | |||||
va.addValidation(OP.GREATER_OR_EQUAL, "4", null, ES.STOP, "Greater than or equal to 4", "Error box type = STOP", true, false, true); | |||||
va.addValidation(OP.LESS_OR_EQUAL, "4", null, ES.STOP, "Less than or equal to 4", "-", false, true, false); | |||||
} | |||||
public void testDataValidation() { | |||||
log("\nTest no. 2 - Test Excel's Data validation mechanism"); | |||||
HSSFWorkbook wb = new HSSFWorkbook(); | |||||
WorkbookFormatter wf = new WorkbookFormatter(wb); | |||||
log(" Create sheet for Data Validation's number types ... "); | |||||
addSimpleNumericValidations(wf); | |||||
log("done !"); | |||||
log(" Create sheet for 'List' Data Validation type ... "); | |||||
addListValidations(wf, wb); | |||||
log("done !"); | |||||
log(" Create sheet for 'Date' and 'Time' Data Validation types ... "); | |||||
addDateTimeValidations(wf, wb); | |||||
log("done !"); | |||||
log(" Create sheet for 'Text length' Data Validation type... "); | |||||
addTextLengthValidations(wf); | |||||
log("done !"); | |||||
// Custom Validation type | |||||
log(" Create sheet for 'Custom' Data Validation type ... "); | |||||
addCustomValidations(wf); | |||||
log("done !"); | |||||
public void assertDataValidation(Workbook wb) { | |||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(22000); | ByteArrayOutputStream baos = new ByteArrayOutputStream(22000); | ||||
try { | try { | ||||
// and then deleting the row that contains the cell. | // and then deleting the row that contains the cell. | ||||
HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("dvEmpty.xls"); | HSSFWorkbook wb = HSSFTestDataSamples.openSampleWorkbook("dvEmpty.xls"); | ||||
int dvRow = 0; | int dvRow = 0; | ||||
HSSFSheet sheet = wb.getSheetAt(0); | |||||
DVConstraint dc = DVConstraint.createNumericConstraint(VT.INTEGER, OP.EQUAL, "42", null); | |||||
HSSFDataValidation dv = new HSSFDataValidation(new CellRangeAddressList(dvRow, dvRow, 0, 0), dc); | |||||
Sheet sheet = wb.getSheetAt(0); | |||||
DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper(); | |||||
DataValidationConstraint dc = dataValidationHelper.createIntegerConstraint(OP.EQUAL, "42", null); | |||||
DataValidation dv = dataValidationHelper.createValidation(dc,new CellRangeAddressList(dvRow, dvRow, 0, 0)); | |||||
dv.setEmptyCellAllowed(false); | dv.setEmptyCellAllowed(false); | ||||
dv.setErrorStyle(ES.STOP); | dv.setErrorStyle(ES.STOP); |
import org.apache.poi.hssf.record.aggregates.WorksheetProtectionBlock; | import org.apache.poi.hssf.record.aggregates.WorksheetProtectionBlock; | ||||
import org.apache.poi.hssf.usermodel.RecordInspector.RecordCollector; | import org.apache.poi.hssf.usermodel.RecordInspector.RecordCollector; | ||||
import org.apache.poi.ss.usermodel.BaseTestSheet; | import org.apache.poi.ss.usermodel.BaseTestSheet; | ||||
import org.apache.poi.ss.usermodel.DataValidation; | |||||
import org.apache.poi.ss.usermodel.DataValidationConstraint; | |||||
import org.apache.poi.ss.usermodel.DataValidationHelper; | |||||
import org.apache.poi.ss.util.CellRangeAddress; | import org.apache.poi.ss.util.CellRangeAddress; | ||||
import org.apache.poi.ss.util.CellRangeAddressList; | import org.apache.poi.ss.util.CellRangeAddressList; | ||||
import org.apache.poi.util.TempFile; | import org.apache.poi.util.TempFile; | ||||
HSSFSheet sheet = workbook.createSheet("Sheet1"); | HSSFSheet sheet = workbook.createSheet("Sheet1"); | ||||
sheet.protectSheet("secret"); | sheet.protectSheet("secret"); | ||||
DVConstraint dvc = DVConstraint.createNumericConstraint(DVConstraint.ValidationType.INTEGER, | |||||
DVConstraint.OperatorType.BETWEEN, "10", "100"); | |||||
DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper(); | |||||
DataValidationConstraint dvc = dataValidationHelper.createIntegerConstraint(DataValidationConstraint.OperatorType.BETWEEN, "10", "100"); | |||||
CellRangeAddressList numericCellAddressList = new CellRangeAddressList(0, 0, 1, 1); | CellRangeAddressList numericCellAddressList = new CellRangeAddressList(0, 0, 1, 1); | ||||
HSSFDataValidation dv = new HSSFDataValidation(numericCellAddressList, dvc); | |||||
DataValidation dv = dataValidationHelper.createValidation(dvc,numericCellAddressList); | |||||
try { | try { | ||||
sheet.addValidationData(dv); | sheet.addValidationData(dv); | ||||
} catch (IllegalStateException e) { | } catch (IllegalStateException e) { | ||||
int minWithRow1And2 = 6400; | int minWithRow1And2 = 6400; | ||||
int maxWithRow1And2 = 7800; | int maxWithRow1And2 = 7800; | ||||
int minWithRow1Only = 2750; | int minWithRow1Only = 2750; | ||||
int maxWithRow1Only = 3300; | |||||
int maxWithRow1Only = 3400; | |||||
// autoSize the first column and check its size before the merged region (1,0,1,1) is set: | // autoSize the first column and check its size before the merged region (1,0,1,1) is set: | ||||
// it has to be based on the 2nd row width | // it has to be based on the 2nd row width |
/* ==================================================================== | |||||
Licensed to the Apache Software Foundation (ASF) under one or more | |||||
contributor license agreements. See the NOTICE file distributed with | |||||
this work for additional information regarding copyright ownership. | |||||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||||
(the "License"); you may not use this file except in compliance with | |||||
the License. You may obtain a copy of the License at | |||||
http://www.apache.org/licenses/LICENSE-2.0 | |||||
Unless required by applicable law or agreed to in writing, software | |||||
distributed under the License is distributed on an "AS IS" BASIS, | |||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
See the License for the specific language governing permissions and | |||||
limitations under the License. | |||||
==================================================================== */ | |||||
package org.apache.poi.ss.usermodel; | |||||
import junit.framework.TestCase; | |||||
import org.apache.poi.ss.ITestDataProvider; | |||||
import org.apache.poi.ss.util.CellRangeAddress; | |||||
import org.apache.poi.ss.util.CellRangeAddressList; | |||||
import org.apache.poi.util.POILogFactory; | |||||
import org.apache.poi.util.POILogger; | |||||
/** | |||||
* Class for testing Excel's data validation mechanism | |||||
* | |||||
* @author Dragos Buleandra ( dragos.buleandra@trade2b.ro ) | |||||
*/ | |||||
public abstract class BaseTestDataValidation extends TestCase { | |||||
private final ITestDataProvider _testDataProvider; | |||||
private static final POILogger log = POILogFactory.getLogger(BaseTestDataValidation.class); | |||||
protected BaseTestDataValidation(ITestDataProvider testDataProvider) { | |||||
_testDataProvider = testDataProvider; | |||||
} | |||||
/** Convenient access to ERROR_STYLE constants */ | |||||
protected static final DataValidation.ErrorStyle ES = null; | |||||
/** Convenient access to OPERATOR constants */ | |||||
protected static final DataValidationConstraint.ValidationType VT = null; | |||||
/** Convenient access to OPERATOR constants */ | |||||
protected static final DataValidationConstraint.OperatorType OP = null; | |||||
private static final class ValidationAdder { | |||||
private final CellStyle _style_1; | |||||
private final CellStyle _style_2; | |||||
private final int _validationType; | |||||
private final Sheet _sheet; | |||||
private int _currentRowIndex; | |||||
private final CellStyle _cellStyle; | |||||
public ValidationAdder(Sheet fSheet, CellStyle style_1, CellStyle style_2, | |||||
CellStyle cellStyle, int validationType) { | |||||
_sheet = fSheet; | |||||
_style_1 = style_1; | |||||
_style_2 = style_2; | |||||
_cellStyle = cellStyle; | |||||
_validationType = validationType; | |||||
_currentRowIndex = fSheet.getPhysicalNumberOfRows(); | |||||
} | |||||
public void addValidation(int operatorType, String firstFormula, String secondFormula, | |||||
int errorStyle, String ruleDescr, String promptDescr, | |||||
boolean allowEmpty, boolean inputBox, boolean errorBox) { | |||||
String[] explicitListValues = null; | |||||
addValidationInternal(operatorType, firstFormula, secondFormula, errorStyle, ruleDescr, | |||||
promptDescr, allowEmpty, inputBox, errorBox, true, | |||||
explicitListValues); | |||||
} | |||||
private void addValidationInternal(int operatorType, String firstFormula, | |||||
String secondFormula, int errorStyle, String ruleDescr, String promptDescr, | |||||
boolean allowEmpty, boolean inputBox, boolean errorBox, boolean suppressDropDown, | |||||
String[] explicitListValues) { | |||||
int rowNum = _currentRowIndex++; | |||||
DataValidationHelper dataValidationHelper = _sheet.getDataValidationHelper(); | |||||
DataValidationConstraint dc = createConstraint(dataValidationHelper,operatorType, firstFormula, secondFormula, explicitListValues); | |||||
DataValidation dv = dataValidationHelper.createValidation(dc,new CellRangeAddressList(rowNum, rowNum, 0, 0)); | |||||
dv.setEmptyCellAllowed(allowEmpty); | |||||
dv.setErrorStyle(errorStyle); | |||||
dv.createErrorBox("Invalid Input", "Something is wrong - check condition!"); | |||||
dv.createPromptBox("Validated Cell", "Allowable values have been restricted"); | |||||
dv.setShowPromptBox(inputBox); | |||||
dv.setShowErrorBox(errorBox); | |||||
dv.setSuppressDropDownArrow(suppressDropDown); | |||||
_sheet.addValidationData(dv); | |||||
writeDataValidationSettings(_sheet, _style_1, _style_2, ruleDescr, allowEmpty, | |||||
inputBox, errorBox); | |||||
if (_cellStyle != null) { | |||||
Row row = _sheet.getRow(_sheet.getPhysicalNumberOfRows() - 1); | |||||
Cell cell = row.createCell(0); | |||||
cell.setCellStyle(_cellStyle); | |||||
} | |||||
writeOtherSettings(_sheet, _style_1, promptDescr); | |||||
} | |||||
private DataValidationConstraint createConstraint(DataValidationHelper dataValidationHelper,int operatorType, String firstFormula, | |||||
String secondFormula, String[] explicitListValues) { | |||||
if (_validationType == VT.LIST) { | |||||
if (explicitListValues != null) { | |||||
return dataValidationHelper.createExplicitListConstraint(explicitListValues); | |||||
} | |||||
return dataValidationHelper.createFormulaListConstraint(firstFormula); | |||||
} | |||||
if (_validationType == VT.TIME) { | |||||
return dataValidationHelper.createTimeConstraint(operatorType, firstFormula, secondFormula); | |||||
} | |||||
if (_validationType == VT.DATE) { | |||||
return dataValidationHelper.createDateConstraint(operatorType, firstFormula, secondFormula, null); | |||||
} | |||||
if (_validationType == VT.FORMULA) { | |||||
return dataValidationHelper.createCustomConstraint(firstFormula); | |||||
} | |||||
if( _validationType == VT.INTEGER) { | |||||
return dataValidationHelper.createIntegerConstraint(operatorType, firstFormula, secondFormula); | |||||
} | |||||
if( _validationType == VT.DECIMAL) { | |||||
return dataValidationHelper.createDecimalConstraint(operatorType, firstFormula, secondFormula); | |||||
} | |||||
if( _validationType == VT.TEXT_LENGTH) { | |||||
return dataValidationHelper.createTextLengthConstraint(operatorType, firstFormula, secondFormula); | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* writes plain text values into cells in a tabular format to form comments readable from within | |||||
* the spreadsheet. | |||||
*/ | |||||
private static void writeDataValidationSettings(Sheet sheet, CellStyle style_1, | |||||
CellStyle style_2, String strCondition, boolean allowEmpty, boolean inputBox, | |||||
boolean errorBox) { | |||||
Row row = sheet.createRow(sheet.getPhysicalNumberOfRows()); | |||||
// condition's string | |||||
Cell cell = row.createCell(1); | |||||
cell.setCellStyle(style_1); | |||||
setCellValue(cell, strCondition); | |||||
// allow empty cells | |||||
cell = row.createCell(2); | |||||
cell.setCellStyle(style_2); | |||||
setCellValue(cell, ((allowEmpty) ? "yes" : "no")); | |||||
// show input box | |||||
cell = row.createCell(3); | |||||
cell.setCellStyle(style_2); | |||||
setCellValue(cell, ((inputBox) ? "yes" : "no")); | |||||
// show error box | |||||
cell = row.createCell(4); | |||||
cell.setCellStyle(style_2); | |||||
setCellValue(cell, ((errorBox) ? "yes" : "no")); | |||||
} | |||||
private static void writeOtherSettings(Sheet sheet, CellStyle style, | |||||
String strStettings) { | |||||
Row row = sheet.getRow(sheet.getPhysicalNumberOfRows() - 1); | |||||
Cell cell = row.createCell(5); | |||||
cell.setCellStyle(style); | |||||
setCellValue(cell, strStettings); | |||||
} | |||||
public void addListValidation(String[] explicitListValues, String listFormula, String listValsDescr, | |||||
boolean allowEmpty, boolean suppressDropDown) { | |||||
String promptDescr = (allowEmpty ? "empty ok" : "not empty") | |||||
+ ", " + (suppressDropDown ? "no drop-down" : "drop-down"); | |||||
addValidationInternal(VT.LIST, listFormula, null, ES.STOP, listValsDescr, promptDescr, | |||||
allowEmpty, false, true, suppressDropDown, explicitListValues); | |||||
} | |||||
} | |||||
private static void log(String msg) { | |||||
log.log(POILogger.INFO, msg); | |||||
} | |||||
/** | |||||
* Manages the cell styles used for formatting the output spreadsheet | |||||
*/ | |||||
private static final class WorkbookFormatter { | |||||
private final Workbook _wb; | |||||
private final CellStyle _style_1; | |||||
private final CellStyle _style_2; | |||||
private final CellStyle _style_3; | |||||
private final CellStyle _style_4; | |||||
private Sheet _currentSheet; | |||||
public WorkbookFormatter(Workbook wb) { | |||||
_wb = wb; | |||||
_style_1 = createStyle( wb, CellStyle.ALIGN_LEFT ); | |||||
_style_2 = createStyle( wb, CellStyle.ALIGN_CENTER ); | |||||
_style_3 = createStyle( wb, CellStyle.ALIGN_CENTER, IndexedColors.GREY_25_PERCENT.getIndex(), true ); | |||||
_style_4 = createHeaderStyle(wb); | |||||
} | |||||
private static CellStyle createStyle(Workbook wb, short h_align, short color, | |||||
boolean bold) { | |||||
Font font = wb.createFont(); | |||||
if (bold) { | |||||
font.setBoldweight(Font.BOLDWEIGHT_BOLD); | |||||
} | |||||
CellStyle cellStyle = wb.createCellStyle(); | |||||
cellStyle.setFont(font); | |||||
cellStyle.setFillForegroundColor(color); | |||||
cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND); | |||||
cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); | |||||
cellStyle.setAlignment(h_align); | |||||
cellStyle.setBorderLeft(CellStyle.BORDER_THIN); | |||||
cellStyle.setLeftBorderColor(IndexedColors.BLACK.getIndex()); | |||||
cellStyle.setBorderTop(CellStyle.BORDER_THIN); | |||||
cellStyle.setTopBorderColor(IndexedColors.BLACK.getIndex()); | |||||
cellStyle.setBorderRight(CellStyle.BORDER_THIN); | |||||
cellStyle.setRightBorderColor(IndexedColors.BLACK.getIndex()); | |||||
cellStyle.setBorderBottom(CellStyle.BORDER_THIN); | |||||
cellStyle.setBottomBorderColor(IndexedColors.BLACK.getIndex()); | |||||
return cellStyle; | |||||
} | |||||
private static CellStyle createStyle(Workbook wb, short h_align) { | |||||
return createStyle(wb, h_align, IndexedColors.WHITE.getIndex(), false); | |||||
} | |||||
private static CellStyle createHeaderStyle(Workbook wb) { | |||||
Font font = wb.createFont(); | |||||
font.setColor( IndexedColors.WHITE.getIndex() ); | |||||
font.setBoldweight(Font.BOLDWEIGHT_BOLD); | |||||
CellStyle cellStyle = wb.createCellStyle(); | |||||
cellStyle.setFillForegroundColor(IndexedColors.BLUE_GREY.getIndex()); | |||||
cellStyle.setFillPattern(CellStyle.SOLID_FOREGROUND); | |||||
cellStyle.setAlignment(CellStyle.ALIGN_CENTER); | |||||
cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); | |||||
cellStyle.setBorderLeft(CellStyle.BORDER_THIN); | |||||
cellStyle.setLeftBorderColor(IndexedColors.WHITE.getIndex()); | |||||
cellStyle.setBorderTop(CellStyle.BORDER_THIN); | |||||
cellStyle.setTopBorderColor(IndexedColors.WHITE.getIndex()); | |||||
cellStyle.setBorderRight(CellStyle.BORDER_THIN); | |||||
cellStyle.setRightBorderColor(IndexedColors.WHITE.getIndex()); | |||||
cellStyle.setBorderBottom(CellStyle.BORDER_THIN); | |||||
cellStyle.setBottomBorderColor(IndexedColors.WHITE.getIndex()); | |||||
cellStyle.setFont(font); | |||||
return cellStyle; | |||||
} | |||||
public Sheet createSheet(String sheetName) { | |||||
_currentSheet = _wb.createSheet(sheetName); | |||||
return _currentSheet; | |||||
} | |||||
public void createDVTypeRow(String strTypeDescription) { | |||||
Sheet sheet = _currentSheet; | |||||
Row row = sheet.createRow(sheet.getPhysicalNumberOfRows()); | |||||
sheet.addMergedRegion(new CellRangeAddress(sheet.getPhysicalNumberOfRows()-1, sheet.getPhysicalNumberOfRows()-1, 0, 5)); | |||||
Cell cell = row.createCell(0); | |||||
setCellValue(cell, strTypeDescription); | |||||
cell.setCellStyle(_style_3); | |||||
row = sheet.createRow(sheet.getPhysicalNumberOfRows()); | |||||
} | |||||
public void createHeaderRow() { | |||||
Sheet sheet = _currentSheet; | |||||
Row row = sheet.createRow(sheet.getPhysicalNumberOfRows()); | |||||
row.setHeight((short) 400); | |||||
for (int i = 0; i < 6; i++) { | |||||
row.createCell(i).setCellStyle(_style_4); | |||||
if (i == 2 || i == 3 || i == 4) { | |||||
sheet.setColumnWidth(i, 3500); | |||||
} else if (i == 5) { | |||||
sheet.setColumnWidth(i, 10000); | |||||
} else { | |||||
sheet.setColumnWidth(i, 8000); | |||||
} | |||||
} | |||||
Cell cell = row.getCell(0); | |||||
setCellValue(cell, "Data validation cells"); | |||||
cell = row.getCell(1); | |||||
setCellValue(cell, "Condition"); | |||||
cell = row.getCell(2); | |||||
setCellValue(cell, "Allow blank"); | |||||
cell = row.getCell(3); | |||||
setCellValue(cell, "Prompt box"); | |||||
cell = row.getCell(4); | |||||
setCellValue(cell, "Error box"); | |||||
cell = row.getCell(5); | |||||
setCellValue(cell, "Other settings"); | |||||
} | |||||
public ValidationAdder createValidationAdder(CellStyle cellStyle, int dataValidationType) { | |||||
return new ValidationAdder(_currentSheet, _style_1, _style_2, cellStyle, dataValidationType); | |||||
} | |||||
public void createDVDescriptionRow(String strTypeDescription) { | |||||
Sheet sheet = _currentSheet; | |||||
Row row = sheet.getRow(sheet.getPhysicalNumberOfRows()-1); | |||||
sheet.addMergedRegion(new CellRangeAddress(sheet.getPhysicalNumberOfRows()-1, sheet.getPhysicalNumberOfRows()-1, 0, 5)); | |||||
Cell cell = row.createCell(0); | |||||
setCellValue(cell, strTypeDescription); | |||||
cell.setCellStyle(_style_3); | |||||
row = sheet.createRow(sheet.getPhysicalNumberOfRows()); | |||||
} | |||||
} | |||||
private void addCustomValidations(WorkbookFormatter wf) { | |||||
wf.createSheet("Custom"); | |||||
wf.createHeaderRow(); | |||||
ValidationAdder va = wf.createValidationAdder(null, VT.FORMULA); | |||||
va.addValidation(OP.BETWEEN, "ISNUMBER($A2)", null, ES.STOP, "ISNUMBER(A2)", "Error box type = STOP", true, true, true); | |||||
va.addValidation(OP.BETWEEN, "IF(SUM(A2:A3)=5,TRUE,FALSE)", null, ES.WARNING, "IF(SUM(A2:A3)=5,TRUE,FALSE)", "Error box type = WARNING", false, false, true); | |||||
} | |||||
private static void addSimpleNumericValidations(WorkbookFormatter wf) { | |||||
// data validation's number types | |||||
wf.createSheet("Numbers"); | |||||
// "Whole number" validation type | |||||
wf.createDVTypeRow("Whole number"); | |||||
wf.createHeaderRow(); | |||||
ValidationAdder va = wf.createValidationAdder(null, VT.INTEGER); | |||||
va.addValidation(OP.BETWEEN, "2", "6", ES.STOP, "Between 2 and 6 ", "Error box type = STOP", true, true, true); | |||||
va.addValidation(OP.NOT_BETWEEN, "2", "6", ES.INFO, "Not between 2 and 6 ", "Error box type = INFO", false, true, true); | |||||
va.addValidation(OP.EQUAL, "=3+2", null, ES.WARNING, "Equal to (3+2)", "Error box type = WARNING", false, false, true); | |||||
va.addValidation(OP.NOT_EQUAL, "3", null, ES.WARNING, "Not equal to 3", "-", false, false, false); | |||||
va.addValidation(OP.GREATER_THAN, "3", null, ES.WARNING, "Greater than 3", "-", true, false, false); | |||||
va.addValidation(OP.LESS_THAN, "3", null, ES.WARNING, "Less than 3", "-", true, true, false); | |||||
va.addValidation(OP.GREATER_OR_EQUAL, "4", null, ES.STOP, "Greater than or equal to 4", "Error box type = STOP", true, false, true); | |||||
va.addValidation(OP.LESS_OR_EQUAL, "4", null, ES.STOP, "Less than or equal to 4", "-", false, true, false); | |||||
// "Decimal" validation type | |||||
wf.createDVTypeRow("Decimal"); | |||||
wf.createHeaderRow(); | |||||
va = wf.createValidationAdder(null, VT.DECIMAL); | |||||
va.addValidation(OP.BETWEEN, "2", "6", ES.STOP, "Between 2 and 6 ", "Error box type = STOP", true, true, true); | |||||
va.addValidation(OP.NOT_BETWEEN, "2", "6", ES.INFO, "Not between 2 and 6 ", "Error box type = INFO", false, true, true); | |||||
va.addValidation(OP.EQUAL, "3", null, ES.WARNING, "Equal to 3", "Error box type = WARNING", false, false, true); | |||||
va.addValidation(OP.NOT_EQUAL, "3", null, ES.WARNING, "Not equal to 3", "-", false, false, false); | |||||
va.addValidation(OP.GREATER_THAN, "=12/6", null, ES.WARNING, "Greater than (12/6)", "-", true, false, false); | |||||
va.addValidation(OP.LESS_THAN, "3", null, ES.WARNING, "Less than 3", "-", true, true, false); | |||||
va.addValidation(OP.GREATER_OR_EQUAL, "4", null, ES.STOP, "Greater than or equal to 4", "Error box type = STOP", true, false, true); | |||||
va.addValidation(OP.LESS_OR_EQUAL, "4", null, ES.STOP, "Less than or equal to 4", "-", false, true, false); | |||||
} | |||||
private static void addListValidations(WorkbookFormatter wf, Workbook wb) { | |||||
final String cellStrValue | |||||
= "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 " | |||||
+ "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 " | |||||
+ "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 " | |||||
+ "a b c d e f g h i j k l m n o p r s t u v x y z w 0 1 2 3 4 "; | |||||
final String dataSheetName = "list_data"; | |||||
// "List" Data Validation type | |||||
Sheet fSheet = wf.createSheet("Lists"); | |||||
Sheet dataSheet = wb.createSheet(dataSheetName); | |||||
wf.createDVTypeRow("Explicit lists - list items are explicitly provided"); | |||||
wf.createDVDescriptionRow("Disadvantage - sum of item's length should be less than 255 characters"); | |||||
wf.createHeaderRow(); | |||||
ValidationAdder va = wf.createValidationAdder(null, VT.LIST); | |||||
String listValsDescr = "POIFS,HSSF,HWPF,HPSF"; | |||||
String[] listVals = listValsDescr.split(","); | |||||
va.addListValidation(listVals, null, listValsDescr, false, false); | |||||
va.addListValidation(listVals, null, listValsDescr, false, true); | |||||
va.addListValidation(listVals, null, listValsDescr, true, false); | |||||
va.addListValidation(listVals, null, listValsDescr, true, true); | |||||
wf.createDVTypeRow("Reference lists - list items are taken from others cells"); | |||||
wf.createDVDescriptionRow("Advantage - no restriction regarding the sum of item's length"); | |||||
wf.createHeaderRow(); | |||||
va = wf.createValidationAdder(null, VT.LIST); | |||||
String strFormula = "$A$30:$A$39"; | |||||
va.addListValidation(null, strFormula, strFormula, false, false); | |||||
strFormula = dataSheetName + "!$A$1:$A$10"; | |||||
va.addListValidation(null, strFormula, strFormula, false, false); | |||||
Name namedRange = wb.createName(); | |||||
namedRange.setNameName("myName"); | |||||
namedRange.setRefersToFormula(dataSheetName + "!$A$2:$A$7"); | |||||
strFormula = "myName"; | |||||
va.addListValidation(null, strFormula, strFormula, false, false); | |||||
strFormula = "offset(myName, 2, 1, 4, 2)"; // Note about last param '2': | |||||
// - Excel expects single row or single column when entered in UI, but process this OK otherwise | |||||
va.addListValidation(null, strFormula, strFormula, false, false); | |||||
// add list data on same sheet | |||||
for (int i = 0; i < 10; i++) { | |||||
Row currRow = fSheet.createRow(i + 29); | |||||
setCellValue(currRow.createCell(0), cellStrValue); | |||||
} | |||||
// add list data on another sheet | |||||
for (int i = 0; i < 10; i++) { | |||||
Row currRow = dataSheet.createRow(i + 0); | |||||
setCellValue(currRow.createCell(0), "Data a" + i); | |||||
setCellValue(currRow.createCell(1), "Data b" + i); | |||||
setCellValue(currRow.createCell(2), "Data c" + i); | |||||
} | |||||
} | |||||
private static void addDateTimeValidations(WorkbookFormatter wf, Workbook wb) { | |||||
wf.createSheet("Dates and Times"); | |||||
DataFormat dataFormat = wb.createDataFormat(); | |||||
short fmtDate = dataFormat.getFormat("m/d/yyyy"); | |||||
short fmtTime = dataFormat.getFormat("h:mm"); | |||||
CellStyle cellStyle_date = wb.createCellStyle(); | |||||
cellStyle_date.setDataFormat(fmtDate); | |||||
CellStyle cellStyle_time = wb.createCellStyle(); | |||||
cellStyle_time.setDataFormat(fmtTime); | |||||
wf.createDVTypeRow("Date ( cells are already formated as date - m/d/yyyy)"); | |||||
wf.createHeaderRow(); | |||||
ValidationAdder va = wf.createValidationAdder(cellStyle_date, VT.DATE); | |||||
va.addValidation(OP.BETWEEN, "2004/01/02", "2004/01/06", ES.STOP, "Between 1/2/2004 and 1/6/2004 ", "Error box type = STOP", true, true, true); | |||||
va.addValidation(OP.NOT_BETWEEN, "2004/01/01", "2004/01/06", ES.INFO, "Not between 1/2/2004 and 1/6/2004 ", "Error box type = INFO", false, true, true); | |||||
va.addValidation(OP.EQUAL, "2004/03/02", null, ES.WARNING, "Equal to 3/2/2004", "Error box type = WARNING", false, false, true); | |||||
va.addValidation(OP.NOT_EQUAL, "2004/03/02", null, ES.WARNING, "Not equal to 3/2/2004", "-", false, false, false); | |||||
va.addValidation(OP.GREATER_THAN,"=DATEVALUE(\"4-Jul-2001\")", null, ES.WARNING, "Greater than DATEVALUE('4-Jul-2001')", "-", true, false, false); | |||||
va.addValidation(OP.LESS_THAN, "2004/03/02", null, ES.WARNING, "Less than 3/2/2004", "-", true, true, false); | |||||
va.addValidation(OP.GREATER_OR_EQUAL, "2004/03/02", null, ES.STOP, "Greater than or equal to 3/2/2004", "Error box type = STOP", true, false, true); | |||||
va.addValidation(OP.LESS_OR_EQUAL, "2004/03/04", null, ES.STOP, "Less than or equal to 3/4/2004", "-", false, true, false); | |||||
// "Time" validation type | |||||
wf.createDVTypeRow("Time ( cells are already formated as time - h:mm)"); | |||||
wf.createHeaderRow(); | |||||
va = wf.createValidationAdder(cellStyle_time, VT.TIME); | |||||
va.addValidation(OP.BETWEEN, "12:00", "16:00", ES.STOP, "Between 12:00 and 16:00 ", "Error box type = STOP", true, true, true); | |||||
va.addValidation(OP.NOT_BETWEEN, "12:00", "16:00", ES.INFO, "Not between 12:00 and 16:00 ", "Error box type = INFO", false, true, true); | |||||
va.addValidation(OP.EQUAL, "13:35", null, ES.WARNING, "Equal to 13:35", "Error box type = WARNING", false, false, true); | |||||
va.addValidation(OP.NOT_EQUAL, "13:35", null, ES.WARNING, "Not equal to 13:35", "-", false, false, false); | |||||
va.addValidation(OP.GREATER_THAN,"12:00", null, ES.WARNING, "Greater than 12:00", "-", true, false, false); | |||||
va.addValidation(OP.LESS_THAN, "=1/2", null, ES.WARNING, "Less than (1/2) -> 12:00", "-", true, true, false); | |||||
va.addValidation(OP.GREATER_OR_EQUAL, "14:00", null, ES.STOP, "Greater than or equal to 14:00", "Error box type = STOP", true, false, true); | |||||
va.addValidation(OP.LESS_OR_EQUAL,"14:00", null, ES.STOP, "Less than or equal to 14:00", "-", false, true, false); | |||||
} | |||||
private static void addTextLengthValidations(WorkbookFormatter wf) { | |||||
wf.createSheet("Text lengths"); | |||||
wf.createHeaderRow(); | |||||
ValidationAdder va = wf.createValidationAdder(null, VT.TEXT_LENGTH); | |||||
va.addValidation(OP.BETWEEN, "2", "6", ES.STOP, "Between 2 and 6 ", "Error box type = STOP", true, true, true); | |||||
va.addValidation(OP.NOT_BETWEEN, "2", "6", ES.INFO, "Not between 2 and 6 ", "Error box type = INFO", false, true, true); | |||||
va.addValidation(OP.EQUAL, "3", null, ES.WARNING, "Equal to 3", "Error box type = WARNING", false, false, true); | |||||
va.addValidation(OP.NOT_EQUAL, "3", null, ES.WARNING, "Not equal to 3", "-", false, false, false); | |||||
va.addValidation(OP.GREATER_THAN, "3", null, ES.WARNING, "Greater than 3", "-", true, false, false); | |||||
va.addValidation(OP.LESS_THAN, "3", null, ES.WARNING, "Less than 3", "-", true, true, false); | |||||
va.addValidation(OP.GREATER_OR_EQUAL, "4", null, ES.STOP, "Greater than or equal to 4", "Error box type = STOP", true, false, true); | |||||
va.addValidation(OP.LESS_OR_EQUAL, "4", null, ES.STOP, "Less than or equal to 4", "-", false, true, false); | |||||
} | |||||
public void testDataValidation() { | |||||
log("\nTest no. 2 - Test Excel's Data validation mechanism"); | |||||
Workbook wb = _testDataProvider.createWorkbook(); | |||||
WorkbookFormatter wf = new WorkbookFormatter(wb); | |||||
log(" Create sheet for Data Validation's number types ... "); | |||||
addSimpleNumericValidations(wf); | |||||
log("done !"); | |||||
log(" Create sheet for 'List' Data Validation type ... "); | |||||
addListValidations(wf, wb); | |||||
log("done !"); | |||||
log(" Create sheet for 'Date' and 'Time' Data Validation types ... "); | |||||
addDateTimeValidations(wf, wb); | |||||
log("done !"); | |||||
log(" Create sheet for 'Text length' Data Validation type... "); | |||||
addTextLengthValidations(wf); | |||||
log("done !"); | |||||
// Custom Validation type | |||||
log(" Create sheet for 'Custom' Data Validation type ... "); | |||||
addCustomValidations(wf); | |||||
log("done !"); | |||||
wb = _testDataProvider.writeOutAndReadBack(wb); | |||||
} | |||||
/* package */ static void setCellValue(Cell cell, String text) { | |||||
cell.setCellValue(text); | |||||
} | |||||
} |