使用 WorkbookFactory.create(FileInputStream) 讀取 Excel 2003 (.xls) 正常,但讀取 Excel 2007 (.xlsx) 時程式卡住,既不拋出異常也讀不出資料。
Excel 2003 與 2007 採用完全不同的檔案格式:
HSSFWorkbookXSSFWorkbookWorkbookFactory 雖支援自動識別,但某些版本或環境下對 .xlsx 支援不穩定,特別是缺少 ooxml 相關依賴時。
// 根據副檔名判斷
String filePath = "data.xlsx";
FileInputStream fis = new FileInputStream(filePath);
Workbook workbook;
if (filePath.endsWith(".xlsx")) {
workbook = new XSSFWorkbook(fis); // Excel 2007+
} else if (filePath.endsWith(".xls")) {
workbook = new HSSFWorkbook(fis); // Excel 2003
} else {
throw new IllegalArgumentException("不支援的檔案格式");
}
Maven 專案需同時引入:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
try (FileInputStream fis = new FileInputStream(file)) {
Workbook wb = WorkbookFactory.create(fis);
// 立即驗證是否成功載入
if (wb.getNumberOfSheets() == 0) {
throw new IOException("工作簿為空或格式不支援");
}
// 後續處理...
} catch (Exception e) {
log.error("讀取 Excel 失敗: {}", file.getName(), e);
throw new RuntimeException("Excel 解析異常", e);
}
public List<Map<String, String>> readExcel(File file) {
List<Map<String, String>> data = new ArrayList<>();
try (FileInputStream fis = new FileInputStream(file)) {
Workbook wb = WorkbookFactory.create(fis);
Sheet sheet = wb.getSheetAt(0);
Row headerRow = sheet.getRow(0);
int colNum = headerRow.getPhysicalNumberOfCells();
for (int i = 1; i <= sheet.getLastRowNum(); i++) {
Row row = sheet.getRow(i);
if (row == null) continue;
Map<String, String> rowData = new HashMap<>();
for (int j = 0; j < colNum; j++) {
Cell cell = row.getCell(j);
String key = getCellValueAsString(headerRow.getCell(j));
String value = getCellValueAsString(cell);
rowData.put(key, value);
}
data.add(rowData);
}
} catch (Exception e) {
throw new RuntimeException("Excel 讀取失敗", e);
}
return data;
}
SXSSFWorkbook (串流模式) 避免 OOMcell.getCellType() 需處理 NUMERIC、STRING、BOOLEAN、FORMULA 等DateUtil.isCellDateFormatted(cell) 判斷sheet.getMergedRegions()