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();  // 必须显式关闭
    }
}
相关推荐
斑马1394 分钟前
Linux软件编程学习笔记(五)——线程
开发语言·php
2601_961901705 分钟前
SpringCloud2023集成Nacos2.4.3
java
玄昌盛不会编程6 分钟前
LeetCode——2091. 从数组中移除最大值和最小值
java·算法·leetcode
Rain的Java大神之路9 分钟前
如何保证接口幂等
java·经验分享·后端·面试·架构
吴声子夜歌10 分钟前
Java——数组和集合(一)
java·开发语言
Jesse_EC12 分钟前
一个看不见的字符——CRLF 如何让我的 Docker 初始化脚本"静默失踪"
java·后端
深念Y12 分钟前
Nuxt 项目 Docker 构建:从 pnpm+node 迁移到全 bun
java·前端·docker
学长毕业设计16 分钟前
基于SpringBoot的社区鲜奶订购系统的设计与实现(源码+文档+讲解视频)
java·spring boot·后端
呆呆敲代码的小Y17 分钟前
Lua 上值(UpValue)
开发语言·junit·lua·lua上值·upvalue
呆呆敲代码的小Y21 分钟前
【游戏开发】C# 中的迭代器
java·开发语言·c#·迭代器