POI 生成 Excel ,生成下拉列表(有效性)即 Excel 中有效性的 序列,值可以是 按逗号分开的,但这种长度有限制。具体方法:
CellRangeAddressList rl = new CellRangeAddressList();
String[] list = {"aa","bb"};
CellRangeAddress address = new CellRangeAddress(flist.getFirstRow, lastRow, firstColumn, lastColumn);
rl.addCellRangeAddress(address);
DataValidation validation = null;
if (version == ExcelVersion.VERSION_2007) {
XSSFDataValidationHelper helper = new XSSFDataValidationHelper((XSSFSheet) sheet);
DataValidationConstraint constraint = helper.createExplicitListConstraint(list.getList());
validation = helper.createValidation(constraint, rl);
} else {
DVConstraint constraint = DVConstraint.createExplicitListConstraint();
validation = new HSSFDataValidation(rl, constraint);
}
validation.setEmptyCellAllowed(false);
// 是否出错警告
validation.setShowErrorBox(true);
validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
sheet.addValidationData(validation);
这种有限制,数组里的长度字节数。这个是因为 Excel 对表达式的长度的限制。
所以想到另一种办法,把数组输出在Excel上,再用表达式把这些数组取出来,如:$A$0:$A$10 ,这样表达式就短很多了。
具体表达式的计算,不用自己拼装,CellRangeAddress 这个类可以完成。
创建方法和上面的不太一样,思路都一样,代码如下:
if (version == ExcelVersion.VERSION_2007) {
XSSFDataValidationHelper helper = new XSSFDataValidationHelper((XSSFSheet) sheet);
DataValidationConstraint constraint = helper.createFormulaListConstraint(formula);
validation = helper.createValidation(constraint, rl);
} else {
DVConstraint constraint = DVConstraint.createFormulaListConstraint(formula);
validation = new HSSFDataValidation(rl, constraint);
}
对于这种感觉还不太好,在同一个Sheet里,在Excel里面是可以跨Sheet,在这需要把表达稍做下修改,用一个函数,INDIRECT ,如:INDIRECT("sheetName!$A$0:$A$10") ,这样就可以了。
在POI 3.8 以前,得自己拼,POI3.8开始,CellRangeAddress 上的 String formatAsString(String sheetName, boolean useAbsoluteAddress)这个方法可以实现。
这些,对于 2003 ,2007 都可以,2007的教程在网上比较少。
2003官网教程: http://poi.apache.org/spreadsheet/quick-guide.html#Validation