记录一次POI导出Excel由于大量单元格合并导致频繁GC问题

记录一次POI导出Excel由于大量单元格合并导致频繁GC问题

解决方法

设置合并GC的时候采用 addMergedRegionUnsafe 方法替换 addMergedRegion

问题排查

  1. 监听GC与内存情况

image

image

  1. 代码定位
    初步判定POI操作excel单元格的问题,到底是哪一步通过耗时打印进一步定位到设置合并单元格方法
org.apache.poi.xssf.usermodel.XSSFSheet#addMergedRegion(org.apache.poi.ss.util.CellRangeAddress)

查看源码得到如下图
image
查看 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;
}
posted @   临渊不羡渔  阅读(412)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示