最近由于项目升级,jdk升级到了17。原来的EasyPOI不支持新版jdk,只能改为EasyExcel。但是两个框架差别比较大,所有踩了很多坑。
支持List和Map数据格式
在使用EasyExcel时网上大多数案例是通过封装类加主键进行数据绑定的。但是EasyExcel也支持List和Map数据格式,可以通过Map封装单个数据或通过List<Map>封装列表数据。
模版占位符
在根据模版导出数据时,要预先设置占位符。包括,单个数据占位符和列表数据占位符。
单个占位符:{字段名} 如:{name}
列表占位符:{.字段名} 如:{.num},如果一个表格中有多个数据列,占位符前要加前缀,如:{studentList.name}、{classList.name}

String path = "C:\\Users\\yunhe\\Desktop\\templates\\farm1.xlsx";
// 填充配置
FillConfig fillConfig = FillConfig.builder()
.forceNewRow(Boolean.TRUE) //强制新增行,每次填充数据都新增一行
.build();
// 获取excel模版中的表格
WriteSheet oneSheet = EasyExcel.writerSheet(0)
.registerWriteHandler(new MyExcelHandler()) //注册合并策略
.build();
OutputStream outputStream = response.getOutputStream();
// 模版文件
InputStream file = new FileInputStream(path);
// 创建Writer对象
ExcelWriter excelWriter = EasyExcel.write(outputStream).withTemplate(file)
.excelType(ExcelTypeEnum.XLSX).build();
// 填充单个数据(封装在Map对象中)
excelWriter.fill(paramData, oneSheet);
// 填充列表数据
excelWriter.fill(new FillWrapper("l1",landReturnPlanList),fillConfig, oneSheet);
// 填充多个列表数据
excelWriter.fill(new FillWrapper("l2",thirdPartyProcessingPlanList),fillConfig, oneSheet);
//流的形式传输数据
response.setHeader("content-type", "application/octet-stream");
//防止中文乱码
String fileNameUrl = "数据.xlsx";
response.setHeader("content-disposition", "attachment;filename=" + fileNameUrl + ";" + "filename*=utf-8''" + fileNameUrl);
excelWriter.finish();
单元格合并策略
当模版中列表数据中有合并单元格时,通过自定义合并策略对象实现。下面时通用合并策略类实现,可以自动复制当前sheel中所有列表数据中的单元格合并效果。
/**
* 自动复制单元格合并
*/
class MyExcelHandler extends AbstractMergeStrategy {
protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
if(relativeRowIndex==null ||relativeRowIndex==0){
return;
}
int rowIndex = cell.getRowIndex();
int colIndex = cell.getColumnIndex();
sheet=cell.getSheet();
Row preRow = sheet.getRow(rowIndex - 1);
Cell preCell = preRow.getCell(colIndex);//获取上一行的该格
List<CellRangeAddress> list = sheet.getMergedRegions();
CellStyle cs = cell.getCellStyle();
cell.setCellStyle(cs);
for (int i = 0; i < list.size(); i++) {
CellRangeAddress cellRangeAddress = list.get(i);
if (cellRangeAddress.containsRow(preCell.getRowIndex()) && cellRangeAddress.containsColumn(preCell.getColumnIndex())) {
int lastColIndex = cellRangeAddress.getLastColumn();
int firstColIndex = cellRangeAddress.getFirstColumn();
CellRangeAddress cra = new CellRangeAddress(cell.getRowIndex(), cell.getRowIndex(), firstColIndex, lastColIndex);
sheet.addMergedRegion(cra);
/*RegionUtil.setBorderBottom(BorderStyle.THIN, cra, sheet);
RegionUtil.setBorderLeft(BorderStyle.THIN, cra, sheet);
RegionUtil.setBorderRight(BorderStyle.THIN, cra, sheet);
RegionUtil.setBorderTop(BorderStyle.THIN, cra, sheet);*/
return;
}
}
}
}
1、注册合并策略
WriteSheet oneSheet = EasyExcel.writerSheet(0)
.registerWriteHandler(new MyExcelHandler()) //注册合并策略
.build();
2、填充配置开启强行新增行
FillConfig fillConfig = FillConfig.builder()
.forceNewRow(Boolean.TRUE) //强制新增行,每次填充数据都新增一行
.build();
至此,同时包含当数据、多类别数据集、列合并表格等复杂模版导出就可以轻松实现。
