如何处理ClassCastException:单列结果集导出Excel异常
问题与解决方案
问题背景
遗留代码中,查询结果赋值给List<Object[]>时存在类型不一致问题:
- 多列结果集:每个元素是
Object[]数组,日志打印为[[Ljava.lang.Object;@391472f5]格式 - 单列结果集:每个元素是直接值(如
String),日志打印为[USA, EUROPE]或[USA]格式
这种不一致导致exportExcel方法遍历时报错:java.lang.ClassCastException: java.lang.String cannot be cast to [Ljava.lang.Object;,因为方法默认每个元素都是Object[],但单列时实际是单个对象。
解决方案
方案一:预处理查询结果(推荐)
在获取查询结果后,统一将所有元素转为Object[]类型,确保reportResults的元素类型完全一致:
List<Object[]> reportResults = new ArrayList<>(); // 先获取原始结果,避免类型强制转换报错 List<?> rawResults = query.getResultList(); for (Object item : rawResults) { if (item instanceof Object[]) { reportResults.add((Object[]) item); } else { // 单列情况,将单个元素包装为长度1的数组 reportResults.add(new Object[]{item}); } } logger.info("reportResults ==== " + reportResults.toString()); workbook = expService.exportExcel(fileName, reportResults, reportHeaders);
此方案无需修改exportExcel方法,保持原有方法的参数约定,适合需要兼容原有调用逻辑的场景。
方案二:修改exportExcel方法兼容类型
直接在导出方法内部处理元素类型差异,调整方法参数为List<?>以接收任意类型元素,再统一转为Object[]遍历:
public XSSFWorkbook exportExcel(String reportName, List<?> reportData, String headers) throws Exception { // ... 原有初始化代码,如创建sheet、rownum初始化等 System.out.println("... " + reportData.size()); for (int i = 0; i < reportData.size(); i++) { row = sheet.createRow(rownum); rownum++; Object item = reportData.get(i); System.out.println("....... " + item); // 统一转换为Object[]数组 Object[] rowData; if (item instanceof Object[]) { rowData = (Object[]) item; } else { rowData = new Object[]{item}; } for (int j = 0; j < rowData.length; j++) { cell = row.createCell(j); Object oCellValue = rowData[j]; if (oCellValue != null) { String className = oCellValue.getClass().getName(); if (className.equals(Timestamp.class.getName())) { CellStyle cStyle = workbook.createCellStyle(); cStyle.setDataFormat((short)14); Timestamp tsValue=(Timestamp)oCellValue; Date dtValue = new Date(tsValue.getTime()); cell.setCellValue(dtValue); cell.setCellStyle(cStyle); } else { cell.setCellValue(""+oCellValue); } } else { cell.setCellValue(""); } } } // ... 原有后续代码,如返回workbook等 }
此方案修改了方法的参数类型,使其能直接兼容单列/多列结果集,适合需要简化调用端逻辑的场景。
内容的提问来源于stack exchange,提问作者Geek
相关产品推荐
相关产品推荐

