EasyExcel导出图片并实现动态表头、自动合并单元格、给指定单元格设置值

本文记录了使用EasyExcel导出图片时如何实现动态表头、自动合并单元格以及给指定单元格设置值的过程。通过自定义拦截器(实现CellWriteHandler接口)阻止EasyExcel默认操作,借助Apache POI库实现手动图片插入,同时在不同方法中处理动态表头、阻止图片导出和设置单元格值。
摘要由CSDN通过智能技术生成

概要描述 

  1. 最近工作中涉及到使用Excel导出图片的需求,下面对使用Excel导出图片遇到的一些问题进行记录说明。需求通过 EasyExcel中提供的转换器(Converter)和拦截器(Handler)实现。EasyExcel 官网地址
  2. 实现效果

实现过程

EasyExcel 支持导出 ByteArrayFileStringInputStreamURL 五种类型的图片。项目中图片字段使用的是InputStream,由前端传入图片,因此本文将介绍导出  InputStream 类型图片的实现过程。

实现过程主要关键步骤:

  1. 自定义拦截器(实现 CellWriteHandler 接口):阻止 EasyExcel 默认的图片导出操作,使用 Apache POI 库向 Excel 表格中手动写入图片。
  2. 在自定义拦截器中重写beforeCellCreate方法实现动态表头赋值。
  3. 在自定义拦截器中重写afterCellDataConverted方法解决EasyExcel 中阻止默认的图片导出操作。
  4. 在自定义拦截器中重写afterCellDispose方法写入图片,并在指定的单元格设置值。

   

  •  引入依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.4</version>
</dependency>
  • 定义前端传入实体类 

