EasyExcel合并单元格导出慢,并消耗CPU

问题遇到的现象和发生背景

使用 EasyExcel 自定义策略合并单元格时,2k条数据需要耗时10s。且cpu使用率过高

用代码块功能插入代码,请勿粘贴截图
public class CellMergeStrategy implements CellWriteHandler {

    /**
     * 合并字段的下标
     */
    private int[] mergeColumnIndex;
    /**
     * 合并几行
     */
    private int mergeRowIndex;

    public CellMergeStrategy() {
    }

    public CellMergeStrategy(int mergeRowIndex, int[] mergeColumnIndex) {
        this.mergeRowIndex = mergeRowIndex;
        this.mergeColumnIndex = mergeColumnIndex;
    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
                                 List> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
        //当前行
        int curRowIndex = cell.getRowIndex();
        //当前列
        int curColIndex = cell.getColumnIndex();

        if (curRowIndex > mergeRowIndex) {
            for (int columnIndex : mergeColumnIndex) {
                if (curColIndex == columnIndex) {
                    mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
                    break;
                }
            }
        }
    }
    private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
        //获取当前行的当前列的数据和上一行的当前列列数据,通过上一行数据是否相同进行合并
        Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() :
                cell.getNumericCellValue();
        Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
        Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() :
                preCell.getNumericCellValue();

        // 比较当前行的第一列的单元格与上一行是否相同,相同合并当前单元格与上一行
        Cell groupIdCell = cell.getSheet().getRow(curRowIndex).getCell(0);
        Object groupData = groupIdCell.getCellTypeEnum() == CellType.STRING ? groupIdCell.getStringCellValue() :
                groupIdCell.getNumericCellValue();
        Cell groupIdPreCell = cell.getSheet().getRow(curRowIndex - 1).getCell(0);
        Object groupPreData = groupIdPreCell.getCellTypeEnum() == CellType.STRING ? groupIdPreCell.getStringCellValue() :
                groupIdPreCell.getNumericCellValue();
        if (curData.equals(preData)&& Objects.equals(groupData,groupPreData)) {
            Sheet sheet = writeSheetHolder.getSheet();
            List mergeRegions = sheet.getMergedRegions();
            boolean isMerged = false;
            for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
                CellRangeAddress cellRangeAddr = mergeRegions.get(i);
                // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
                if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
                    sheet.removeMergedRegion(i);
                    cellRangeAddr.setLastRow(curRowIndex);
                    sheet.addMergedRegionUnsafe(cellRangeAddr);
                    isMerged = true;
                }
            }
            // 若上一个单元格未被合并,则新增合并单元
            if (!isMerged) {
                CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex,
                        curColIndex);
                sheet.addMergedRegionUnsafe(cellRangeAddress);
            }
        }
    }
}
运行结果及报错内容

导出时间过久,cpu到达峰值.

我的解答思路和尝试过的方法

导出结束后,cpu4核cpu依旧保持100%的使用率.
查看线程占用发现有个自定义策略中有个addMergedRegion导致。
下面是线程异常图.

img

img

我想要达到的结果

3秒内可导出2000条数据,并降低cpu的使用率. 如有问题easyExcel相关解决方案,或者有高效率的合并单元格解决技术方案.请广大网友指教一二. 采纳后可以请您喝杯咖啡以表感谢. 谢谢大家.

一个简单的导出,一百万数据30秒,http://t.csdn.cn/CXYeg,主要看下是哪里慢,查询数据慢还是循环写数据慢,再根据具体的地方优化