当前位置: 首页 > article >正文

【EasyExcel】导出excel并支持自定义设置数据行背景颜色等

需求背景:

        根据查询条件将列表数据导出,并筛选出满足某个条件的数据,将满足条件的数据的背景颜色设置成黄色。
        (本文例子如:name出现的次数大于等于2,将相关数据背景颜色都设置为黄色)

一、技术选型:

        1、easyExcel的自定义写策略处理:CellWriteHandler

        2、poi自带的写数据行处理:Workbook

思考选定:

        由于目前系统中多处使用的是file插件导出类,是由统一形成的,直接改动,对其它项目引入,从而导出的性能产生一定的影响,所以选择自定义策略实现,故选1。

二、方案设计:(基于实现 CellWriteHandler 接口)

        1、在 beforeCellCreate 方法中统计出 每个数据行的 name 出现的次数,在 afterCellDispose 方法中处理满足设置背景颜色数据的背景颜色。

        2、直接传入数据行的索引,在 afterCellDispose 方法中处理满足设置背景颜色数据的背景颜色。

note:原本考虑的是选择1,但是在实现的时候,统计name出现次数一直会出现问题,在easeExcel的源码中:beforeCellCreate 操作数据出现问题,待处理。(码友们可自行尝试!!!)故暂选择 方案2 实现当前需求。

三、代码实现:

pom.xml:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version>
</dependency>

API:

 @ApiOperation(value = "评论审核导出")
 @GetMapping(value = "/export")
 public void exportExcel(HttpServletResponse response, TestParam param) throws BaseException {
        service.export(response, param);
 }
实现层:
public class TestExcelService {

    private static final String FILE_NAME = "测试文件名字";
    private static final String SHEET_NAME = "测试";

    private final IEasyExcelService easyExcelService;
    public SeedDemandExcelService(IEasyExcelService easyExcelService) {
        this.easyExcelService = easyExcelService;
    }

    public void export(HttpServletResponse response, TestParam param) throws BaseException{
        // 根据查询参数获取查询到的数据(根据自己的查询方法在这里将数据查询出来)
        List<TestExcelData> exportData = this.getExportData(param);
        // Obtain data rows that require background color settings
        // 获取需要设置背景颜色的数据行索引
        List<Integer> index = getIndexList(exportData);
        // export
        try {
            easyExcelService.exportExcelWithBackGround(exportData, response, DemoExcelData.class, FILE_NAME, SHEET_NAME, index);
        } catch (Exception e) {
            throw new Exception(CodeEnum.FAILED, "导出异常,请联系开发人员!异常信息是:" + e.getMessage());
        }
    }
}
工具类:IEasyExcelService
public interface IEasyExcelService {
    /**
     * 导出excel方法
     * @param exportData 需要导出的数据
     * @param response response
     * @param tClass 导出excel的字段实体类
     * @param fileName 文件名字
     * @param sheetName sheet名字
     */
    <T> void exportExcel(List<T> exportData, HttpServletResponse response, Class<T> tClass, String fileName, String sheetName);
    /**
     * 导出excel方法(支持设置背景颜色)
     * @param exportData 需要导出的数据
     * @param response response
     * @param tClass 导出excel的字段实体类
     * @param fileName 文件名字
     * @param sheetName sheet名字
     * @param backGroundIndex 需要设置背景的数据行
     * @param <T> t
     * @throws Exception Exception
     */
    <T> void exportExcelWithBackGround(List<T> exportData, HttpServletResponse response, Class<T> tClass , String fileName, String sheetName, List<Integer> backGroundIndex) throws Exception;
}
工具类:EasyExcelServiceImpl
@Service
@Slf4j
public class EasyExcelServiceImpl implements IEasyExcelService {

