Java + easyexcel 新旧数据对比,单元格值标红

说明:Java + easyexcel 复制excel模版样式及表头,写入新数据,并对比旧数据,数据不一致标红

pom

复制代码
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>easyexcel</artifactId>
			<version>4.0.3</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>5.2.5</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>5.2.5</version>
		</dependency>

数据对比处理器

复制代码
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 com.example.entity.Equipment;
import org.apache.poi.ss.usermodel.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class CustomValueHandler implements CellWriteHandler {

    private final Map<Integer, Map<Integer, String>> originalValues;

    public CustomValueHandler(List<Equipment> originalList) {
        this.originalValues = new HashMap<>();
        for (int i = 0; i < originalList.size(); i++){
            Map<Integer, String> rowMap = new HashMap<>();
            Equipment item = originalList.get(i);
            rowMap.put(0, item.getEquipCode());
            rowMap.put(1, item.getEquipName());
            rowMap.put(2, item.getEquipRule());
            rowMap.put(3, item.getEquipState());
            rowMap.put(4, item.getEquipNum());
			//我这里的表头是4行,所以序号要加4
            this.originalValues.put(i + 4, rowMap);

        }
    }
    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder,
                                 WriteTableHolder writeTableHolder,
                                 List<WriteCellData<?>> cellDataList,
                                 Cell cell, Head head,
                                 Integer relativeRowIndex,
                                 Boolean isHead) {

        String stringCellValue = cell.getStringCellValue();
        int rowIndex = cell.getRowIndex();
        int columnIndex = cell.getColumnIndex();

        if(originalValues.containsKey(rowIndex)) {

            String original = originalValues.get(rowIndex).get(columnIndex);

            if(original != null && !original.trim().equals(stringCellValue.trim())) {
                Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
                CellStyle originalStyle = cell.getCellStyle();
                CellStyle style = workbook.createCellStyle();
                //复制原有样式属性
                style.cloneStyleFrom(originalStyle);
                Font font = workbook.createFont();
                font.setColor(IndexedColors.RED.getIndex());
                style.setFont(font);
                // 保留原有背景色(不设置背景色)
                cell.setCellStyle(style);
            }
        }
    }
}

excel处理器

复制代码
public class EasyExcelDynamicFilter implements SheetWriteHandler {
    private final int rowIndex;

    public EasyExcelDynamicFilter(int rowIndex) {
        this.rowIndex = rowIndex;
    }

    @Override
    public void afterSheetCreate(SheetWriteHandlerContext context) {
        Sheet sheet = context.getWriteSheetHolder().getSheet();
        // 保留前4行(索引0-3),删除其余行
        for (int i = rowIndex; i <= sheet.getLastRowNum(); i++) {
            if (sheet.getRow(i) != null) {
                sheet.removeRow(sheet.getRow(i));
            }
        }
    }
}

业务处理

复制代码
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
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.example.handler.DynamicFilter;

import java.io.IOException;
import java.util.List;

public class ExcelHeaderUtil {
    /**
     * 复制模板前4行并清除后续内容
     *
     * @param templatePath 模板路径
     * @param outputPath 输出路径
     * @param originalList 初始数据
     * @param data 新数据
     */
    public static void copyRows(String templatePath,
                                String outputPath,
                                List<Equipment> data, List<Equipment> originalList) throws IOException {

        // 创建样式拦截器
        CellWriteHandler styleHandler = new CellWriteHandler() {
            @Override
            public void afterCellCreate(WriteSheetHolder sheetHolder,
                                        WriteTableHolder tableHolder,
                                        Cell cell, Head head,
                                        Integer relativeRowIndex,
                                        Boolean isHead) {
            }
        };

        // 构建写入器
        ExcelWriter writer = EasyExcel.write(outputPath)
                .withTemplate(templatePath)
                .registerWriteHandler(new EasyExcelDynamicFilter(4))
                .registerWriteHandler(new CustomValueHandler(originalList))
                .registerWriteHandler(styleHandler)
                .build();

        // 触发模板处理
        writer.write(data, EasyExcel.writerSheet().build());
        writer.finish();  // 必须显式关闭
    }
}
相关推荐
xwz小王子3 分钟前
智元发布 GO-2:动作空间推理 + 全生命周期闭环,让机器人稳定可靠落地
开发语言·golang·机器人
charlie1145141913 分钟前
通用GUI编程技术——图形渲染实战(二十八)——图像格式与编解码:PNG/JPEG全掌握
开发语言·c++·windows·学习·图形渲染·win32
ZC跨境爬虫6 分钟前
海南大学交友平台登录页开发实战day4(解决python传输并读取登录信息的问题)
开发语言·前端·python·flask·html
wjs20249 分钟前
SQL LEN() 函数详解
开发语言
姓刘的哦14 分钟前
Qt自定义控件
开发语言·qt
Ricky_Theseus14 分钟前
C++静态库
开发语言·c++
SuperEugene15 分钟前
Python 异步 async/await:为什么 AI 框架大量使用?| 基础篇
开发语言·人工智能·python
云烟成雨TD20 分钟前
Spring AI 1.x 系列【28】基于内存和 MySQL 的多轮对话实现案例
java·人工智能·spring
SMF191921 分钟前
【uv】Python包管理器uv安装和应用
开发语言·python·uv
Lyyaoo.22 分钟前
【JAVA基础面经】String、StringBuffer、StringBuilder
java·开发语言