【学习总结】EasyExcel合并同列不同行,表格数据相同的行

实体类

java 复制代码
@Data
@HeadRowHeight(50)
@ContentStyle(horizontalAlignment = HorizontalAlignmentEnum.CENTER, verticalAlignment = VerticalAlignmentEnum.CENTER, wrapped = BooleanEnum.TRUE)
public class CriterionDataExportDTO {


    @ColumnWidth(15)
    @ExcelProperty(value = "所属街道")
    private String streetName;

    @ColumnWidth(25)
    @ExcelProperty(value = "点位类型")
    private String pointType;

    @ColumnWidth(40)
    @ExcelProperty(value = "测评点位")
    private String pointName;

    @ColumnWidth(50)

    @ExcelProperty(value = "问题明细")
    private String issueDetails;

    @ColumnWidth(15)
    @ExcelProperty(value = "问题笔数")
    private Integer issueCount;

    @ColumnWidth(25)
    @ExcelProperty(value = "二级负责单位")
    private String responsibleUnit2;

    @ColumnWidth(25)
    @ExcelProperty(value = "二级单位接件时间")
    private String assignTime2;

    @ColumnWidth(25)
    @ExcelProperty(value = "三级负责单位")
    private String responsibleUnit3;

    @ColumnWidth(25)
    @ExcelProperty(value = "三级单位接件时间")
    private String assignTime3;

    @ExcelIgnore
    private Integer pushStatus;

}

工具类

继承合并单元格,重写合并方法

java 复制代码
package com.jeesite.modules.utils.easyExcel;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.merge.AbstractMergeStrategy;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.*;

public class EasyExcelUtils extends AbstractMergeStrategy {
    private Map<String, List<Integer>> nameRowMap = new HashMap<>();

    @Override
    protected void merge(Sheet sheet, Cell cell, Head head, Integer relativeRowIndex) {
        int columnIndex = cell.getColumnIndex();

        if (columnIndex == 0) {
            String currentValue = cell.getStringCellValue();
            if (currentValue == null || currentValue.isEmpty()) {
                return;
            }

            int currentRowIndex = cell.getRowIndex();
            List<Integer> rowList = nameRowMap.getOrDefault(currentValue, new ArrayList<>());
            rowList.add(currentRowIndex);
            nameRowMap.put(currentValue, rowList);

            mergeRows(sheet, currentValue, rowList, columnIndex);
        }

        if (columnIndex == 2) {
            String currentValue = cell.getStringCellValue();
            if (currentValue == null || currentValue.isEmpty()) {
                return;
            }

            int currentRowIndex = cell.getRowIndex();
            List<Integer> rowList = nameRowMap.getOrDefault(currentValue, new ArrayList<>());
            rowList.add(currentRowIndex);
            nameRowMap.put(currentValue, rowList);

            mergeRows(sheet, currentValue, rowList, columnIndex);
        }
    }

    private void mergeRows(Sheet sheet, String value, List<Integer> rowList, int columnIndex) {
        if (rowList.size() <= 1) {
            return;
        }

        int startRow = rowList.get(0);
        int endRow = rowList.get(rowList.size() - 1);

        // 检查是否存在重叠合并区域
        CellRangeAddress existingRegion = findOverlappingRegion(sheet, startRow, endRow, columnIndex);
        if (existingRegion != null) {
            // 扩展现有合并区域以适应新的合并行
            startRow = Math.min(existingRegion.getFirstRow(), startRow);
            endRow = Math.max(existingRegion.getLastRow(), endRow);

            // 移除现有合并区域
            removeMergedRegion(sheet, existingRegion);
        }

        CellRangeAddress range = new CellRangeAddress(startRow, endRow, columnIndex, columnIndex);
        sheet.addMergedRegionUnsafe(range);
    }

    private CellRangeAddress findOverlappingRegion(Sheet sheet, int startRow, int endRow, int columnIndex) {
        for (CellRangeAddress region : sheet.getMergedRegions()) {
            if (region.getFirstColumn() == columnIndex && region.getLastColumn() == columnIndex) {
                // 只考虑指定列的合并区域
                if (startRow <= region.getLastRow() && endRow >= region.getFirstRow()) {
                    return region;
                }
            }
        }
        return null;
    }

    private void removeMergedRegion(Sheet sheet, CellRangeAddress region) {
        int index = -1;
        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
            CellRangeAddress mergedRegion = sheet.getMergedRegion(i);
            if (mergedRegion.equals(region)) {
                index = i;
                break;
            }
        }
        if (index >= 0) {
            sheet.removeMergedRegion(index);
        }
    }
}

调用

java 复制代码
public void exportTaskDetails() {
        List<CriterionDataExportDTO> dataDetails = dataDao.findTaskDataDetails();
        for (CriterionDataExportDTO item : dataDetails) {
            //数据处理
            }
        }
		
		//写入路径
        String fileName =  "D:\\数据测试_" + System.currentTimeMillis() + ".xlsx";
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);

        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)15);
        headWriteCellStyle.setWriteFont(headWriteFont);

        HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
        EasyExcel.write(fileName, CriterionDataExportDTO.class)
                .registerWriteHandler(new EasyExcelUtils())
                .registerWriteHandler(horizontalCellStyleStrategy)
                .sheet("模板")
                .doWrite(dataDetails);

    }
    
    
    
相关推荐
_BugMan39 分钟前
【IDEA】干活?一个IDEA即可,集成开发平台打造攻略
java·ide·intellij-idea
YA3332 小时前
java设计模式二、工厂
java·开发语言·设计模式
金色天际线-2 小时前
Nginx 优化与防盗链配置指南
java·后端·spring
我爱挣钱我也要早睡!3 小时前
Java 复习笔记
java·开发语言·笔记
AD钙奶-lalala5 小时前
Mac OS上搭建 http server
java
知识分享小能手5 小时前
React学习教程,从入门到精通, React 属性(Props)语法知识点与案例详解(14)
前端·javascript·vue.js·学习·react.js·vue·react
茯苓gao8 小时前
STM32G4 速度环开环,电流环闭环 IF模式建模
笔记·stm32·单片机·嵌入式硬件·学习
是誰萆微了承諾8 小时前
【golang学习笔记 gin 】1.2 redis 的使用
笔记·学习·golang
皮皮林5518 小时前
SpringBoot 全局/局部双模式 Gzip 压缩实战:14MB GeoJSON 秒变 3MB
java·spring boot
weixin_456904279 小时前
Spring Boot 用户管理系统
java·spring boot·后端