记录一次POI导出Excel由于大量单元格合并导致频繁GC问题
记录一次POI导出Excel由于大量单元格合并导致频繁GC问题
解决方法
设置合并GC的时候采用
addMergedRegionUnsafe
方法替换addMergedRegion
。
问题排查
- 监听GC与内存情况
- 代码定位
初步判定POI操作excel单元格的问题,到底是哪一步通过耗时打印进一步定位到设置合并单元格方法
org.apache.poi.xssf.usermodel.XSSFSheet#addMergedRegion(org.apache.poi.ss.util.CellRangeAddress)
查看源码得到如下图
查看 validateMergedRegions
相关源码如下,基本确认了每次设置合并的时候调用到 getMergedRegions
方法重新遍历创建了一遍对象。
/** * Verify that candidate region does not intersect with an existing merged region in this sheet * * @param candidateRegion the range of cells to verify * @throws IllegalStateException if candidate region intersects an existing merged region in this sheet (or candidateRegion is already merged in this sheet) */ private void validateMergedRegions(CellRangeAddress candidateRegion) { for (final CellRangeAddress existingRegion : getMergedRegions()) { if (existingRegion.intersects(candidateRegion)) { throw new IllegalStateException("Cannot add merged region " + candidateRegion.formatAsString() + " to sheet because it overlaps with an existing merged region (" + existingRegion.formatAsString() + ")."); } } } /** * Returns the list of merged regions. If you want multiple regions, this is * faster than calling {@link #getMergedRegion(int)} each time. * * @return the list of merged regions */ @Override public List<CellRangeAddress> getMergedRegions() { List<CellRangeAddress> addresses = new ArrayList<>(); CTMergeCells ctMergeCells = worksheet.getMergeCells(); if(ctMergeCells == null) { return addresses; } for(CTMergeCell ctMergeCell : ctMergeCells.getMergeCellArray()) { String ref = ctMergeCell.getRef(); addresses.add(CellRangeAddress.valueOf(ref)); } return addresses; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律