如何正确移除XSSFWorkbook中的所有名称避免运行时异常?
异常原因说明
两种写法触发异常的核心原因如下:
- for-each循环本质依赖集合迭代器实现,遍历过程中直接调用
workbook.removeName()修改工作簿内部存储名称的原始集合,会触发迭代器的快速失败(fail-fast)机制,抛出ConcurrentModificationException。 workbook.getAllNames()返回的是工作簿内部名称集合的不可修改视图,该视图的迭代器并未实现remove()方法,直接调用就会抛出UnsupportedOperationException。
可行实现方案
不要直接遍历getAllNames()返回的原始集合,先将所有名称元素拷贝到一个独立的、完全和工作簿内部集合解耦的新集合中,再遍历这个新集合逐个执行删除操作即可:
import org.apache.poi.xssf.usermodel.XSSFName; import java.util.ArrayList; import java.util.List; // 把所有名称拷贝到独立的ArrayList,和原内部集合切断关联 List<XSSFName> nameList = new ArrayList<>(workbook.getAllNames()); for (XSSFName name : nameList) { workbook.removeName(name); }
如果使用的是Apache POI 5.0.0及以上版本,还可以直接调用内置的清空方法,不需要手动遍历,执行效率更高:
workbook.clearNames();
如果需要按规则过滤删除部分名称(比如仅删除用户自定义名称、保留Excel内置名称),直接在遍历副本集合时增加对应判断逻辑即可,不会触发结构修改相关的运行时异常。
内容的提问来源于stack exchange,提问作者emilelm
相关产品推荐
相关产品推荐

