Java数据导入导出需按场景选IO工具:简单数据用BufferedReader/Writer,Excel用POI或EasyExcel,大文件必须流式处理;CSV中文乱码因未指定UTF-8编码,须用InputStreamReader+FileInputStream;导出千万级数据用SXSSFWorkbook;导入避免OOM需用Stream和批量插入;下载失败多因响应头Content-Type、Content-Disposition配置错误或网关限制。
Java 里做数据导入导出,核心不是堆框架,而是分清场景选对 IO 工具:简单结构化数据用 BufferedReader/BufferedWriter 或 Scanner 就够;Excel 要上 Apache POI;大文件必须流式处理,否则 OutOfMemoryError 几乎必现。
根本原因是没显式指定字符集,JDK 默认用系统编码(Windows 是 GBK),而 CSV 多为 UTF-8。不设编码,FileReader 会直接崩。
FileReader —— 它不支持指定 charset,强制用 InputStreamReader 包裹 FileInputStream
StandardCharsets.UTF_8,哪怕你确认文件是 GBK,也要先统一转成 UTF-8 存储BufferedReader 套一层提升性能,但注意它不解决编码问题,只是加速读取try (BufferedReader reader = new BufferedReader(
new InputStreamReader(
new FileInp
utStream("data.csv"),
StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
// 按逗号分割,注意处理引号包围的字段
String[] fields = line.split(",", -1);
System.out.println(Arrays.toString(fields));
}
}
Apache POI 功能全但 API 繁琐,EasyExcel 是阿里封装的简化层,底层仍用 POI,但屏蔽了样式、单元格对象等细节。
EasyExcel.write() + 实体类注解最省事XSSFWorkbook 或 SXSSFWorkbook
SXSSFWorkbook(流式写入),且要调 setCompressTempFiles(true) 防磁盘爆满关键区别在内存模型:HSSFWorkbook(.xls)全量驻内存,XSSFWorkbook(.xlsx)也驻内存,SXSSFWorkbook 才真正流式 —— 它只保留最近 100 行在内存,其余刷到磁盘临时文件。
不是加 JVM 参数就能解决,本质是设计上不能把整份数据 load 进 List。
Stream 替代 List:JDK8+ 的 Files.lines() 返回惰性流,逐行处理不囤积PreparedStatement.addBatch() + executeBatch(),每 1000 条 flush 一次,别等全读完再提交JsonParser 流式读,POI 用 EventModel(SAX 模式)而非 Workbook
try (Streamlines = Files.lines(Paths.get("huge.csv"), StandardCharsets.UTF_8)) { lines.skip(1) // 跳过 header .map(this::parseLineToEntity) .forEach(this::saveToDatabaseInBatch); // 内部控制 batch size }
后端吐出字节流,前端收不到或提示损坏,90% 出在 HTTP 响应头不对。
Content-Type 必须匹配文件类型:text/csv、application/vnd.openxmlformats-officedocument.spreadsheetml.sheet(xlsx)Content-Disposition 要带 attachment; filename="xxx.xlsx",缺 attachment 会导致浏览器试图渲染而非下载@ResponseBody + ResponseEntity 是最稳组合,别用 String 返回 base64还有个隐形坑:Nginx 或网关默认限制响应体大小,导出 50MB Excel 时若没调 client_max_body_size 或超时配置,请求会在中间被截断。