    @Override
    public <T> void exportExcel(List<T> exportData, HttpServletResponse response, Class<T> tClass, String fileName, String sheetName){
        try{
            // 使用swagger 会导致各种问题,直接用浏览器或者用postman
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // fileName encoder
            String fileNameEncoder = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileNameEncoder + ".xlsx");
            // write to excel
            EasyExcelFactory.write(response.getOutputStream(), tClass)
                    .autoCloseStream(Boolean.FALSE)
                    .sheet(sheetName)
                    .doWrite(exportData);
        }catch (Exception e){
            log.error("EasyExcelServiceImpl->exportExcel error, message is :{}", e.getMessage());
        }
    }

    @Override
    public <T> void exportExcelWithBackGround(List<T> exportData, HttpServletResponse response, Class<T> tClass,
                                              String fileName, String sheetName, List<Integer> backGroundIndex) throws Exception {
        // 使用swagger 会导致各种问题,直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // fileName encoder
        String fileNameEncoder = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileNameEncoder + ".xlsx");
        // 自定义策略
        Set<Integer> yellowRowsSet = new HashSet<>(backGroundIndex);
        SeedDemandCellWriteHandler seedDemandCellWriteHandler = new SeedDemandCellWriteHandler(yellowRowsSet);
        // write to excel
        EasyExcelFactory.write(response.getOutputStream(), tClass)
                // 自定义背景颜色策略
                .registerWriteHandler(seedDemandCellWriteHandler)
                .inMemory(Boolean.TRUE)
                .autoCloseStream(Boolean.FALSE)
                .sheet(sheetName)
                .doWrite(exportData);
    }

}
(其中registerWriteHandler支持扩展多个,可以通过HorizontalCellStyleStrategy策略设置全局的配置,如背景颜色、字体、合并单元格等)

自定义Handle:(自定义设置数据行背景颜色)

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.BooleanUtils;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import java.util.Set;

/**
 * @author c
 */
public class CustomCellWriteHandler implements CellWriteHandler {

    /**
     * 标黄行宽集合
     */
    private final Set<Integer> yellowRowIndex;

    public CustomCellWriteHandler(Set<Integer> yellowRowIndex) {
        this.yellowRowIndex = yellowRowIndex;
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
        // 源码context中row待优化:支持入参 获取需要字段的出现次数 从而设置背景颜色
        // to do:(row.getCell(columnIndex)失效)
    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        // empty
    }

    @Override
    public void afterCellDispose(CellWriteHandlerContext context) {
        if (BooleanUtils.isNotTrue(context.getHead())) {
            // 获取当前行的行号
            Integer currentRowIndex = context.getRowIndex();
            // 判断当前行是否在yellowRowIndex's中
            if (yellowRowIndex.contains(currentRowIndex)) {
                // 设置背景颜色,也可以设置字体等其它元素
                WriteCellData<?> cellData = context.getFirstCellData();
                WriteCellStyle writeCellStyle = cellData.getOrCreateStyle();
                writeCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
                writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
            }
        }
    }

}
DemoExcelData:(导出字段实体类)
@Data
@EqualsAndHashCode
public class DemoExcelData{

    @ExcelProperty(value = "TaskID", index = 0)
    private String name;
    @ExcelProperty(value = "taskName", index = 1)
    private String sex;
    @ExcelProperty(value = "taskName", index = 2)
    private String age;
}

End:

        👍如果对你有帮助,给博主一个免费的点赞以示鼓励
欢迎各位🔎点赞👍评论收藏⭐️


http://www.kler.cn/a/152534.html

相关文章:

  • 【ASP.NET CORE】EntityFrameworkCore 数据迁移
  • 键盘打字盲打练习系列之刻意练习——1
  • ssm+java车辆售后维护系统 springboot汽车保养养护管理系统+jsp
  • 不会代码(零基础)学语音开发(学习工具)
  • 物联网实训室虚拟仿真软件建设方案
  • 代码随想录刷题题Day2
  • 【PUSDN】WebStorm中报错Switch language version to React JSX
  • 可验证随机函数(VRF)
  • 百度推送收录工具-免费的各大搜索引擎推送工具
  • 如何在服务器上运行python文件
  • 二叉树题目:祖父结点值为偶数的结点和
  • Android设置文字颜色渐变
  • 单片机学习12——电容
  • 视频后期效果制作工具Mocha Pro 2022 Plugins mac中文版软件介绍
  • vscode项目推送到git
  • CCF CSP认证 历年题目自练Day50
  • 无限移动的风景 css3 动画 鼠标移入暂停
  • 希尔伯特变换-matlab仿真
  • 虚假IP地址攻击的溯源方法
  • Java实现集合和Excel文件相互转换