Java使用XSSFWorkbook生成的.xlsx文件打开显示只读如何解决?
问题根因
- 代码未显式关闭
FileOutputStream资源,文件写入完成后流句柄仍被JVM持有,操作系统会将文件标记为占用状态,打开时默认设为只读 tempFile.setWritable(true)调用时机错误,在流未释放时修改文件权限,会被仍在运行的IO操作覆盖- Windows系统会默认对来自临时目录、非信任位置的Office文件启用「受保护的视图」,表现为只读状态,和代码逻辑无关
修复方案
建议使用try-with-resources语法自动管理IO资源,无需手动关闭,避免资源泄漏,修复后代码如下:
try { File tempFile = new File(validateFileUrl); // 写入操作前先设置文件可写权限 tempFile.setWritable(true, false); XSSFWorkbook workbook = null; XSSFSheet sheet = null; if(!rowList.isEmpty()) { workbook = new XSSFWorkbook(); sheet = workbook.createSheet(); int rownum=0; for(String rowStr : rowList) { XSSFRow row = sheet.createRow(rownum++); String[] cellArr = rowStr.split(","); int cellCount=0; for(String cellStr : cellArr) { XSSFCell crrCell = row.createCell(cellCount++); crrCell.setCellValue(cellStr); } } // try-with-resources自动处理流关闭 try(FileOutputStream fos = new FileOutputStream(tempFile)) { workbook.write(fos); fos.flush(); } finally { workbook.close(); } } } catch(Exception e) { e.printStackTrace(); }
额外排查方案
- 生成文件后如果还是只读,右键点击文件选择「属性」,查看底部是否有「解除锁定」的勾选选项,勾选后确认即可正常编辑,这是Windows对非本地来源文件的默认安全防护
- 不要将文件导出到系统盘根目录、Program Files、系统临时目录这类需要特殊权限的路径,选择普通用户目录下的文件夹存储
- Linux/macOS环境下如果
setWritable不生效,可手动执行chmod 644 <文件路径>修改文件权限,共享挂载目录下Java的文件权限API不生效是已知兼容问题
内容的提问来源于stack exchange,提问作者Kavi Chinna
相关产品推荐
相关产品推荐

