使用poi进行excel模板导出,出现异常org.apache.xmlbeans.impl.values.XmlValueDisconnectedException
异常的部分代码块为:
org.apache.xmlbeans.impl.values.XmlValueDisconnectedException
at org.apache.xmlbeans.impl.values.XmlObjectBase.check_orphaned(XmlObjectBase.java:1258)
at org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTCellImpl.isSetF(Unknown Source)
at org.apache.poi.xssf.usermodel.XSSFCell.isFormulaCell(XSSFCell.java:661)
at org.apache.poi.xssf.usermodel.XSSFCell.getCellType(XSSFCell.java:679)
at net.sf.jxls.transformer.CellTransformer.transform(CellTransformer.java:35)
at net.sf.jxls.transformer.SimpleRowTransformer.transform(SimpleRowTransformer.java:68)
at net.sf.jxls.transformer.SheetTransformer.transformSheet(SheetTransformer.java:108)
at net.sf.jxls.transformer.XLSTransformer.transformWorkbook(XLSTransformer.java:249)
at net.sf.jxls.transformer.XLSTransformer.transformXLS(XLSTransformer.java:222)
at com.cxwl.common.util.ExcelUtil.exportTemplate(ExcelUtil.java:142)
export Template代码
public static MultipartFile exportTemplate(String fileName, String fileUrl, Map<String, Object> contextMap) throws Exception {
MultipartFile multipartFile = null;
XLSTransformer transformer = new XLSTransformer();
File inputFile = new File(fileUrl);
try (FileInputStream inputStream = new FileInputStream(inputFile)) {
Workbook workbook;
try {
workbook = transformer.transformXLS(inputStream, contextMap);
} catch (org.apache.xmlbeans.impl.values.XmlValueDisconnectedException e) {
// 处理异常
throw new RuntimeException("XML Value Disconnected Exception during XLS transformation", e);
}
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
workbook.write(bos);
try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray())) {
multipartFile = new MockMultipartFile(fileName, fileName, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", bis);
}
}
} catch (IOException e) {
// 处理文件 IO 异常
throw new RuntimeException("File IO Exception during XLS transformation", e);
}
return multipartFile;
}
出现异常的场景:
使用jxls进行操作poi Excel导出模板数据时,模板正常导出,但打印上述日志,查看excel内容发现数据被截断,不正常显示。
解决思路:
①:异常出现的原因:
这个异常 org.apache.xmlbeans.impl.values.XmlValueDisconnectedException
表示在处理 XML 数据时,某个 XML 对象已断开连接,通常发生在对象已经被从其父文档或上下文中移除之后,但仍然尝试对其进行操作。
虽然文件已导出,但这个异常可能会对数据完整性和文件的正确性产生影响。具体影响取决于以下几个方面:
- 数据完整性:异常可能导致导出的文件中缺少某些数据或部分数据不正确。
- 文件格式:如果 XML 结构被破坏,导出的文件可能无法被其他应用程序正确解析或打开。
- 隐藏错误:虽然文件导出成功,但异常可能掩盖了其他潜在的错误或问题。
为了解决这个问题,可以采取以下措施:
- 检查输入数据:确保传递给
transformer.transformXLS
的inputStream
和contextMap
是有效且完整的。 - 调试代码:在抛出异常的位置添加调试信息,检查哪些 XML 对象断开连接,找出根本原因。
- 更新库版本:确保使用的 Apache POI 和 XMLBeans 库是最新版本,因为新版本可能修复了相关的 bug。
- 处理异常:在代码中添加异常处理逻辑,捕获并处理
XmlValueDisconnectedException
,确保导出的文件在出现异常时依然能保持数据完整性。
一:使用排查法,将excel模板中的内容进行逐步删除,排除出报错的点
如:
博主这里是多个sheet页,一个一个sheet页进行累加排查。可以直接查看截取后不正常显示的开始端在哪。
如上图显示是再进行jx:forEach 【individualTotalVisaTypeCountList】时出现的问题。那就进行定位到生成excel时对应的individualTotalVisaTypeCountList数据情况。
二:定位到java代码对应占位符参数后,进行debug调试,检查数据,发现断点调试时【individualTotalVisaTypeCountList】为数组,并且数组的size==0。
三:检查模板中的对应关系
这里发现在表头中有对visaTypeList进行了forEach但是在合计中size==0,因此可以定位到问题为头为N个数据长度,但是合计尾部为0,导致在进行处理excel导出时出现异常
根据visaTypeList的长度去进行初始化【individualTotalVisaTypeCountList】中的数据即可解决
List<Integer> individualTotalVisaTypeCountList = new ArrayList<>(); // 初始化集合 for (int i = 0; i < length; i++) { individualTotalVisaTypeCountList.add(0); }
注:博主这里使用poi版本为4.1.2