1. 概述
这篇教程我们来聊聊 如何使用 Java 写入 CSV 文件。CSV(Comma-Separated Values,逗号分隔值)是一种常见的用于系统间批量数据传输的格式。
我们将使用 java.io
包中的类来实现写入功能。
✅ 我们会重点讨论 特殊字符的处理,并确保生成的 CSV 文件能在 Microsoft Excel 和 Google Sheets 中正常打开。
在 Java 原生方式演示完之后,我们还会 简单介绍几个常用的第三方 CSV 处理库。
2. 使用 PrintWriter 写入 CSV
我们选用 PrintWriter
来完成写入任务。如果你对 java.io
包操作文件还不太熟悉,可以先看看我们之前写的 Java 文件写入指南。
2.1. 写入 CSV 数据
首先,我们写一个方法,将字符串数组格式化为一行 CSV 数据:
public String convertToCSV(String[] data) {
return Stream.of(data)
.map(this::escapeSpecialCharacters)
.collect(Collectors.joining(","));
}
接着,我们准备一些测试数据:
List<String[]> dataLines = new ArrayList<>();
dataLines.add(new String[]
{ "John", "Doe", "38", "Comment Data\nAnother line of comment data" });
dataLines.add(new String[]
{ "Jane", "Doe, Jr.", "19", "She said \"I'm being quoted\"" });
然后,使用 convertToCSV
方法将每一行数据转换,并写入文件:
public void givenDataArray_whenConvertToCSV_thenOutputCreated() throws IOException {
File csvOutputFile = new File(CSV_FILE_NAME);
try (PrintWriter pw = new PrintWriter(csvOutputFile)) {
dataLines.stream()
.map(this::convertToCSV)
.forEach(pw::println);
}
assertTrue(csvOutputFile.exists());
}
2.2. 特殊字符处理 ⚠️
CSV 文件中,逗号、双引号、换行符 是最容易出问题的字符。我们无法保证输入数据的“干净”,所以必须手动处理。
处理规则如下:
- 包含逗号、引号或换行符的字段,需要用 双引号包裹
- 字段中的 双引号要用两个双引号转义
- 换行符我们统一替换成空格(你也可以根据需求换成
\r\n
)
来看我们的 escapeSpecialCharacters
方法实现:
public String escapeSpecialCharacters(String data) {
if (data == null) {
throw new IllegalArgumentException("Input data cannot be null");
}
String escapedData = data.replaceAll("\\R", " ");
if (escapedData.contains(",") || escapedData.contains("\"") || escapedData.contains("'")) {
escapedData = escapedData.replace("\"", "\"\"");
escapedData = "\"" + escapedData + "\"";
}
return escapedData;
}
⚠️ 注意:不同场景下对特殊字符的处理规则可能略有不同,建议根据实际业务调整。
3. 第三方库推荐 ✅
虽然我们可以用原生 Java 实现 CSV 写入,但在处理复杂场景时,还是推荐使用成熟的第三方库,它们通常内置了各种边界情况的处理逻辑。
下面是一些常用的库:
- Apache Commons CSV:Apache 出品,稳定可靠
- Open CSV:社区活跃,功能丰富
- Flatpack:轻量级开源库
- CSVeed:注解驱动,适合 POJO 映射
- FastCSV:高性能,适合大数据量处理
4. 总结
这篇文章我们使用 Java 原生的 PrintWriter
实现了 CSV 文件的写入,并处理了常见的特殊字符问题。
虽然原生方式足够应付简单场景,但如果项目中频繁操作 CSV,还是建议引入成熟的第三方库,避免重复造轮子,也能减少踩坑概率。