Java 文件上传与 Excel 数据导入导出

管理后台常见的文件功能包括图片上传、表格导入和数据导出。实现时要同时考虑接口格式、文件大小、内容校验、存储位置和失败反馈,不能只把文件接收后写到磁盘。

1. Multipart 上传

浏览器通常以 multipart/form-data 提交文件。Spring MVC 可用 MultipartFile 接收文件,并从 getInputStream() 读取内容或把文件转存到安全位置。上传前检查请求大小、文件名长度和业务允许的类型;客户端提供的扩展名和 Content-Type 都不能单独作为真实文件类型的证明。

1
2
3
4
5
6
7
8
@PostMapping("/files")
public UploadResult upload(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
throw new IllegalArgumentException("请选择文件");
}
// 校验大小和允许的内容类型,再交给受控存储服务
return storageService.store(file);
}

实际项目还应设置 Spring 与反向代理的请求大小限制,避免大文件占满内存或磁盘。

2. 文件名和存储位置

不要直接把用户提交的原始文件名拼成服务器路径,避免路径穿越和同名覆盖。可生成随机对象键,把原始文件名作为经过清理的展示元数据保存。上传目录不应能执行脚本;图片等内容如需公开访问,也应通过受控域名和访问策略提供。

本地磁盘适合开发或单机环境;多实例部署时,本地文件不一定能被其他实例读取。对象存储更适合共享访问,但要保护访问密钥、控制 Bucket 权限,并使用短时签名链接或后端鉴权。

3. Excel 导入

导入流程可以分成:接收文件、解析表头、逐行校验、汇总错误、确认导入和写入数据库。不要遇到第一行错误就只抛出一个不清楚的异常;可以返回行号、字段名和问题描述。

大量数据应限制行数和单元格长度,避免超大文件导致内存耗尽。使用 Apache POI 时,按文件规模选择合适的读取方式,并关闭工作簿和输入流。导入操作需要考虑事务范围、重复数据和部分失败策略。

4. Excel 导出

导出前明确列名、日期格式、数字精度、数据权限和最大记录数。大表导出应使用流式方式或异步生成,避免一次性把全部行装入内存。导出的数据要按用户权限过滤,不要因为“后台接口”就默认可以导出全库信息。

如果数据会被用户再以 CSV/Excel 打开,需考虑以 =, +, -, @ 开头的文本被表格软件解释为公式的风险,并按具体格式采取安全处理。

5. 常见失败处理

  • 文件为空、过大、格式不支持时返回明确错误。
  • 数据库写入失败时清理已上传但未引用的文件,或安排定期清理孤儿对象。
  • 对象存储上传成功但数据库记录失败时,设计补偿或重试。
  • 日志记录请求 ID 和对象键,不记录文件内容、令牌或敏感字段。

6. 小结

文件功能是一条跨越 HTTP、应用、数据库和文件存储的链路。上传、导入、导出都要有明确的大小限制、内容校验、权限控制和失败清理策略。