Spring Boot 应用中通过 getResourceAsStream() 读取 Excel 文件时会缓存类路径资源,导致始终返回应用启动时的旧数据;应改用 File 直接读取文件系统中的最新文件,并配合 InputStreamResource 和 HttpHeaders.CONTENT_TYPE 正确响应。
spring boot 应用中通过 `getresourceasstream()` 读取 excel 文件时会缓存类路径资源,导致始终返回应用启动时的旧数据;应改用 `file` 直接读取文件系统中的最新文件,并配合 `inputstreamresource` 和 `httpheaders.content_type` 正确响应。
在 Spring Boot 中,若需动态提供服务器上实时更新的 Excel 文件(如由外部程序定期生成或用户上传),绝不可依赖 Class#getResourceAsStream() —— 因为该方法从 classpath(如 JAR 包、target/classes)加载资源,且 JVM 通常会对资源流进行一次性缓存,重启前无法感知磁盘文件变更。
✅ 正确做法是:使用 java.io.File 指向实际文件系统路径(如 /var/data/sample.xlsx 或 ./sample.xlsx),每次请求时重新打开文件流,确保读取的是磁盘上的最新内容。
以下是优化后的完整实现:
诊断并修复涉及公式、命名范围、Power Query 刷新、数据透视表、VBA/宏保存等问题的 Microsoft Excel XLSX 工作簿
@GetMapping("/download")
public ResponseEntity<Resource> download() throws IOException {
// ✅ 使用 File 而非 getResourceAsStream(),确保每次读取最新文件
File file = new File("sample.xlsx"); // 注意:路径为相对当前工作目录(如 java -jar 启动时的目录)
if (!file.exists() || !file.isFile()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new InputStreamResource(new ByteArrayInputStream(new byte[0])));
}
InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
String contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; // .xlsx
// 若为 .xls,用 "application/vnd.ms-excel"
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getName() + "\"")
.contentType(MediaType.parseMediaType(contentType))
.contentLength(file.length())
.body(resource);
}? 关键注意事项:
- 路径可靠性:new File("sample.xlsx") 的路径是相对于 JVM 启动目录(即 user.dir),建议改用绝对路径(如 "/opt/app/data/sample.xlsx")或通过 @Value("${excel.path:/tmp/sample.xlsx}") 注入配置化路径;
- 权限与存在性检查:务必校验文件是否存在、是否可读,避免 FileNotFoundException;
- 内存友好性:上述代码使用 InputStreamResource 流式传输,不将整个文件加载进内存,适合大文件;
- .xlsx vs .xls:注意 MIME 类型区分——.xlsx 对应 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,.xls 对应 application/vnd.ms-excel;
- 生产环境建议:将 Excel 存放于独立目录(如 uploads/),并配合定时清理或版本号命名,避免并发写入冲突。
通过此方案,每次 HTTP 请求均真实读取磁盘最新文件,彻底解决“返回 Tomcat 启动时旧数据”的问题。

















