You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

未打开保存的复制Excel文件无法读取数据的问题求助

解决未保存复制Excel文件的读取问题

问题根源

从其他Excel复制而来的未保存文件,本质是系统生成的临时文件,文件结构未完成规范化持久化,Apache POI默认无法正确解析这类文件的内容;而手动打开保存后,Excel会补全文件结构的完整性,POI就能正常读取。

解决方案

1. 自动完成文件结构规范化(模拟手动保存)

在读取前先用POI打开文件并重新写入,相当于自动执行“打开-保存”操作,修复文件结构:

fun normalizeExcelFile(filePath: String) {
    FileInputStream(filePath).use { fis ->
        val wb = XSSWorkbook(fis)
        FileOutputStream(filePath).use { fos ->
            wb.write(fos)
        }
    }
}

调用读取逻辑前先执行这个方法:

normalizeExcelFile(filePath)
// 后续执行你的读取循环

2. 修复excelReader函数的潜在问题

原函数存在未关闭流、未处理空行/空单元格、使用过时API等问题,修改后版本:

fun excelReader(filePath: String, row: String, col: String, sheet: Int): String? {
    FileInputStream(filePath).use { fis -> // 用use自动关闭流,避免资源泄漏
        val wb = XSSWorkbook(fis)
        val targetSheet = wb.getSheetAt(sheet) ?: return null
        val evaluator = wb.creationHelper.createFormulaEvaluator()
        
        val cellReference = CellReference(col + row)
        val targetRow = targetSheet.getRow(cellReference.row) ?: return null
        val cell = targetRow.getCell(cellReference.col.toInt()) ?: return null
        
        // 兼容不同单元格类型,替换过时的setCellType
        return when (cell.cellType) {
            Cell.CELL_TYPE_STRING -> cell.stringCellValue
            Cell.CELL_TYPE_NUMERIC -> if (DateUtil.isCellDateFormatted(cell)) {
                cell.dateCellValue.toString()
            } else {
                cell.numericCellValue.toString()
            }
            Cell.CELL_TYPE_BOOLEAN -> cell.booleanCellValue.toString()
            Cell.CELL_TYPE_FORMULA -> {
                val cellValue = evaluator.evaluate(cell)
                when (cellValue.cellType) {
                    Cell.CELL_TYPE_STRING -> cellValue.stringValue
                    Cell.CELL_TYPE_NUMERIC -> cellValue.numberValue.toString()
                    Cell.CELL_TYPE_BOOLEAN -> cellValue.booleanValue.toString()
                    else -> null
                }
            }
            else -> null
        }
    }
}

3. 优化读取循环逻辑

避免每次循环创建新的Excel实例,减少资源消耗:

val excel = Excel()
while (true) {
    val cellValue = excel.excelReader(filePath, rowExcel.toString(), "A", 4)
    if (cellValue == null) break
    data.appendText("$cellValue\r\n")
    rowExcel++
}

注意事项

  • 自动规范化文件的方法会覆盖原文件,建议操作前备份文件,或使用临时文件中转处理。
  • 修改后的读取函数增加了空值判断,避免空指针异常,同时兼容多种单元格数据类型。

内容的提问来源于stack exchange,提问作者user999

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:52:40