重庆铜梁网站建设,松江做移动网站,爱站网影院,外贸网站 有哪些谈到新技术#xff0c;每个人都会有点恐惧#xff0c;怕处理不好。确实#xff0c;第一次使用新技术会遇到很多坑#xff0c;这次使用 EasyExcel 这个新技术去做 excel 导出#xff0c;还要给表格加样式#xff0c;遇到不同的版本问题#xff0c;遇到颜色加错了地方每个人都会有点恐惧怕处理不好。确实第一次使用新技术会遇到很多坑这次使用 EasyExcel 这个新技术去做 excel 导出还要给表格加样式遇到不同的版本问题遇到颜色加错了地方反正各种效果都打不到自己想要的那种幸好最终看文档解决了特此写下这篇博客。 EasyExcel导出自定义表格 一、导入依赖二、原理分析三、上代码 一、导入依赖
dependencygroupIdcom.alibaba/groupIdartifactIdeasyexcel/artifactIdversion3.3.2/version
/dependency二、原理分析 对于 read 函数主要通过流操作获取 对于 EasyExcel.read 方法中常用的一个 read 函数 javaEasyExcel.read(fileName, head, readListener).sheet().doRead();三个参数如下 fileNameExcel 文件的路径或输入流。headExcel 表头对应的实体类定义了 Excel 表的结构。readListener数据读取的监听器定义了读取数据的逻辑。 Excel 表头的实体类 在读取 Excel 文件时需要定义一个实体类来映射 Excel 表头每个字段对应一个表头列。这个实体类用于指定数据在 Java 对象中的存储结构。 javapublic class ExcelData {private String name;private Integer age;// 其他字段...// 省略 getter 和 setter 方法
}数据读取监听器 EasyExcel 提供了 AnalysisEventListener 类来处理 Excel 数据的读取。 需要集成该类并实现 invoke 方法来处理每一行数据的读取逻辑以及 doAfterAllAnalysed 方法来处理所有数据解析完成后的逻辑。 public class ExcelDataListener extends AnalysisEventListenerExcelData {Overridepublic void invoke(ExcelData data, AnalysisContext context) {// 处理每一行数据的逻辑System.out.println(Read data: data);}Overridepublic void doAfterAllAnalysed(AnalysisContext context) {// 所有数据解析完成后的逻辑}
}Excel 写入 EasyExcel 也提供了写入 Excel 文件的功能。可以使用 EasyExcel.write 方法来配置写入参数然后调用 sheet 方法指定写入的 sheet最后调用 doWrite 方法执行写入操作。 EasyExcel.write(fileName, head).sheet(Sheet1).doWrite(dataList);三个参数如下 fileName写入的 Excel 文件路径。headExcel 表头对应的实体类。dataList要写入的数据列表。dataList 是一个 List 集合其中的元素是实体类的对象。 Excel 写入监听器 写入 Excel 文件时进行一些额外的处理可以使用写入的监听器 WritHandler。 public class ExcelWriteHandler implements WriteHandler {Overridepublic void sheet(int sheetNo, Sheet sheet) {// 对每个 sheet 进行处理的逻辑}Overridepublic void row(int rowNum, Row row) {// 对每一行进行处理的逻辑}Overridepublic void cell(int cellNum, Cell cell) {// 对每个单元格进行处理的逻辑}
}在写入 Excel 文件时通过 excelWriter.registerWriterHandler( new ExcelWriterHandler() ) 注册写入监听器即可。
三、上代码
先看要求 其实这里的大部分样式都可以参考 EasyExcel API 文档
导出
Overridepublic void importUserSign(ImportUserSignReq req, HttpServletResponse response) {String projectName req.getProjectName();String time req.getTime();// 查询第一页数据ListSignTemplate1 data1 new ArrayList();data1.add(new SignTemplate1().setE1(序号).setE2(成员姓名).setE3(签到次数).setE4(补签次数).setE5(签到总工时).setE6(最后签到时间));data1.addAll(getData1(req));// 查询第二页数据ListSignTemplate2 data2 getData2(req, getData1(req));Integer maxRow data2.stream().map(SignTemplate2::getE2).max(Integer::compare).orElse(0); //获取最大行try {// 指定文件名
// response.setContentType(application/vnd.openxmlformats-officedocument.spreadsheetml.sheet);
// response.setCharacterEncoding(utf-8);
// String fileName URLEncoder.encode(签到模板导出.xlsx, UTF-8);
// response.setHeader(Content-disposition, attachment;filename* fileName);String fileName E:\\excel\\ 签到模板导出 System.currentTimeMillis() .xlsx;ExcelWriter excelWriter EasyExcel.write(response.getOutputStream()).build();// 第一页// 自定义头部样式WriteCellStyle headWriteCellStyle1 new WriteCellStyle();headWriteCellStyle1.setFillForegroundColor(IndexedColors.GOLD.getIndex()); //背景颜色-黄色headWriteCellStyle1.setHorizontalAlignment(HorizontalAlignment.LEFT); //左对齐// 自定义内容样式WriteCellStyle contentWriteCellStyle1 new WriteCellStyle();// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现HorizontalCellStyleStrategy style1 new HorizontalCellStyleStrategy(headWriteCellStyle1, contentWriteCellStyle1);// sheet命名WriteSheet writeSheet1 EasyExcel.writerSheet(1, 项目名称).registerWriteHandler(style1) //自定义策略.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) //自动列宽.head(getHead(【projectName】, time, 6)) //动态表头.head(SignTemplate1.class).build();// 写入第一页excelWriter.write(data1, writeSheet1);// 第二页// 自定义头部样式WriteCellStyle headWriteCellStyle2 new WriteCellStyle();headWriteCellStyle2.setFillForegroundColor(IndexedColors.GOLD.getIndex()); //背景颜色-黄色headWriteCellStyle2.setHorizontalAlignment(HorizontalAlignment.LEFT); //左对齐// 自定义内容样式WriteCellStyle contentWriteCellStyle2 new WriteCellStyle();contentWriteCellStyle2.setHorizontalAlignment(HorizontalAlignment.RIGHT); //右对齐// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现HorizontalCellStyleStrategy style2 new HorizontalCellStyleStrategy(headWriteCellStyle2, contentWriteCellStyle2);// sheet命名WriteSheet writeSheet2 EasyExcel.writerSheet(2, 签到明细).registerWriteHandler(style2) //自定义策略.registerWriteHandler(new CustomCellWriteHandler(maxRow, (data2.size()1))) //自定义动态行/列背景颜色.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) //自动列宽.head(getHead(【projectName】, time, (data2.size()1))) //动态表头.build();// 写入第二页excelWriter.write(dataList(data2, maxRow), writeSheet2).close();}catch (Exception e){e.printStackTrace();throw new CustomException(导出失败);}}动态标题头
private ListListString getHead(String projectName, String time, Integer num) {ListListString list new ArrayListListString();for (int i 0; i num; i) {list.add(Arrays.asList(projectName, time));}return list;
}动态填充数据
private ListListObject dataList(ListSignTemplate2 data2, Integer maxRow) {ListListObject list new ArrayList();ListObject row1 ListUtils.newArrayList(); //第一行ListObject row2 ListUtils.newArrayList(); //第二行row1.add(成员名称);row2.add(签到次数);for (int i 0; i data2.size(); i) { //行内每一列数据row1.add(data2.get(i).getE1());row2.add(data2.get(i).getE2());}list.add(row1);list.add(row2);for (int i 0; i maxRow; i) {ListObject row3 ListUtils.newArrayList(); //第三行-多条ListObject row4 ListUtils.newArrayList(); //第四行-多条row3.add(null);row4.add(null);for (int j 0; j data2.size(); j) { //行内每一列数据ListSignTemplate3 eList data2.get(j).getEList();//当前列的签到集合if (i eList.size()) {row3.add(eList.get(i).getE2() eList.get(i).getE1());row4.add(ObjectUtil.isNotNull(eList.get(i).getE3())?eList.get(i).getE3():暂无);}else {row3.add(null);row4.add(null);}}list.add(row3);list.add(row4);}return list;
}自定义动态行/列背景颜色
package com.glbTech.business.dto.req.stat;import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.AbstractCellWriteHandler;
import com.alibaba.excel.write.handler.SheetWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import lombok.Data;
import org.apache.commons.lang.BooleanUtils;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddressList;import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;Data
public class CustomCellWriteHandler extends AbstractCellWriteHandler {private Integer maxRow;private Integer maxCol;private final short colorL IndexedColors.LIME.getIndex(); //绿色private final short colorH IndexedColors.GREY_25_PERCENT.getIndex(); //灰色public CustomCellWriteHandler(Integer maxRow, Integer maxCol) {this.maxRow maxRow;this.maxCol maxCol;}Overridepublic void afterCellDispose(CellWriteHandlerContext context) {// 自定义样式处理// 当前事件会在 数据设置到poi的cell里面才会回调int x 1;for (int i 4; i (maxRow2)*2; i(x*2)) {Cell cell context.getCell();int rowIndex cell.getRowIndex(); //行int cellIndex cell.getColumnIndex(); //行的列// 判断不是头的情况 如果是fill 的情况 这里会null 所以用not trueif (BooleanUtils.isNotTrue(context.getHead())) {if (cellIndex 0 (rowIndexi || rowIndexi1)) {// 拿到poi的workbookWorkbook workbook context.getWriteWorkbookHolder().getWorkbook();// 这里千万记住 想办法能复用的地方把他缓存起来 一个表格最多创建6W个样式// 不同单元格尽量传同一个 cellStyleCellStyle cellStyle workbook.createCellStyle();//设置颜色if (x%20) {cellStyle.setFillForegroundColor(colorL); //绿色}else {cellStyle.setFillForegroundColor(colorH); //灰色}cellStyle.setAlignment(HorizontalAlignment.RIGHT); //右对齐// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUNDcellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);cell.setCellStyle(cellStyle);// 由于这里没有指定dataformat 最后展示的数据 格式可能会不太正确// 这里要把 WriteCellData的样式清空 不然后面还有一个拦截器 FillStyleCellWriteHandler 默认会将 WriteCellStyle 设置到// cell里面去 会导致自己设置的不一样很关键context.getFirstCellData().setWriteCellStyle(null);}}x;}}
}好事定律每件事最后都会是好事如果不是好事说明还没到最后。