一对多 EasyExcel复杂表头导出升级版

一、前言
在之前写的复杂表头导出(一对多)的博客的结尾,受限于当时的能力和精力,留下一些问题及展望 。现在写下此博客,目的就是解决之前遗留的问题 。
背景介绍,见上述链接指向的博客,这里主要通过自定义拦截器的形式来完美解决 。
二、导出功能的实现 2. 对象
import com.alibaba.excel.annotation.ExcelProperty;import com.alibaba.excel.annotation.write.style.ColumnWidth;import com.alibaba.excel.annotation.write.style.ContentRowHeight;import com.alibaba.excel.annotation.write.style.HeadRowHeight;import com.alibaba.excel.annotation.write.style.HeadStyle;import com.alibaba.excel.converters.string.StringImageConverter;import lombok.AllArgsConstructor;import lombok.Data;import lombok.EqualsAndHashCode;import lombok.NoArgsConstructor;import java.net.URL;@Data@EqualsAndHashCode@HeadRowHeight(30)@ContentRowHeight(80)@ColumnWidth(15)@HeadStyle(fillForegroundColor = 44)@NoArgsConstructor@AllArgsConstructorclass Customer {@ExcelProperty({"客户编号"})private String userCode;@ExcelProperty({"客户名称"})private String userName;@ColumnWidth(25)@ExcelProperty({"客户所在地址"})private String address;@ExcelProperty({"联系人信息", "联系人姓名"})private String personName;@ExcelProperty({"联系人信息", "联系电话"})private String telephone;@ExcelProperty({"图片"})private URL picture;/*** 你也可以通过字符串的形式来保存图片,具体说明见注意事项3.1*///@ExcelProperty(converter = StringImageConverter.class, value = http://www.kingceram.com/post/{"本地图片"})//private String localPic;}
2.2层
@PostMapping("/exportExcel")@ApiOperation("导出Excel")public void exportExcel(HttpServletResponse response) throws Exception {// 查询需要导出的数据List result = getData();// 1设置表头样式WriteCellStyle headStyle = new WriteCellStyle();// 1.1设置表头数据居中headStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 2设置表格内容样式WriteCellStyle bodyStyle = new WriteCellStyle();// 2.1设置表格内容水平居中bodyStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 2.2设置表格内容垂直居中bodyStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 3设置表格sheet样式WriteSheet sheet = EasyExcel.writerSheet("客户信息").head(Customer.class).sheetNo(1).build();// 4拿到表格处理对象ExcelWriter writer = EasyExcel.write(response.getOutputStream()).needHead(true).excelType(ExcelTypeEnum.XLSX)// 设置需要待合并的行和列 。参数1:数值数组,指定需要合并的列;参数2:数值,指定从第几行开始合并.registerWriteHandler(new ExcelMergeCellHandler(new int[]{0, 1, 2, 5}, 0))// 设置单元格的风格样式.registerWriteHandler(new HorizontalCellStyleStrategy(headStyle, bodyStyle)).build();// 5写入excel数据writer.write(result, sheet);// 6通知浏览器以附件的形式下载处理,设置返回头要注意文件名有中文response.setHeader("Content-disposition", "attachment;filename=" + new String("客户信息表".getBytes("gb2312"), "ISO8859-1") + ".xlsx");response.setContentType("multipart/form-data");response.setCharacterEncoding("utf-8");writer.finish();}
2.3 自定义拦截器(r)
import com.alibaba.excel.metadata.Head;import com.alibaba.excel.metadata.data.WriteCellData;import com.alibaba.excel.write.handler.CellWriteHandler;import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;import com.alibaba.excel.write.metadata.holder.WriteTableHolder;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.CellType;import org.apache.poi.ss.usermodel.Sheet;import org.apache.poi.ss.util.CellRangeAddress;import java.util.List;/*** @author DaHuaJia* @Description 自定义单元格合并处理Handler类* @Date 2022-08-18 19:25:58*/@Data@NoArgsConstructor@AllArgsConstructorpublic class ExcelMergeCellHandler implements CellWriteHandler {// 需要合并的列,从0开始算private int[] mergeColIndex;// 从指定的行开始合并,从0开始算private int mergeRowIndex;/*** 在单元格上的所有操作完成后调用,遍历每一个单元格,判断是否需要向上合并*/@Overridepublic void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List