@Data
public class ProjectGanttExportReqVO implements Serializable {
    @Schema(description = "文件附件", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotNull(message = "文件附件不能为空")
    @JSONField(serialize = false)
    private MultipartFile file;

    @Schema(description = "项目信息Id", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotNull(message = "项目信息Id不能为空")
    private Long projectId;

    @Schema(description = "图片的高度", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotNull(message = "图片高度不能为空")
    private Integer height;

    @Schema(description = "图片宽度", requiredMode = Schema.RequiredMode.REQUIRED)
    @NotNull(message = "图片宽度不能为空")
    private Integer width;
}
  • 定义导出的实体类

@Data
public class ProjectGanttExportVO implements Serializable {
    @ExcelProperty(value = {"${projectName}"})
    @ColumnWidth(15)
    private InputStream fileInputStream;

    @ExcelIgnore
    private String projectName; // 动态表头-项目名称

    @ExcelIgnore
    private Integer height;  // 图片的高度

    @ExcelIgnore
    private Integer width;  // 图片的宽度

    @ExcelIgnore
    private String lineConstructionScaleHead = "线路建设规模:"; //线路建设规模

    @ExcelIgnore
    private String lineConstructionScale; // 线路建设规模内容描述

    @ExcelIgnore
    private String substationConstructionScaleHead = "变电建设规模:"; // 变电建设规模

    @ExcelIgnore
    private String substationConstructionScale; //变电建设规模内容描述

    @ExcelIgnore
    private String designDeptNameHead = "设计单位:"; // 设计单位表头

    @ExcelIgnore
    private String designDeptName; // 设计单位名称

    @ExcelIgnore
    private String eiaDeptNameHead = "环评编制单位:"; //环评编制单位表头

    @ExcelIgnore
    private String eiaDeptName; // 环评编制单位

    @ExcelIgnore
    private String waterConservationDeptNameHead = "水保编制单位:"; //水保编制单位表头

    @ExcelIgnore
    private String waterConservationDeptName; //水保编制单位

    @ExcelIgnore
    private String approvalDeptNameHead = "核准编制单位:"; // 核准编制单位表头

    @ExcelIgnore
    private String approvalDeptName; // 核准编制单位

    @ExcelIgnore
    private String linKanDeptNameHead = "林勘编制单位:"; // 林勘编制单位表头

    @ExcelIgnore
    private String linKanDeptName; // 林勘编制单位

    @ExcelIgnore
    private String orePressingDeptNameHead = "压矿编制单位:"; // 压矿编制单位表头

    @ExcelIgnore
    private String orePressingDeptName; // 压矿编制单位

    @ExcelIgnore
    private String landDeptNameHead = "土地编制单位:"; // 土地编制单位表头

    @ExcelIgnore
    private String landDeptName; // 土地编制单位

    @ExcelIgnore
    private String roadDeptNameHead = "施工单位:"; // 施工单位表头

    @ExcelIgnore
    private String roadDeptName; // 施工单位

    @ExcelIgnore
    private String supervisorDeptNameHead = "监理单位:"; // 监理单位表头

    @ExcelIgnore
    private String supervisorDeptName; // 监理单位


}
  • 定义单元格合并属性实体类

/**
 * 单元格合并
Java中使用easyexcel库可以通过注册写入处理器(WriteHandler)来实现对Excel文件写入过程的自定义操作。WriteHandler是一个接口,用于在写入Excel文件的各个阶段插入自定义逻辑。 当你想要在写入Excel时给每个单元格设置不同的背景色,你可以通过实现WriteHandler接口中的方法来自定义背景色的设置逻辑。下面是一个简化的例子,展示如何通过注册一个自定义的WriteHandler拦截器来实现这个功能: ```java import com.alibaba.excel.write.handler.AbstractRowWriteHandler; import com.alibaba.excel.write.handler.context.RowWriteHandlerContext; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteTableHolder; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.usermodel.XSSFClientAnchor; import org.apache.poi.xssf.usermodel.XSSFSimpleShape; import org.apache.poi.xssf.usermodel.XSSFColor; import org.apache.poi.ss.usermodel.Workbook; public class BackgroundColorWriteHandler extends AbstractRowWriteHandler { // 假设这是一个根据某些条件来决定单元格背景色的策略 private WriteHandlerStrategy strategy; public BackgroundColorWriteHandler(WriteHandlerStrategy strategy) { this.strategy = strategy; } @Override public void afterRowDispose(RowWriteHandlerContext context) { // 获取当前行号 int rowIndex = context.getRowIndex(); // 获取工作表 WriteSheetHolder writeSheetHolder = context.getWriteSheetHolder(); Sheet sheet = writeSheetHolder.getSheet(); // 获取当前工作簿 Workbook workbook = sheet.getWorkbook(); // 获取绘图对象 Drawing<?> drawing = sheet.createDrawingPatriarch(); // 根据行号进行循环,为每个单元格设置背景色 for (int i = 0; i < context.getWriteCellHolder().getColumns(); i++) { // 获取单元格 Cell cell = context.getWriteCellHolder().getCell(); // 根据策略设置单元格背景色 XSSFColor color = strategy决定了背景色(cell, rowIndex, i); if (color != null) { // 创建单元格锚点 ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, context.getWriteCellHolder().getColumnIndex() + i, rowIndex, context.getWriteCellHolder().getColumnIndex() + i, rowIndex); // 创建形状对象 XSSFSimpleShape shape = ((XSSFDrawing) drawing).createSimpleShape((XSSFClientAnchor) anchor); shape.setFillColor(color); } } } // 这里是策略接口的定义,实际中需要根据具体逻辑来实现它 public interface WriteHandlerStrategy { XSSFColor决定了背景色(Cell cell, int rowIndex, int columnIndex); } } ``` 在上面的代码中,`BackgroundColorWriteHandler`类继承自`AbstractRowWriteHandler`,并重写了`afterRowDispose`方法,该方法会在每一行写入之后调用。在`afterRowDispose`方法中,我们根据行索引和列索引循环设置每个单元格的背景色。`WriteHandlerStrategy`是一个策略接口,你需要根据实际需求实现该策略来决定每个单元格的背景色。 要在easyexcel的写操作中使用这个拦截器,你可以这样做: ```java EasyExcel.write(fileName, YourDataClass.class) .registerWriteHandler(new BackgroundColorWriteHandler(new WriteHandlerStrategy() { // 实现具体策略逻辑 @Override public XSSFColor 决定了背景色(Cell cell, int rowIndex, int columnIndex) { // 根据你的逻辑返回不同的XSSFColor对象或者null(不设置背景色) } })) .sheet("模板") .doWrite(dataList); ``` 在这个例子中,`YourDataClass`是你的数据模型类,`fileName`是文件的存储路径,`dataList`是要写入的数据集合。通过这种方式,你就可以在easyexcel写入Excel的过程中给每个单元格设置不同的背景色了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值