alibaba / easyexcel

快速、简洁、解决大文件内存溢出的java处理Excel工具
https://easyexcel.opensource.alibaba.com
Apache License 2.0
31.96k stars 7.49k forks source link

easyexcel 3.3.1动态合并单元格后,合并的单元格内容出现空白 #3651

Open 895341748 opened 8 months ago

895341748 commented 8 months ago

导出excel后,合并的单元格出现空白。如果双击空白处,或上下拖动滚动条,此时空白的单元格的内容就显示出来了。

1 2

采用的是模板填充的方式。确认模板没有问题。我已经吧整个sheet删除了,重新新增一个sheet还是一样。

合并代码: public class ExcelReportMergeStrategy implements CellWriteHandler {

private int mergeRowIndex;

private int[] mergeColumnIndex;

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

@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {

}

@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

}

@Override
public void afterCellDataConverted(CellWriteHandlerContext context) {

}

@Override
public void afterCellDispose(CellWriteHandlerContext context) {
    WriteSheetHolder writeSheetHolder=context.getWriteSheetHolder();
    Cell cell=context.getCell();

    int curRowIndex = cell.getRowIndex();
    int curColIndex = cell.getColumnIndex();
    if (curRowIndex > mergeRowIndex) {
        for (int i = 0; i < mergeColumnIndex.length; i++) {
            if (curColIndex == mergeColumnIndex[i]) {
                mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
                break;
            }
        }
    }
}

/**
 * 当前单元格向上合并
 * @param writeSheetHolder
 * @param cell             当前单元格
 * @param curRowIndex      当前行
 * @param curColIndex      当前列
 */
private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
    Object curData = cell.getCellType() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
    Row prevRow = cell.getSheet().getRow(curRowIndex - 1);
    Row curRow = cell.getSheet().getRow(curRowIndex);
    if (prevRow == null) {
        prevRow = writeSheetHolder.getCachedSheet().getRow(curRowIndex - 1);
    }
    Cell prevFirstColCell = prevRow.getCell(0);
    Cell curFirstColCell = curRow.getCell(0);
    Object prevFirstColData = prevFirstColCell.getCellType() == CellType.STRING ? prevFirstColCell.getStringCellValue() : prevFirstColCell.getNumericCellValue();
    Object curFirstColData = curFirstColCell.getCellType() == CellType.STRING ? curFirstColCell.getStringCellValue() : curFirstColCell.getNumericCellValue();
    Cell prevCell = prevRow.getCell(curColIndex);
    Object prevData = prevCell.getCellType() == CellType.STRING ? prevCell.getStringCellValue() : prevCell.getNumericCellValue();
    boolean isDataSame = curData.equals(prevData) && curFirstColData.equals(prevFirstColData);
    if(isDataSame){
        Sheet sheet = writeSheetHolder.getSheet();
        List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
        boolean isMerged = false;
        for(int i = 0; i < mergeRegions.size(); i++) {
            CellRangeAddress cellRangeAddress = mergeRegions.get(i);
            if(cellRangeAddress.isInRange(curRowIndex - 1, curColIndex)){
                sheet.removeMergedRegion(i);
                cellRangeAddress.setLastRow(curRowIndex);
                sheet.addMergedRegionUnsafe(cellRangeAddress);
                isMerged = true;
            }
        }
        if(!isMerged){
            CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
            sheet.addMergedRegion(cellRangeAddress);
        }
    }
}

}

895341748 commented 8 months ago

int mergeRowIndex=0; int[] mergeColumeIndex = new int[]{0,1}; WriteSheet writeSheet = EasyExcel.writerSheet(0) .registerWriteHandler(new ExcelReportMergeStrategy(mergeRowIndex, mergeColumeIndex)) .registerWriteHandler(setStyleStrategy()) .build(); excelWriter.fill(agentList, writeSheet);

895341748 commented 8 months ago

数据分组,当只有1个分组时,不会复现。如果存在大于1个分组才会出现