EasyExcel模板填充list时按第一行格式合并单元格(含分页线设置)

前言:

在使用easyExcel填充list时,第一行存在合并单元格的情况下,后面使用forceNewRow()填充的行却没有合并样式。

模板:

填充后:

自定义拦截器:

根据官方文档的提示,我们需要自定义拦截器来对单元格进行操作。拦截器MyHandler继承了easyExcel的AbstractMergeStrategy类,并重写了merge方法用于定义具体的单元格合并逻辑。

merge方法主要用于检查当前单元格的上一行对应位置的单元格是否已被合并。如果已被合并,则在当前单元格的位置创建一个新的合并区域,并设置该区域的边框样式,以此来保持填充list时合并区域的连续性。

java 复制代码
public class MyHandler extends AbstractMergeStrategy {

    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
        if(relativeRowIndex==null ||relativeRowIndex==0){
            return;
        }

        int rowIndex = cell.getRowIndex();
        int colIndex = cell.getColumnIndex();
        sheet=cell.getSheet();
        Row preRow = sheet.getRow(rowIndex - 1);
        Cell preCell = preRow.getCell(colIndex);//获取上一行的该格
        List<CellRangeAddress> list = sheet.getMergedRegions();
        for (int i = 0; i < list.size(); i++) {
            CellRangeAddress cellRangeAddress = list.get(i);
            if (cellRangeAddress.containsRow(preCell.getRowIndex()) && cellRangeAddress.containsColumn(preCell.getColumnIndex())) {
                int lastColIndex = cellRangeAddress.getLastColumn();
                int firstColIndex = cellRangeAddress.getFirstColumn();
                int firstRowIndex = cellRangeAddress.getFirstRow();
                CellRangeAddress cra = new CellRangeAddress(rowIndex, rowIndex, firstColIndex, lastColIndex);
                sheet.addMergedRegion(cra);

                //设置合并区域cra的边框
                RegionUtil.setBorderBottom(BorderStyle.THIN, cra, sheet);
                RegionUtil.setBorderLeft(BorderStyle.THIN, cra, sheet);
                RegionUtil.setBorderRight(BorderStyle.THIN, cra, sheet);
                RegionUtil.setBorderTop(BorderStyle.THIN, cra, sheet);
                return;
            }
        }
    }
}

定义好拦截器后,我们要在填充时调用registerWriteHandler(),将定义的拦截器作为参数。

填充后:

单元格列合并:

上面的效果已经满足了大部分人的需求。但可能有些人会有将第一列相同的item单元格进行列合并的需求,那么我们只需要将拦截器中merge方法的新增合并区域cra修改如下。如果当前单元格的内容和上一行单元格内容相等,我们要先移除上一行单元格的合并区域再和当前单元格组成新的合并区域,而不能直接合并上一行单元格,否则会报错:

修改的部分调用了getCellContent()方法,这个方法主要是来获取单元格的内容来进行比较的,具体的实现如下:

java 复制代码
private String getCellContent(Cell cell) {
        if (cell == null) {
            return null;
        }
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    return Double.toString(cell.getNumericCellValue());
                }
            case BOOLEAN:
                return Boolean.toString(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            default:
                return "";
        }
}

填充后:

分页线:

可以看到现在第一列的item,相同内容的已经进行列合并了。但是我发现一个问题就是分页线错位了,在填充完list之后,分页线并没有随数据一起下移。所以我们需要在拦截器的merge方法中添加下面几行代码,就可以重新设置分页线了。

下面代码将分页线设置在填充的list最后一行数据的下一行,有其他需求的伙伴可以看情况自行修改:

填充后:

参考:EasyExcel填充时合并单元格_easyexcel填充数据合并单元格-CSDN博客文章浏览阅读9k次,点赞29次,收藏51次。由于填充时第二行开始,easyexcel不会自动合并单元格,所以需要自定义handler根据上一行的合并信息自行合并public class MyHandler extends AbstractMergeStrategy {@Overrideprotected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {if(relativeRowIndex==null ||relativeRowIn_easyexcel填充数据合并单元格https://blog.csdn.net/weixin_44682948/article/details/112897500

相关推荐
老鑫安全培训11 分钟前
从安全角度看 SEH 和 VEH
java·网络·安全·网络安全·系统安全·安全威胁分析
罗政12 分钟前
PDF书籍《手写调用链监控APM系统-Java版》第8章 插件与链路的结合:Gson插件实现
java·pdf·linq
马船长38 分钟前
RCE-PLUS (学习记录)
java·linux·前端
HelloZheQ43 分钟前
深入了解 Java 字符串:基础、操作与性能优化
java·python·性能优化
魔法工坊1 小时前
只谈C++11新特性 - 删除函数
java·开发语言·c++
hfxns_1 小时前
Excel无法插入新单元格怎么办?有解决方法吗?
excel
落霞与孤鹭齐飞。。1 小时前
学生考勤系统|Java|SSM|VUE| 前后端分离
java·mysql·毕业设计·课程设计
橙子家czzj1 小时前
关于 K8s 的一些基础概念整理-补充【k8s系列之二】
java·开发语言·kubernetes
云:2 小时前
寒假准备找实习复习java基础-day1
java·开发语言
罗政2 小时前
PDF书籍《手写调用链监控APM系统-Java版》第3章 配置文件系统的建立
java·pdf·linq