alibaba / easyexcel

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

设置字体为微软雅黑,导致和动态合并单元格冲突 #3842

Open 895341748 opened 3 months ago

895341748 commented 3 months ago

1)设置字体为微软雅黑 public HorizontalCellStyleStrategy setStyleStrategy() { // 头的策略 WriteCellStyle headWriteCellStyle = new WriteCellStyle();

    // 内容的策略
    WriteCellStyle contentWriteCellStyle = new WriteCellStyle();

    // 设置字体
    WriteFont contentWriteFont = new WriteFont();
    contentWriteFont.setFontName("微软雅黑");
    contentWriteCellStyle.setWriteFont(contentWriteFont);

    contentWriteCellStyle.setWrapped(true); // 自动换行
    contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 设置垂直居中
    contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); // 设置水平居中

    // 设置每个单元格的边框
    /*contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
    contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
    contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
    contentWriteCellStyle.setBorderRight(BorderStyle.THIN);*/

    // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
    HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    return horizontalCellStyleStrategy;
}

2)动态合并单元格 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);
        }
    }
}

}

3)bug截图 image

备注:如果设置为宋体就是正常的。设置为微软雅黑则出现该bug

895341748 commented 3 months ago
com.alibaba easyexcel 3.3.1