Java技术栈2024-10-23 · 约 10 分钟
Springboot中解决EasyExcel导出的下拉框总字符超过255就打不开
1. 自定义SheetWriteHandler
java
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;
import java.util.Map;
/**
* 多列需要下拉框用Map来装数据,key为需要下拉框的列,value为该列下拉框的值;这里设置了序号为1到5000的行需要下拉框;
*/
public class CustomSheetWriteHandler implements SheetWriteHandler {
private Map<Integer, String[]> map;
private int index;
public CustomSheetWriteHandler(Map<Integer, String[]> map) {
this.map = map;
this.index = 0;
}
@Override
public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
}
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
DataValidationHelper helper = writeSheetHolder.getSheet().getDataValidationHelper();
// k 为存在下拉数据集的单元格下表 v为下拉数据集
map.forEach((k, v) -> {
// 创建sheet,突破下拉框255的限制
// 获取一个workbook
Workbook workbook = writeWorkbookHolder.getWorkbook();
// 定义sheet的名称
String sheetName = "sheet" + k;
// 1.创建一个隐藏的sheet 名称为 proviceSheet
Sheet proviceSheet = workbook.createSheet(sheetName);
// 从第二个工作簿开始隐藏
this.index++;
// 设置隐藏
workbook.setSheetHidden(this.index, true);
// 2.循环赋值(为了防止下拉框的行数与隐藏域的行数相对应,将隐藏域加到结束行之后)
for (int i = 0, length = v.length; i < length; i++) {
// i:表示你开始的行数 0表示你开始的列数
proviceSheet.createRow(i).createCell(0).setCellValue(v[i]);
}
Name category1Name = workbook.createName();
category1Name.setNameName(sheetName);
// 4 $A$1:$A$N代表 以A列1行开始获取N行下拉数据
category1Name.setRefersToFormula(sheetName + "!$A$1:$A$" + (v.length));
// 5 将刚才设置的sheet引用到你的下拉列表中,1表示从行的序号1开始(开始行,通常行的序号为0的行是表头),5000表示行的序号5000(结束行),表示从行的序号1到5000,k表示开始列序号和结束列序号
CellRangeAddressList addressList = new CellRangeAddressList(1, 5000, k, k);
DataValidationConstraint constraint = helper.createFormulaListConstraint(sheetName);
DataValidation dataValidation = helper.createValidation(constraint, addressList);
dataValidation.setErrorStyle(DataValidation.ErrorStyle.STOP);
dataValidation.setShowErrorBox(true);
dataValidation.setSuppressDropDownArrow(true);
dataValidation.createErrorBox("提示", "请输入下拉选项中的内容");
writeSheetHolder.getSheet().addValidationData(dataValidation);
});
}
}
2. 具体用法
java
@Override
public void templateDownload() {
HashMap<Integer, String[]> map = new HashMap<>();
//性别
String[] genders = {"男", "女"};
map.put(3, genders);
//身份
List<UserIdentity> identityList = getIdentityList();
String[] identityNames = identityList.stream().map(UserIdentity::getName).toArray(String[]::new);
map.put(4, identityNames);
try {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + "downloadTemplate.xlsx");
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
WriteSheet sheet = EasyExcel
.writerSheet("全部")
.registerWriteHandler(new CustomSheetWriteHandler(map))
.head(ExcelObjectTemplate.class).build();
List<ExcelObjectTemplate> list = Arrays.asList(new ExcelObjectTemplate());
excelWriter.write(list, sheet).finish();
} catch (Exception e) {
log.error("下载模板异常,{}", e.getMessage());
}
}
觉得有用就点个赞吧