EasyExcel导出Excel文件——合并单元格多层级数据导出
数据映射:利用Map和Stream API进行数据转换,提高代码的可读性和效率。HTTP响应处理:设置正确的响应头以实现文件下载,以及解决中文乱码问题。EasyExcel库:简化Excel文件的生成和读取过程,提升开发效率。单元格合并:通过自定义策略实现Excel中数据的分组和单元格合并,提升报表的可读性。
合并单元格多层数据导出
思维脑图

代码实现
java
代码解读
复制代码
/** * 导出所有信息 * * @param request 请求体 */ @Override public void getWilliamExportList(WilliamReqVo request, HttpServletResponse response) throws Exception { List<SysDictData> dataByType = dictDataService.getDictDataByType("status"); Map<String, String> calendarStatus = dataByType.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel)); List<WilliamAllExportVo> list = baseMapper.getWilliamExportData(request); if (CollectionUtils.isNotEmpty(list)) { list.forEach(s -> s.setStatus(calendarStatus.get(s.getStatus()))); } // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 String fileName = URLEncoder.encode("某某表" + DateUtil.format(new Date(), SysConstants.DATE_FORMAT), "UTF-8").replaceAll("\\+", "%20"); response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); ExcelWriterBuilder writerBuilder = EasyExcel.write(response.getOutputStream(), WilliamAllExportVo.class); //合并策略 addMergeStrategy(list, writerBuilder); writerBuilder.sheet("信息表").doWrite(list); } /** * 合并策略 * * @param list 数据集 * @param writerBuilder excel写对象 */ private static void addMergeStrategy(List<WilliamAllExportVo> list, ExcelWriterBuilder writerBuilder) { // 第一级,选定键值进行分层准备 Map<String, List<WilliamAllExportVo>> collect = list.stream().collect(Collectors.groupingBy(s -> s.getProjectSn() + s.getMonth())); Map<String, List<WilliamAllExportVo>> collect2 = list.stream().collect(Collectors.groupingBy(s -> s.getProjectSn() + s.getMonth() + s.getTitle())); //第一层合并单元格处理 for (int i = 1; i < list.size(); ) { WilliamAllExportVo exportVo = list.get(i); //计算集合长度,确定有多少行 int size = collect.get(exportVo.getProjectSn() + exportVo.getMonth()).size(); //按照分层合并范围的属性,设置j的数值 for (int j = 0; j < 10; j++) { OnceAbsoluteMergeStrategy strategy = new OnceAbsoluteMergeStrategy(i, i + size - 1, j, j); writerBuilder.registerWriteHandler(strategy); } i = i + size; } //第二层合并单元格处理, for (int i = 1; i < list.size(); ) { WilliamAllExportVo exportVo = list.get(i); int size = collect2.get(exportVo.getProjectSn() + exportVo.getMonth() + exportVo.getTitle()).size(); for (int j = 10; j < 14; j++) { OnceAbsoluteMergeStrategy strategy = new OnceAbsoluteMergeStrategy(i, i + size - 1, j, j); writerBuilder.registerWriteHandler(strategy); } i = i + size; } }
逻辑分析
1. 数据准备与状态映射
首先,通过dictDataService.getDictDataByType("status")获取字典数据,这通常用于将数据库中的状态码(如数字或简短字符串)转换为更加友好的展示标签。之后,使用Java 8的Stream API将这些数据转换成一个Map,键为状态值,值为状态标签,便于后续替换列表中项目的状态字段。
java
代码解读
复制代码
List<SysDictData> dataByType = dictDataService.getDictDataByType("project_calendar_status"); Map<String, String> calendarStatus = dataByType.stream() .collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
接着,调用baseMapper.getWilliamExportData(request)获取项目日历导出数据列表,然后遍历列表,使用前面构建的状态映射替换项目状态字段的代码值为描述文本。
2. 设置响应头及内容类型
让HTTP响应能够以Excel文件的形式下载。首先,设置了响应的内容类型为Excel的OpenXML格式,然后通过URLEncoder.encode方法对文件名进行编码,以防止中文乱码,并使用特定的Content-Disposition头部来指示浏览器以附件形式下载文件,并给出文件名。
java
代码解读
复制代码
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setCharacterEncoding("utf-8"); String fileName = URLEncoder.encode("某某表" + DateUtil.format(new Date(), SysConstants.DATE_FORMAT), "UTF-8") .replaceAll("\\+", "%20"); response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
3. 使用EasyExcel导出数据
EasyExcel是一个用于简化Excel操作的Java库,它允许开发者以更简洁的方式读写Excel文件。在这里,通过EasyExcel.write(response.getOutputStream(), WilliamAllExportVo.class)初始化一个Excel写入器,然后调用addMergeStrategy方法注册合并单元格的策略,最后在指定的工作表中写入数据。
4. 单元格合并策略
addMergeStrategy方法实现了Excel表格中单元格的合并策略。这里的逻辑是首先按照编号(projectSn)和月份(month)进行第一级分组,然后在同一组内再按照标题(title)进行第二级分组,分别对不同列范围内的连续行进行合并。
对于第一级分组(第1至第9列),合并所有属于同一项目、同一月份的行。 对于第二级分组(第10至第13列),在第一级的基础上,进一步根据标题合并。 使用了OnceAbsoluteMergeStrategy类,该类为EasyExcel提供的单元格合并策略之一,参数分别为起始行号、结束行号、起始列号、结束列号,指定了合并的具体范围。
知识点总结
- 数据映射:利用Map和Stream API进行数据转换,提高代码的可读性和效率。
- HTTP响应处理:设置正确的响应头以实现文件下载,以及解决中文乱码问题。
- EasyExcel库:简化Excel文件的生成和读取过程,提升开发效率。
- 单元格合并:通过自定义策略实现Excel中数据的分组和单元格合并,提升报表的可读性。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)