由于业务需求,我需要处理一个excel表,读取数据库中的信息并作为下拉列表(即数据验证,旧版的叫数据有效性)添加到excel表中。由于是新版的excel, 这里就不考虑HSSF而是直接使用XSSF。
首先,由于我对poi,xssf这个东西不熟,所以直接采用createExplicitListConstraint实现,但是一开始就报错了。打开生成的excel表提示:
"无法读取表中的某些数据,如果对其信任,是否对数据源进行修复?"
选择“是”,就会发现弹出这样一个提示:
"已删除的功能:../../xx.xml,的数据验证"
然后数据验证功能被完全删除!
这是为什么呢?一开始,我以为是编码问题,后来发现不是,又以为是中文问题,手动测试后发现也不是。难道是因为出现了空格和特殊字符?都不是!我小心翼翼地测试,发现有时候报错有时候不报错,但总体规律就是:数据验证的条数越多、每条的字数越多,报错的几率越大。
后面,我终于知道了,这个它这个功能固有的缺陷,那怎么办?方法就是改用createFormulaListConstraint,创建一个隐藏的sheet,并往里放入枚举项,然后在真正的sheet内增加关联关系!
具体的实现步骤如下:
public static Workbook XSSFSetDropDownAndHidden(String[] formulaString) {
Workbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("mysheet");
// 创建隐藏sheet,写入枚举项
Sheet hideSheet = workbook.createSheet("hiddenSheet");
for (int i = 0; i < formulaString.length; i++) {
hideSheet.createRow(i).createCell(0).setCellValue(formulaString[i]);
}
// 创建名称,作用是被其他单元格引用
Name categoryName = workbook.createName();
categoryName.setNameName("hidden");
// 设置名称引用的公式
categoryName.setRefersToFormula("hiddenSheet!" + "$A$1:$A$" + formulaString.length);
//由于在hiddensheet中的每一行的第一个格子我们放入了等同于length的数据,所以这里用绝对引用第一列的1到length的数据
// 设置下拉单位格范围,第5列的1到1024
CellRangeAddressList regions = new CellRangeAddressList(0,1024,4,4);
//获取数据
XSSFDataValidationHelper dvHelper = (XSSFDataValidationHelper) sheet.getDataValidationHelper();
XSSFDataValidationConstraint dvConstraint = (XSSFDataValidationConstraint)dvHelper.createFormulaListConstraint("hidden");
//将数据关联
XSSFDataValidation dataValidation = (XSSFDataValidation)dvHelper.createValidation(dvConstraint,regions);
//其他设置
dataValidation.setSuppressDropDownArrow(true);
dataValidation.setShowErrorBox(true);
//添加到sheet中
sheet.addValidationData(dataValidation);
//设置隐藏
workBook.setSheetHidden(1,true);
return workbook;
}
最后感谢博客园的"(00)"的博文。
网友评论