alibaba / easyexcel

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

在导出excel中,需要灵活的合并单元格内容,官网示例中用的LoopMergeStrategy只能做循环合并,并不能指定哪行哪列,有什么好的解决方案嘛?自己扩展LoopMergeStrategy总提示已经合并异常;实在不行就自己实现了CellWriteHandler并使用poi提供的合并方法来指定,在使用过程中出现了问题,麻烦有空帮忙指答一下,谢谢! #911

Closed wurainren closed 4 years ago

wurainren commented 4 years ago

异常代码


ERROR c.a.c.e.h.GlobalExceptionHandler - java.lang.IllegalStateException: Cannot add merged region A1:P1 to sheet because it overlaps with an existing merged region (A1:P1).
   这里写你的代码
```public class CustomTiaozhaCellWriteHandler implements CellWriteHandler {
        @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
            List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        // TODO Auto-generated method stub
        if (!isHead && cell.getRowIndex() == 1  &&  cell.getColumnIndex() == 3 )  {
            Sheet sheet  = writeSheetHolder.getSheet();
            CellRangeAddress cellAddresses = new CellRangeAddress(0,0,0,3);
            sheet.addMergedRegion(cellAddresses);
        }
      }

}
**异常提示**
请提供完整的异常提示,记住是全部异常!
我想通过单元格销毁后,直接自己指定合并哪行哪列!
**建议描述**
wurainren commented 4 years ago

使用的版本是v2.1.3

pdkst commented 4 years ago

如果只需要合并一次,请使用com.alibaba.excel.write.merge.OnceAbsoluteMergeStrategy

wurainren commented 4 years ago

多谢答复。 那合并多次呢?有没有比较好的解决方案?

pdkst commented 4 years ago

应该结合业务逻辑,根据参照LoopMergeStrategy源代码进行定制

Mengzuozhu commented 4 years ago

@wurainren ,怀疑你的合并区域与默认的表头合并冲突了,建议先取消默认的表头合并,再自定义合并单元格。看下POI的addMergedRegion、addMergedRegionUnsafe和validateMergedRegions方法。可参考以下代码:

    @Test
    public void dynamicHeadWrite() {
        String fileName = TestFileUtil.getPath() + "dynamicHeadWrite" + "1" + ".xlsx";
        EasyExcel.write(fileName)
            .registerWriteHandler(CellMergeStrategy())
            //取消默认的表头合并
            .automaticMergeHead(false)
            // 这里放入动态头
            .head(head()).sheet("模板")
            // 当然这里数据也可以用 List<List<String>> 去传入
            .doWrite(data());
    }

    private CellWriteHandler CellMergeStrategy() {
        return new CellWriteHandler() {
            @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 afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,
                                         List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex,
                                         Boolean isHead) {
                int rowIndex = cell.getRowIndex();
                int columnIndex = cell.getColumnIndex();
                //自己指定需要合并的单元格区域
                if (rowIndex == 0 && columnIndex == 0) {
                    CellRangeAddress cellRangeAddress = new CellRangeAddress(rowIndex, rowIndex, columnIndex,
                        columnIndex + 1);
                    writeSheetHolder.getSheet().addMergedRegionUnsafe(cellRangeAddress);
                }
            }
        };
    }