Swift使用xlsxreaderwriter更新Excel后无法保存问题排查
问题原因与解决方案
你碰到的这个问题其实是iOS开发里的常见坑——App的主Bundle是只读的!你直接从Bundle.main.path获取的文件路径,只能用来读取,根本没办法写入修改。哪怕控制台打印了一堆"Saving target"的日志,系统也会悄悄阻止你修改Bundle里的文件,所以你打开原文件自然看不到变化。
正确的处理流程
要解决这个问题,你需要先把Bundle里的Excel文件复制到App的Documents目录(这个目录是可读写的),之后所有的读取、修改、保存操作都针对这个副本。具体步骤如下:
- 编写一个工具函数,负责将Bundle里的原始文件复制到Documents目录(只需要复制一次,后续直接用Documents里的文件)
- 修改你的
getExcelCells和saveExcelFile函数,让它们操作Documents目录里的文件路径
修改后的代码示例
首先添加复制文件的工具函数:
private func getWritableExcelPath() -> String { // 获取Documents目录路径 let documentsDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] let targetPath = documentsDir.appending("/DatabaseV1.xlsx") // 如果Documents里没有这个文件,从Bundle复制过去 let fileManager = FileManager.default if !fileManager.fileExists(atPath: targetPath) { if let sourcePath = Bundle.main.path(forResource: "DatabaseV1", ofType: "xlsx") { do { try fileManager.copyItem(atPath: sourcePath, toPath: targetPath) } catch { print("复制文件失败: \(error.localizedDescription)") } } } return targetPath }
然后修改你的两个核心函数:
private func getExcelCells() { let path = getWritableExcelPath() // 用可读写的路径 let spreadsheet: BRAOfficeDocumentPackage = BRAOfficeDocumentPackage.open(path) let worksheet: BRAWorksheet = spreadsheet.workbook.worksheets[0] as! BRAWorksheet var cat1 = CellModel(categoryTitle: "Best DJ", firstCell: worksheet.cell(forCellReference: "B5"), secondCell: worksheet.cell(forCellReference: "B6"), thirdCell: worksheet.cell(forCellReference: "B7"), fourthCell: worksheet.cell(forCellReference: "B8")) let cat2 = CellModel(categoryTitle: "Best SGA", firstCell: worksheet.cell(forCellReference: "E5"), secondCell: worksheet.cell(forCellReference: "E6"), thirdCell: worksheet.cell(forCellReference: "E7"), fourthCell: worksheet.cell(forCellReference: "E8")) let cat3 = CellModel(categoryTitle: "Best Greek Organization", firstCell: worksheet.cell(forCellReference: "H5"), secondCell: worksheet.cell(forCellReference: "H6"), thirdCell: worksheet.cell(forCellReference: "H7"), fourthCell: worksheet.cell(forCellReference: "H8")) excelCells += [cat1, cat2, cat3] cat1.cellOne.setStringValue(nominees.optionA) let data = worksheet.cell(forCellReference: "A5").stringValue() print(cat1.cellOne.stringValue()) print(data) } private func saveExcelFile() { let path = getWritableExcelPath() // 用可读写的路径 let spreadsheet: BRAOfficeDocumentPackage = BRAOfficeDocumentPackage.open(path) let worksheet: BRAWorksheet = spreadsheet.workbook.worksheets[0] as! BRAWorksheet worksheet.save() spreadsheet.save() }
补充说明
- 为什么控制台显示保存成功?因为
xlsxreaderwriter库确实执行了内存中文件对象的保存逻辑,但它尝试写入的是Bundle里的只读路径,系统底层拒绝了这个写入操作,只是没有抛出明显的错误日志,导致你误以为保存成功。 - 如果你想验证修改是否生效,可以在保存后,读取Documents目录里的文件内容,或者用Xcode的"Devices and Simulators"工具查看App的Documents目录里的Excel文件。
内容的提问来源于stack exchange,提问作者Dash
相关产品推荐
相关产品推荐

