EasyExcel下拉列表长度过长不显示【已修复】
背景
在使用easyexcel进行报表生成的时候,有需求要把字典数据塞到单元格中,easyexcel提供了一个直接生成下拉列表的方法,但是实际使用过程中,字典长度过长时,会导致下拉列表无数据的问题
环境
组件 | 版本 |
---|---|
jdk | 1.8 |
x-easypdf | 2.10.0 |
最新插入下拉数据方法
先创建一个隐藏的字典sheet,在对应列中插入字典数据,在原sheet里根据列序号找到字典sheet中对应的字典数据,作为下拉列表
java
/**
* 处理下拉数据
* @param sheet
* @param cell
*/
private void handleDropDown(Sheet sheet, Cell cell) {
String hiddenName = "hidden";
Workbook workbook = sheet.getWorkbook();
Sheet hidden = workbook.getSheet(hiddenName);
if(ObjectUtils.isEmpty(hidden)) {
hidden = workbook.createSheet(hiddenName);
}
// 设置隐藏
workbook.setSheetHidden(workbook.getSheetIndex(hidden), true);
DataValidationHelper helper = sheet.getDataValidationHelper();
Map<String, Map<String, String>> rowColMap = new HashMap<>();
Map<String, String> colReferMap = new HashMap<>();
if(ObjectUtils.isEmpty(needPickData)) {
return;
}
for (Integer k : needPickData.keySet()) {
List<Object> v = needPickData.get(k);
if(CollectionUtils.isEmpty(v)) {
continue;
}
String excelLine = getExcelLine(k);
List<Object> lists = v.stream().filter(ObjectUtils::isNotEmpty).distinct().collect(Collectors.toList());
colReferMap.put(k.toString(), "=" + hiddenName + "!$" + excelLine +
"$1:$" + excelLine + "$" + (lists.size()));
if(CollectionUtils.isEmpty(lists)) {
continue;
}
for (int i = 0; i < lists.size(); i++) {
Map<String, String> colMap = rowColMap.containsKey(Integer.toString(i))?rowColMap.get(Integer.toString(i)):new HashMap<>();
String value = lists.get(i).toString();
colMap.put(k.toString(), value);
rowColMap.put(Integer.toString(i), colMap);
}
}
if(rowColMap.size()>0) {
for (String rowNum : rowColMap.keySet().stream().sorted(Comparator.comparing(Integer::parseInt)).collect(Collectors.toList())) {
Row row = hidden.createRow(Integer.parseInt(rowNum));
if (rowColMap.get(rowNum).size() == 0) {
continue;
}
for (String colNum : rowColMap.get(rowNum).keySet().stream().sorted(Comparator.comparing(Integer::parseInt)).collect(Collectors.toList())) {
row.createCell(Integer.parseInt(colNum)).setCellValue(rowColMap.get(rowNum).get(colNum));
}
}
}
if(colReferMap.size()>0) {
for (String colNum : colReferMap.keySet().stream().sorted(Comparator.comparing(Integer::parseInt)).collect(Collectors.toList())) {
// 设置下拉列表的行: 首行,末行,首列,末列
CellRangeAddressList addressList = new CellRangeAddressList(cell.getRowIndex(), 10000, Integer.parseInt(colNum), Integer.parseInt(colNum));
DataValidationConstraint constraint = helper.createFormulaListConstraint(colReferMap.get(colNum));
DataValidation dataValidation = helper.createValidation(constraint, addressList);
sheet.addValidationData(dataValidation);
}
}
}
/**
* 返回excel列标A-Z-AA-ZZ
* @param num 列数
* @return java.lang.String
*/
public String getExcelLine ( int num){
String line = "";
int first = num / 26;
int second = num % 26;
if (first > 0) {
line = (char) ('A' + first - 1) + "";
}
line += (char) ('A' + second) + "";
return line;
}
旧版插入下拉数据方法
缺陷:字典长度过长时,无法插入下拉列表
java
/**
* 处理下拉数据
* @param sheet
* @param cell
*/
@Deprecated
private void handleDropDownOld(Sheet sheet, Cell cell) {
DataValidationHelper helper = sheet.getDataValidationHelper();
needPickData.forEach((k, v) -> {
// 设置下拉列表的行: 首行,末行,首列,末列
CellRangeAddressList rangeList = new CellRangeAddressList(cell.getRowIndex(), 100000, k, k);
// 设置下拉列表的值
if (CollectionUtils.isNotEmpty(v)){
List<Object> lists = v.stream().filter(ObjectUtils::isNotEmpty).distinct().collect(Collectors.toList());
if(CollectionUtils.isNotEmpty(lists)) {
String[] values = new String[lists.size()];
for (int i = 0; i < lists.size(); i++) {
values[i] = lists.get(i).toString();
}
DataValidationConstraint constraint = helper.createExplicitListConstraint(values);
// 设置约束
DataValidation validation = helper.createValidation(constraint, rangeList);
// 阻止输入非下拉选项的值
validation.setErrorStyle(DataValidation.ErrorStyle.STOP);
validation.setShowErrorBox(true);
validation.setSuppressDropDownArrow(true);
validation.createErrorBox("提示", "请输入下拉选项中的内容");
sheet.addValidationData(validation);
}
}
});
}