您的位置:

EasyExcel 动态合并单元格详解

Excel 是一种非常常见的文件格式,在工作中也是经常遇到。而 EasyExcel 是一个非常好用的 Java 操作 Excel 的工具,我们可以用它来快速完成对 Excel 的读写操作,同时也支持动态合并单元格功能,本文将详细阐述 EasyExcel 动态合并单元格的使用方法。

一、准备工作

首先,我们需要在项目的 pom.xml 文件中引入 easyexcel 的依赖:

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

然后,我们需要创建一个 Excel 的实体类,这个实体类对应着 Excel 文件中的每一行数据。例如,我们要操作以下这个 Excel 文件:

姓名   学科   成绩
小明   语文   90
小明   数学   95
小明   英语   88
小红   语文   85
小红   数学   92
小红   英语   90

我们可以定义一个 ExcelEntity 类:

public class ExcelEntity {
    private String name;
    private String subject;
    private Integer score;
    
    //getters and setters
}

二、基础操作

读取 Excel 文件

使用 EasyExcel 读取 Excel 文件非常简单,只需要定义一个 AnalysisEventListener 类,并重写其中的 invoke() 方法即可:

public class ExcelListener extends AnalysisEventListener<ExcelEntity> {
    @Override
    public void invoke(ExcelEntity data, AnalysisContext context) {
        //TODO 对读取到的数据进行处理
    }
    
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        //TODO 所有数据解析完成后的操作
    }
}

public class ExcelUtil {
    public static void readExcel(String fileName) {
        try (InputStream inputStream = new FileInputStream(fileName)) {
            EasyExcel.read(inputStream, ExcelEntity.class, new ExcelListener()).sheet().doRead();
        } catch (Exception e) {
            //TODO 异常处理
        }
    }
}

其中,fileName 代表 Excel 文件的路径。

写入 Excel 文件

使用 EasyExcel 写入 Excel 文件同样也非常简单,只需要定义一个 WriteHandler 类,并重写其中的 invoke() 方法即可:

public class ExcelHandler implements WriteHandler {
    @Override
    public void sheet(int sheetNo, Sheet sheet) {
        //TODO 对当前 sheet 进行操作
    }

    @Override
    public void row(int rowNum, Row row) {
        //TODO 对当前 row 进行操作
    }

    @Override
    public void cell(int cellNum, Cell cell) {
        //TODO 对当前 cell 进行操作
    }
    
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        //TODO 所有数据解析完成后的操作
    }
}

public class ExcelUtil {
    public static void writeExcel(String fileName, List<ExcelEntity> list) {
        try (OutputStream outputStream = new FileOutputStream(fileName)) {
            EasyExcel.write(outputStream, ExcelEntity.class).sheet().doWrite(list);
        } catch (Exception e) {
            //TODO 异常处理
        }
    }
}

其中,fileName 代表要写入 Excel 文件的路径,list 代表要写入的数据列表。

三、动态合并单元格

上述基础操作可以帮助我们完成对 Excel 文件的读写操作,但是有时我们需要对 Excel 中的数据进行更加灵活的处理,例如,我们需要动态地对相同名称的行进行合并。

EasyExcel 提供了抽象类 AbstractMergeStrategy,我们可以在自定义的类中继承这个类,然后重写其中的 merge() 方法实现动态合并单元格的功能。例如,我们要对上述 Excel 文件中的相同名称的行进行合并,可以定义以下这个类:

public class ExcelMergeStrategy extends AbstractMergeStrategy {
    private int rowIndex = -1;
    private String lastName;

    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
        if (head.getRowIndex() == 0 || !head.getHeadName().equals("姓名")) {
            return;
        }

        //获取当前行的数据
        List<Object> currentRowData = sheet.getRow(relativeRowIndex);

        //获取当前行姓名的值
        String name = currentRowData.get(0).toString();
        if (!name.equals(lastName)) {
            if (rowIndex != -1) {
                sheet.addMergedRegion(new CellRangeAddress(rowIndex, relativeRowIndex - 1, 0, 0));
            }
            rowIndex = relativeRowIndex;
            lastName = name;
        }

        if (relativeRowIndex == sheet.getLastRowNum()) {
            sheet.addMergedRegion(new CellRangeAddress(rowIndex, relativeRowIndex, 0, 0));
        }
    }
}

public class ExcelUtil {
    public static void readExcel(String fileName) {
        try (InputStream inputStream = new FileInputStream(fileName)) {
            EasyExcel.read(inputStream, ExcelEntity.class, new ExcelListener()).sheet().registerReadHandler(new ExcelMergeStrategy()).doRead();
        } catch (Exception e) {
            //TODO 异常处理
        }
    }
}

其中,我们重写的 merge() 方法中,每次读取一个单元格的时候都会被调用一次。我们可以判断当前行的姓名的值是否和上一行相等,如果相等,则不需要合并单元格;如果不相等,则需要将上一组相同名称的行进行合并。

最后,在读取 Excel 文件的时候,我们需要将自定义的单元格合并策略类作为参数传入到 registerReadHandler() 方法中。

四、总结

EasyExcel 是一个非常好用的 Java 操作 Excel 工具,可以帮助我们快速完成对 Excel 文件的读写操作。同时,它也支持动态合并单元格的功能,可以对 Excel 中的数据进行更加灵活的处理。希望本文对读者们有所帮助。