本文将继续介绍POI的使用,上接在Java中使用Apache POI导入导出Excel(四)
使用Apache POI组件操作Excel(五)
38、数据验证
当您创建基于 xml 的 SpreadsheetML 时,数据验证的工作方式类似。 工作簿文件;但也有不同之处。显式强制转换是必需的,例如 在一些地方,对 XSSF 流中的数据验证的支持与 XSSF 流中 内置于 Unifying SS 流中,稍后会详细介绍。其他差异包括 在代码中用注释表示。
根据一个或多个预定义值检查用户在单元格中输入的值。
java
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Data Validation");
XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
dvHelper.createExplicitListConstraint(new String[]{"11", "21", "31"});
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
XSSFDataValidation validation =(XSSFDataValidation)dvHelper.createValidation(
dvConstraint, addressList);
// Here the boolean value false is passed to the setSuppressDropDownArrow()
// method. In the hssf.usermodel examples above, the value passed to this
// method is true.
validation.setSuppressDropDownArrow(false);
// Note this extra method call. If this method call is omitted, or if the
// boolean value false is passed, then Excel will not validate the value the
// user enters into the cell.
validation.setShowErrorBox(true);
sheet.addValidationData(validation);
下拉列表:
此代码将执行相同的操作,但为用户提供一个下拉列表以从中选择一个值。
java
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Data Validation");
XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
dvHelper.createExplicitListConstraint(new String[]{"11", "21", "31"});
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
XSSFDataValidation validation = (XSSFDataValidation)dvHelper.createValidation(
dvConstraint, addressList);
validation.setShowErrorBox(true);
sheet.addValidationData(validation);
请注意,对 setSuppressDropDowmArrow() 方法的调用可以简单地排除或替换为:
java
validation.setSuppressDropDownArrow(true);
提示和错误消息:
这两个都完全反映了 hssf.usermodel,因此请参阅上面的 'Messages On Error:' 和 'Prompts:' 部分。
进一步的数据验证:
例如,要获取将检查输入值的验证,请执行以下操作: 一个介于 10 和 100 之间的整数,请使用 XSSFDataValidationHelper(s) createNumericConstraint(int, int, String, String) 工厂方法。
java
SSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
dvHelper.createNumericConstraint(
XSSFDataValidationConstraint.ValidationType.INTEGER,
XSSFDataValidationConstraint.OperatorType.BETWEEN,
"10", "100");
传递给最后两个 String 参数的值可以是公式;'=' 符号用于表示公式。 因此,以下代码将创建验证,仅当值介于两个单元格范围求和的结果之间时,才允许值
java
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
dvHelper.createNumericConstraint(
XSSFDataValidationConstraint.ValidationType.INTEGER,
XSSFDataValidationConstraint.OperatorType.BETWEEN,
"=SUM(A1:A10)", "=SUM(B24:B27)");
如果调用 createNumericConstraint() 方法,则无法创建下拉列表。 setSuppressDropDownArrow(true) 方法调用将被忽略。
请检查 javadoc 以了解其他约束类型,因为此处不包含这些类型的示例。 例如,在 XSSFDataValidationHelper 类上定义了一些方法,允许您创建 以下类型的约束;日期、时间、小数、整数、数字、公式、文本长度和自定义约束。
从电子表格单元格创建数据验证:
上面未提及的另一种类型的约束是公式列表约束。 它允许您创建一个验证,该验证从一系列单元格中获取其值。此代码
java
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
dvHelper.createFormulaListConstraint("$A$1:$F$1");
将创建一个验证,该验证从范围 A1 到 F1 中的单元格获取其值。
如果你使用这样的命名范围,则可以扩展这种技术的有用性;
java
XSSFName name = workbook.createName();
name.setNameName("data");
name.setRefersToFormula("$B$1:$F$1");
XSSFDataValidationHelper dvHelper = new XSSFDataValidationHelper(sheet);
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)
dvHelper.createFormulaListConstraint("data");
CellRangeAddressList addressList = new CellRangeAddressList(
0, 0, 0, 0);
XSSFDataValidation validation = (XSSFDataValidation)
dvHelper.createValidation(dvConstraint, addressList);
validation.setSuppressDropDownArrow(true);
validation.setShowErrorBox(true);
sheet.addValidationData(validation);
OpenOffice Calc 在名称范围方面的规则略有不同。 Excel 同时支持名称的 Workbook 和 Sheet 范围,但 Calc 不支持,它似乎只支持名称的 Sheet 范围。 因此,通常最好为区域或区域完全限定名称,例如:
java
XSSFName name = workbook.createName();
name.setNameName("data");
name.setRefersToFormula("'Data Validation'!$B$1:$F$1");
....
然而,这确实提供了一个更有趣的机会,那就是将验证的所有数据放入工作簿中隐藏工作表上的命名单元格区域中。然后可以在 setRefersToFormula() 方法参数中显式标识这些范围。
39、ss.user模型
ss.usermodel 包中的类允许开发人员创建可以使用的代码 生成二进制 (.xls) 和 SpreadsheetML (.xlsx) 工作簿。
用于创建数据验证的技术与上面的 xssf.usermodel 示例有很多共同之处。 因此,这里将只介绍一两个示例。
根据一个或多个预定义值检查用户在单元格中输入的值。
java
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Data Validation");
DataValidationHelper dvHelper = sheet.getDataValidationHelper();
DataValidationConstraint dvConstraint = dvHelper.createExplicitListConstraint(
new String[]{"13", "23", "33"});
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
DataValidation validation = dvHelper.createValidation(
dvConstraint, addressList);
// Note the check on the actual type of the DataValidation object.
// If it is an instance of the XSSFDataValidation class then the
// boolean value 'false' must be passed to the setSuppressDropDownArrow()
// method and an explicit call made to the setShowErrorBox() method.
if(validation instanceof XSSFDataValidation) {
validation.setSuppressDropDownArrow(false);
validation.setShowErrorBox(true);
}
else {
// If the Datavalidation contains an instance of the HSSFDataValidation
// class then 'true' should be passed to the setSuppressDropDownArrow()
// method and the call to setShowErrorBox() is not necessary.
validation.setSuppressDropDownArrow(true);
}
sheet.addValidationData(validation);
下拉列表:
此代码将执行相同的操作,但为用户提供一个下拉列表以从中选择一个值。
java
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Data Validation");
DataValidationHelper dvHelper = sheet.getDataValidationHelper();
DataValidationConstraint dvConstraint = dvHelper.createExplicitListConstraint(
new String[]{"13", "23", "33"});
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
DataValidation validation = dvHelper.createValidation(
dvConstraint, addressList);
// Note the check on the actual type of the DataValidation object.
// If it is an instance of the XSSFDataValidation class then the
// boolean value 'false' must be passed to the setSuppressDropDownArrow()
// method and an explicit call made to the setShowErrorBox() method.
if(validation instanceof XSSFDataValidation) {
validation.setSuppressDropDownArrow(true);
validation.setShowErrorBox(true);
}
else {
// If the Datavalidation contains an instance of the HSSFDataValidation
// class then 'true' should be passed to the setSuppressDropDownArrow()
// method and the call to setShowErrorBox() is not necessary.
validation.setSuppressDropDownArrow(false);
}
sheet.addValidationData(validation);
提示和错误消息:
这两个都完全反映了 hssf.usermodel,因此请参阅上面的 'Messages On Error:' 和 'Prompts:' 部分。
由于 ss.usermodel 和 xssf.usermodel 示例之间的差异很小 - 主要受限于 DataValidationHelper 的获取方式,缺少任何 需要显式转换数据类型和 setSuppressDropDowmArrow() 方法的 hssf 和 xssf 解释, 本节将不再包含更多示例。
高级数据验证。
Dependent 下拉列表。
在某些情况下,可能需要向用户显示包含多个下拉列表的工作表。 此外,用户在一个下拉列表中所做的选择可能会影响 第二个或后续下拉列表。现在将解释一种可能用于实现此行为的技术。
该技术有两个关键;一种是使用命名区域或单元格区域来保存下拉列表的数据, 第二种是使用 INDIRECT() 函数在单元格的名称和实际地址之间进行转换。 在示例部分中,有一个完整的工作示例------称为 LinkedDropDownLists.java - 演示如何创建链接或依赖下拉列表。这里只解释了更相关的要点。
要创建两个下拉列表,其中第二个下拉列表中显示的选项取决于第一个下拉列表中的选择, 首先,创建一个命名的单元格区域,以保存用于填充第一个下拉列表的所有数据。 接下来,创建一个数据验证,该验证将查找此命名区域的数据,如下所示:
java
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
DataValidationHelper dvHelper = sheet.getDataValidationHelper();
DataValidationConstraint dvConstraint = dvHelper.createFormulaListConstraint(
"CHOICES");
DataValidation validation = dvHelper.createValidation(
dvConstraint, addressList);
sheet.addValidationData(validation);
请注意,区域的名称 - 在上面的示例中是 'CHOICES' - )被简单地传递给 createFormulaListConstraint() 方法。这就足够了 使 Excel 使用来自该命名区域的数据填充下拉列表。
接下来,对于用户可以在第一个下拉列表中选择的每个选项, 创建匹配的命名单元格区域。该区域的名称应与 用户可以在第一个下拉列表中选择的文本。请注意,在示例中, 单元格区域的名称中使用所有大写字母。
现在,可以使用非常相似的代码来创建第二个链接的下拉列表:
java
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 1, 1);
DataValidationConstraint dvConstraint = dvHelper.createFormulaListConstraint(
"INDIRECT(UPPER($A$1))");
DataValidation validation = dvHelper.createValidation(
dvConstraint, addressList);
sheet.addValidationData(validation);
此处的关键位于以下 Excel 函数 INDIRECT(UPPER($A$1)) 中,该函数用于填充第二个 linked,下拉列表。从最里面的一对括号开始,它指示 Excel 查看 在单元格 A1 的内容中,将其读取的内容转换为大写 - 因为使用了大写字母 在每个区域的名称中 - 然后将此名称转换为包含 要填充另一个 (Data to populate another) 下拉列表。
40、嵌入对象
可以对嵌入的 Excel、Word 或 PowerPoint 文档进行更详细的处理, 或处理任何其他类型的嵌入对象。
java
XSSFWorkbook workbook = new XSSFWorkbook("excel_with_embeded.xlsx");
for (PackagePart pPart : workbook.getAllEmbeddedParts()) {
String contentType = pPart.getContentType();
// Excel Workbook - either binary or OpenXML
if (contentType.equals("application/vnd.ms-excel")) {
HSSFWorkbook embeddedWorkbook = new HSSFWorkbook(pPart.getInputStream());
}
// Excel Workbook - OpenXML file format
else if (contentType.equals("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) {
OPCPackage docPackage = OPCPackage.open(pPart.getInputStream());
XSSFWorkbook embeddedWorkbook = new XSSFWorkbook(docPackage);
}
// Word Document - binary (OLE2CDF) file format
else if (contentType.equals("application/msword")) {
HWPFDocument document = new HWPFDocument(pPart.getInputStream());
}
// Word Document - OpenXML file format
else if (contentType.equals("application/vnd.openxmlformats-officedocument.wordprocessingml.document")) {
OPCPackage docPackage = OPCPackage.open(pPart.getInputStream());
XWPFDocument document = new XWPFDocument(docPackage);
}
// PowerPoint Document - binary file format
else if (contentType.equals("application/vnd.ms-powerpoint")) {
HSLFSlideShow slideShow = new HSLFSlideShow(pPart.getInputStream());
}
// PowerPoint Document - OpenXML file format
else if (contentType.equals("application/vnd.openxmlformats-officedocument.presentationml.presentation")) {
OPCPackage docPackage = OPCPackage.open(pPart.getInputStream());
XSLFSlideShow slideShow = new XSLFSlideShow(docPackage);
}
// Any other type of embedded object.
else {
System.out.println("Unknown Embedded Document: " + contentType);
InputStream inputStream = pPart.getInputStream();
}
}
41、自动过滤器
java
Workbook wb = new XSSFWorkbook();
Sheet sheet = wb.createSheet();
sheet.setAutoFilter(CellRangeAddress.valueOf("C5:F200"));
42、条件格式
java
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet();
SheetConditionalFormatting sheetCF = sheet.getSheetConditionalFormatting();
ConditionalFormattingRule rule1 = sheetCF.createConditionalFormattingRule(ComparisonOperator.EQUAL, "0");
FontFormatting fontFmt = rule1.createFontFormatting();
fontFmt.setFontStyle(true, false);
fontFmt.setFontColorIndex(IndexedColors.DARK_RED.index);
BorderFormatting bordFmt = rule1.createBorderFormatting();
bordFmt.setBorderBottom(BorderStyle.THIN);
bordFmt.setBorderTop(BorderStyle.THICK);
bordFmt.setBorderLeft(BorderStyle.DASHED);
bordFmt.setBorderRight(BorderStyle.DOTTED);
PatternFormatting patternFmt = rule1.createPatternFormatting();
patternFmt.setFillBackgroundColor(IndexedColors.YELLOW.index);
ConditionalFormattingRule rule2 = sheetCF.createConditionalFormattingRule(ComparisonOperator.BETWEEN, "-10", "10");
ConditionalFormattingRule [] cfRules =
{
rule1, rule2
};
CellRangeAddress[] regions = {
CellRangeAddress.valueOf("A3:A5")
};
sheetCF.addConditionalFormatting(regions, cfRules);