Patch from hishidama to add Sheet.getDataValidations() for HSSF and XSSF. This closes #11 from github

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1636857 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Nick Burch 2014-11-05 12:14:54 +00:00
parent 20438f4db5
commit 85d0a161b0
6 changed files with 398 additions and 4 deletions

View File

@ -18,9 +18,9 @@
package org.apache.poi.hssf.record;
import org.apache.poi.hssf.record.common.UnicodeString;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.hssf.usermodel.HSSFDataValidation;
import org.apache.poi.ss.formula.Formula;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.util.BitField;
@ -196,8 +196,29 @@ public final class DVRecord extends StandardRecord {
}
// <-- end option flags
public String getPromptTitle() {
return resolveTitleString(_promptTitle);
}
public String getErrorTitle() {
return resolveTitleString(_errorTitle);
}
public String getPromptText() {
return resolveTitleString(_promptText);
}
public String getErrorText() {
return resolveTitleString(_errorText);
}
public Ptg[] getFormula1() {
return Formula.getTokens(_formula1);
}
public Ptg[] getFormula2() {
return Formula.getTokens(_formula2);
}
public CellRangeAddressList getCellRangeAddress() {
return this._regions;
@ -285,6 +306,13 @@ public final class DVRecord extends StandardRecord {
return new UnicodeString(str);
}
private static String resolveTitleString(UnicodeString us) {
if (us == null || us.equals(NULL_TEXT_STRING)) {
return null;
}
return us.getString();
}
private static UnicodeString readUnicodeString(RecordInputStream in) {
return new UnicodeString(in);
}

View File

@ -17,15 +17,20 @@
package org.apache.poi.hssf.usermodel;
import java.text.MessageFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.regex.Pattern;
import org.apache.poi.hssf.model.HSSFFormulaParser;
import org.apache.poi.hssf.record.DVRecord;
import org.apache.poi.ss.formula.FormulaRenderer;
import org.apache.poi.ss.formula.FormulaRenderingWorkbook;
import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.formula.ptg.NumberPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.formula.ptg.StringPtg;
import org.apache.poi.ss.formula.FormulaType;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
/**
@ -429,4 +434,78 @@ public class DVConstraint implements DataValidationConstraint {
HSSFWorkbook wb = sheet.getWorkbook();
return HSSFFormulaParser.parse(formula, wb, FormulaType.CELL, wb.getSheetIndex(sheet));
}
static DVConstraint createDVConstraint(DVRecord dvRecord, FormulaRenderingWorkbook book) {
switch (dvRecord.getDataType()) {
case ValidationType.ANY:
return new DVConstraint(ValidationType.ANY, dvRecord.getConditionOperator(), null, null, null, null, null);
case ValidationType.INTEGER:
case ValidationType.DECIMAL:
case ValidationType.DATE:
case ValidationType.TIME:
case ValidationType.TEXT_LENGTH:
FormulaValuePair pair1 = toFormulaString(dvRecord.getFormula1(), book);
FormulaValuePair pair2 = toFormulaString(dvRecord.getFormula2(), book);
return new DVConstraint(dvRecord.getDataType(), dvRecord.getConditionOperator(), pair1.formula(),
pair2.formula(), pair1.value(), pair2.value(), null);
case ValidationType.LIST:
if (dvRecord.getListExplicitFormula()) {
String values = toFormulaString(dvRecord.getFormula1(), book).string();
if (values.startsWith("\"")) {
values = values.substring(1);
}
if (values.endsWith("\"")) {
values = values.substring(0, values.length() - 1);
}
String[] explicitListValues = values.split(Pattern.quote("\0"));
return createExplicitListConstraint(explicitListValues);
} else {
String listFormula = toFormulaString(dvRecord.getFormula1(), book).string();
return createFormulaListConstraint(listFormula);
}
case ValidationType.FORMULA:
return createCustomFormulaConstraint(toFormulaString(dvRecord.getFormula1(), book).string());
default:
throw new UnsupportedOperationException(MessageFormat.format("validationType={0}", dvRecord.getDataType()));
}
}
private static class FormulaValuePair {
private String _formula;
private String _value;
public String formula() {
return _formula;
}
public Double value() {
if (_value == null) {
return null;
}
return new Double(_value);
}
public String string() {
if (_formula != null) {
return _formula;
}
if (_value != null) {
return _value;
}
return null;
}
}
private static FormulaValuePair toFormulaString(Ptg[] ptgs, FormulaRenderingWorkbook book) {
FormulaValuePair pair = new FormulaValuePair();
if (ptgs != null && ptgs.length > 0) {
String string = FormulaRenderer.toFormulaString(book, ptgs);
if (ptgs.length == 1 && ptgs[0].getClass() == NumberPtg.class) {
pair._value = string;
} else {
pair._formula = string;
}
}
return pair;
}
}

View File

@ -44,6 +44,7 @@ import org.apache.poi.hssf.record.WSBoolRecord;
import org.apache.poi.hssf.record.WindowTwoRecord;
import org.apache.poi.hssf.record.aggregates.DataValidityTable;
import org.apache.poi.hssf.record.aggregates.FormulaRecordAggregate;
import org.apache.poi.hssf.record.aggregates.RecordAggregate.RecordVisitor;
import org.apache.poi.hssf.record.aggregates.WorksheetProtectionBlock;
import org.apache.poi.hssf.util.PaneInformation;
import org.apache.poi.ss.SpreadsheetVersion;
@ -60,6 +61,7 @@ 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.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.util.SSCellRange;
import org.apache.poi.ss.util.SheetUtil;
@ -394,6 +396,35 @@ public final class HSSFSheet implements org.apache.poi.ss.usermodel.Sheet {
return _lastrow;
}
public List<HSSFDataValidation> getDataValidations() {
DataValidityTable dvt = _sheet.getOrCreateDataValidityTable();
final List<HSSFDataValidation> hssfValidations = new ArrayList<HSSFDataValidation>();
RecordVisitor visitor = new RecordVisitor() {
private HSSFEvaluationWorkbook book = HSSFEvaluationWorkbook.create(getWorkbook());
@Override
public void visitRecord(Record r) {
if (!(r instanceof DVRecord)) {
return;
}
DVRecord dvRecord = (DVRecord) r;
CellRangeAddressList regions = dvRecord.getCellRangeAddress().copy();
DVConstraint constraint = DVConstraint.createDVConstraint(dvRecord, book);
HSSFDataValidation hssfDataValidation = new HSSFDataValidation(regions, constraint);
hssfDataValidation.setErrorStyle(dvRecord.getErrorStyle());
hssfDataValidation.setEmptyCellAllowed(dvRecord.getEmptyCellAllowed());
hssfDataValidation.setSuppressDropDownArrow(dvRecord.getSuppressDropdownArrow());
hssfDataValidation.createPromptBox(dvRecord.getPromptTitle(), dvRecord.getPromptText());
hssfDataValidation.setShowPromptBox(dvRecord.getShowPromptOnCellSelected());
hssfDataValidation.createErrorBox(dvRecord.getErrorTitle(), dvRecord.getErrorText());
hssfDataValidation.setShowErrorBox(dvRecord.getShowErrorOnInvalidValue());
hssfValidations.add(hssfDataValidation);
}
};
dvt.visitContainedRecords(visitor);
return hssfValidations;
}
/**
* Creates a data validation object
*

View File

@ -18,6 +18,7 @@
package org.apache.poi.ss.usermodel;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.hssf.util.PaneInformation;
import org.apache.poi.ss.util.CellRangeAddress;
@ -921,6 +922,12 @@ public interface Sheet extends Iterable<Row> {
public DataValidationHelper getDataValidationHelper();
/**
* Returns the list of DataValidation in the sheet.
* @return list of DataValidation in the sheet
*/
public List<? extends DataValidation> getDataValidations();
/**
* Creates a data validation object
* @param dataValidation The Data validation object settings

View File

@ -20,6 +20,7 @@ package org.apache.poi.xssf.streaming;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
@ -42,6 +43,7 @@ import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.SheetUtil;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetFormatPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
@ -1339,6 +1341,11 @@ public class SXSSFSheet implements Sheet, Cloneable
return _sh.getDataValidationHelper();
}
public List<XSSFDataValidation> getDataValidations()
{
return _sh.getDataValidations();
}
/**
* Creates a data validation object
* @param dataValidation The Data validation object settings

View File

@ -24,6 +24,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.List;
import junit.framework.AssertionFailedError;
@ -34,7 +35,16 @@ import org.apache.poi.hssf.eventmodel.EventRecordFactory;
import org.apache.poi.hssf.record.DVRecord;
import org.apache.poi.hssf.record.RecordFormatException;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.BaseTestDataValidation;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationConstraint.OperatorType;
import org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
/**
@ -209,4 +219,236 @@ public final class TestDataValidation extends BaseTestDataValidation {
}
return -1;
}
public void testGetDataValidationsAny() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
List<HSSFDataValidation> list = sheet.getDataValidations();
assertEquals(0, list.size());
DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = dataValidationHelper.createNumericConstraint(ValidationType.ANY,
OperatorType.IGNORED, null, null);
CellRangeAddressList addressList = new CellRangeAddressList(1, 2, 3, 4);
DataValidation validation = dataValidationHelper.createValidation(constraint, addressList);
validation.setEmptyCellAllowed(true);
validation.createErrorBox("error-title", "error-text");
validation.createPromptBox("prompt-title", "prompt-text");
sheet.addValidationData(validation);
list = sheet.getDataValidations(); // <-- works
assertEquals(1, list.size());
HSSFDataValidation dv = list.get(0);
{
CellRangeAddressList regions = dv.getRegions();
assertEquals(1, regions.countRanges());
CellRangeAddress address = regions.getCellRangeAddress(0);
assertEquals(1, address.getFirstRow());
assertEquals(2, address.getLastRow());
assertEquals(3, address.getFirstColumn());
assertEquals(4, address.getLastColumn());
}
assertEquals(true, dv.getEmptyCellAllowed());
assertEquals(false, dv.getSuppressDropDownArrow());
assertEquals(true, dv.getShowErrorBox());
assertEquals("error-title", dv.getErrorBoxTitle());
assertEquals("error-text", dv.getErrorBoxText());
assertEquals(true, dv.getShowPromptBox());
assertEquals("prompt-title", dv.getPromptBoxTitle());
assertEquals("prompt-text", dv.getPromptBoxText());
DataValidationConstraint c = dv.getValidationConstraint();
assertEquals(ValidationType.ANY, c.getValidationType());
assertEquals(OperatorType.IGNORED, c.getOperator());
}
public void testGetDataValidationsIntegerFormula() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
List<HSSFDataValidation> list = sheet.getDataValidations();
assertEquals(0, list.size());
DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = dataValidationHelper.createIntegerConstraint(OperatorType.BETWEEN, "=A2",
"=A3");
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
DataValidation validation = dataValidationHelper.createValidation(constraint, addressList);
sheet.addValidationData(validation);
list = sheet.getDataValidations(); // <-- works
assertEquals(1, list.size());
HSSFDataValidation dv = list.get(0);
DVConstraint c = dv.getConstraint();
assertEquals(ValidationType.INTEGER, c.getValidationType());
assertEquals(OperatorType.BETWEEN, c.getOperator());
assertEquals("A2", c.getFormula1());
assertEquals("A3", c.getFormula2());
assertEquals(null, c.getValue1());
assertEquals(null, c.getValue2());
}
public void testGetDataValidationsIntegerValue() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
List<HSSFDataValidation> list = sheet.getDataValidations();
assertEquals(0, list.size());
DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = dataValidationHelper.createIntegerConstraint(OperatorType.BETWEEN, "100",
"200");
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
DataValidation validation = dataValidationHelper.createValidation(constraint, addressList);
sheet.addValidationData(validation);
list = sheet.getDataValidations(); // <-- works
assertEquals(1, list.size());
HSSFDataValidation dv = list.get(0);
DVConstraint c = dv.getConstraint();
assertEquals(ValidationType.INTEGER, c.getValidationType());
assertEquals(OperatorType.BETWEEN, c.getOperator());
assertEquals(null, c.getFormula1());
assertEquals(null, c.getFormula2());
assertEquals(new Double("100"), c.getValue1());
assertEquals(new Double("200"), c.getValue2());
}
public void testGetDataValidationsDecimal() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
List<HSSFDataValidation> list = sheet.getDataValidations();
assertEquals(0, list.size());
DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = dataValidationHelper.createDecimalConstraint(OperatorType.BETWEEN, "=A2",
"200");
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
DataValidation validation = dataValidationHelper.createValidation(constraint, addressList);
sheet.addValidationData(validation);
list = sheet.getDataValidations(); // <-- works
assertEquals(1, list.size());
HSSFDataValidation dv = list.get(0);
DVConstraint c = dv.getConstraint();
assertEquals(ValidationType.DECIMAL, c.getValidationType());
assertEquals(OperatorType.BETWEEN, c.getOperator());
assertEquals("A2", c.getFormula1());
assertEquals(null, c.getFormula2());
assertEquals(null, c.getValue1());
assertEquals(new Double("200"), c.getValue2());
}
public void testGetDataValidationsDate() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
List<HSSFDataValidation> list = sheet.getDataValidations();
assertEquals(0, list.size());
DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = dataValidationHelper.createDateConstraint(OperatorType.EQUAL,
"2014/10/25", null, null);
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
DataValidation validation = dataValidationHelper.createValidation(constraint, addressList);
sheet.addValidationData(validation);
list = sheet.getDataValidations(); // <-- works
assertEquals(1, list.size());
HSSFDataValidation dv = list.get(0);
DVConstraint c = dv.getConstraint();
assertEquals(ValidationType.DATE, c.getValidationType());
assertEquals(OperatorType.EQUAL, c.getOperator());
assertEquals(null, c.getFormula1());
assertEquals(null, c.getFormula2());
assertEquals(DateUtil.getExcelDate(DateUtil.parseYYYYMMDDDate("2014/10/25")), c.getValue1());
assertEquals(null, c.getValue2());
}
public void testGetDataValidationsListExplicit() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
List<HSSFDataValidation> list = sheet.getDataValidations();
assertEquals(0, list.size());
DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = dataValidationHelper.createExplicitListConstraint(new String[] { "aaa",
"bbb", "ccc" });
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
DataValidation validation = dataValidationHelper.createValidation(constraint, addressList);
validation.setSuppressDropDownArrow(true);
sheet.addValidationData(validation);
list = sheet.getDataValidations(); // <-- works
assertEquals(1, list.size());
HSSFDataValidation dv = list.get(0);
assertEquals(true, dv.getSuppressDropDownArrow());
DVConstraint c = dv.getConstraint();
assertEquals(ValidationType.LIST, c.getValidationType());
assertEquals(null, c.getFormula1());
assertEquals(null, c.getFormula2());
assertEquals(null, c.getValue1());
assertEquals(null, c.getValue2());
String[] values = c.getExplicitListValues();
assertEquals(3, values.length);
assertEquals("aaa", values[0]);
assertEquals("bbb", values[1]);
assertEquals("ccc", values[2]);
}
public void testGetDataValidationsListFormula() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
List<HSSFDataValidation> list = sheet.getDataValidations();
assertEquals(0, list.size());
DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = dataValidationHelper.createFormulaListConstraint("A2");
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
DataValidation validation = dataValidationHelper.createValidation(constraint, addressList);
validation.setSuppressDropDownArrow(true);
sheet.addValidationData(validation);
list = sheet.getDataValidations(); // <-- works
assertEquals(1, list.size());
HSSFDataValidation dv = list.get(0);
assertEquals(true, dv.getSuppressDropDownArrow());
DVConstraint c = dv.getConstraint();
assertEquals(ValidationType.LIST, c.getValidationType());
assertEquals("A2", c.getFormula1());
assertEquals(null, c.getFormula2());
assertEquals(null, c.getValue1());
assertEquals(null, c.getValue2());
}
public void testGetDataValidationsFormula() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet();
List<HSSFDataValidation> list = sheet.getDataValidations();
assertEquals(0, list.size());
DataValidationHelper dataValidationHelper = sheet.getDataValidationHelper();
DataValidationConstraint constraint = dataValidationHelper.createCustomConstraint("A2:A3");
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
DataValidation validation = dataValidationHelper.createValidation(constraint, addressList);
sheet.addValidationData(validation);
list = sheet.getDataValidations(); // <-- works
assertEquals(1, list.size());
HSSFDataValidation dv = list.get(0);
DVConstraint c = dv.getConstraint();
assertEquals(ValidationType.FORMULA, c.getValidationType());
assertEquals("A2:A3", c.getFormula1());
assertEquals(null, c.getFormula2());
assertEquals(null, c.getValue1());
assertEquals(null, c.getValue2());
}
}