Hutool 的CsvUtil是一个简单易用的 CSV 文件读写工具类,基于 RFC 4180 标准实现。
一、添加依赖
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.26</version> </dependency>二、读取 CSV
1. 从文件读取
// 方式1:获取 CsvReader 对象 CsvReader reader = CsvUtil.getReader(); // 读取所有行 List<CsvRow> rows = reader.read(FileUtil.file("test.csv")); // 方式2:直接读取为 List List<CsvRow> rows = CsvUtil.getReader().read(FileUtil.file("test.csv")); // 遍历每一行 for (CsvRow row : rows) { // 通过索引获取值 String name = row.get(0); String age = row.get(1); }2. 带表头读取
CsvReader reader = CsvUtil.getReader(); // 从第二行开始读取(第一行为表头) List<CsvRow> rows = reader.read(FileUtil.file("test.csv"), 1); // 获取表头 CsvRow header = rows.get(0);3. 读取为 Map
CsvReader reader = CsvUtil.getReader(); // 第一行为 key,后续行转为 Map List<Map<String, String>> mapList = reader.readMapList(FileUtil.file("test.csv"));4. 流式读取(大文件)
CsvReader reader = CsvUtil.getReader(); reader.read(FileUtil.file("large.csv"), new CsvReadHandler() { @Override public void handle(int rowIndex, List<String> row) { // 逐行处理 System.out.println(rowIndex + ": " + row); } });三、写入 CSV
1. 基础写入
// 获取 CsvWriter(默认覆盖写入) CsvWriter writer = CsvUtil.getWriter("result.csv", CharsetUtil.CHARSET_UTF_8); // 写入单行(按列顺序) writer.write( new String[]{"张三", "25", "北京"}, new String[]{"李四", "30", "上海"} ); // 写入集合 List<List<String>> rows = new ArrayList<>(); rows.add(Arrays.asList("王五", "28", "广州")); writer.write(rows); writer.close();2. 追加写入
// 第二个参数 true 表示追加模式 CsvWriter writer = CsvUtil.getWriter("result.csv", CharsetUtil.CHARSET_UTF_8, true); writer.writeLine("赵六", "35", "深圳"); writer.close();3. 写入带表头
CsvWriter writer = CsvUtil.getWriter("result.csv"); // 先写表头 writer.writeLine("姓名", "年龄", "城市"); // 写数据 writer.writeLine("张三", "25", "北京"); writer.writeLine("李四", "30", "上海"); writer.close();4. 写入 Bean 集合(需配合其他工具)
// 使用 CsvData 构造 List<CsvRow> rows = new ArrayList<>(); rows.add(CsvRow.of("name", "age", "city")); rows.add(CsvRow.of("张三", "25", "北京")); CsvData data = new CsvData(rows); CsvUtil.getWriter("bean.csv").write(data);四、配置选项
CsvReader 配置
CsvReadConfig config = CsvReadConfig.defaultConfig(); // 设置是否首行是表头 config.setContainsHeader(true); // 设置字段分隔符(默认逗号) config.setFieldSeparator(','); // 设置文本限定符(默认双引号) config.setTextDelimiter('"'); // 跳过空行 config.setSkipEmptyRows(true); // 忽略表头大小写 config.setHeaderAlias(new HashMap<>()); CsvReader reader = CsvUtil.getReader(config);CsvWriter 配置
CsvWriteConfig config = CsvWriteConfig.defaultConfig(); // 设置字段分隔符 config.setFieldSeparator(','); // 设置是否总是使用文本限定符 config.setAlwaysDelimitText(false); // 设置换行符 config.setLineDelimiter(LineDelimiterUtil.CRLF); CsvWriter writer = CsvUtil.getWriter("config.csv", CharsetUtil.CHARSET_UTF_8, false, config);五、完整示例
示例1:读取并处理 CSV
public class CsvReadExample { public static void main(String[] args) { // 读取 CSV List<CsvRow> rows = CsvUtil.getReader().read(FileUtil.file("users.csv")); for (int i = 0; i < rows.size(); i++) { CsvRow row = rows.get(i); System.out.printf("第%d行: 姓名=%s, 年龄=%s, 邮箱=%s%n", i + 1, row.get(0), row.get(1), row.get(2)); } } }示例2:生成 CSV 报表
public class CsvWriteExample { public static void main(String[] args) { CsvWriter writer = CsvUtil.getWriter("report.csv", CharsetUtil.CHARSET_GBK); // 写入表头 writer.writeLine("序号", "姓名", "成绩"); // 写入数据 for (int i = 1; i <= 10; i++) { writer.writeLine(String.valueOf(i), "学生" + i, String.valueOf(60 + i * 3)); } writer.close(); System.out.println("CSV 文件生成成功!"); } }示例3:处理特殊字符(逗号、引号、换行)
// 包含特殊字符的值会自动被引号包裹 writer.writeLine("张三", "25", "北京,朝阳区"); // 自动处理逗号 writer.writeLine("李四", "30", "他\"说\"你好"); // 自动处理引号 writer.writeLine("王五", "28", "第一行\n第二行"); // 自动处理换行六、注意事项
编码问题:中文建议使用 UTF-8 或 GBK 编码
大文件处理:大文件应使用流式读取,避免内存溢出
自动关闭:
CsvWriter实现了Closeable,使用后记得关闭特殊字符:包含逗号、引号、换行的字段会自动处理
空行处理:默认会跳过空行,可通过配置修改
七、与其他工具对比
| 特性 | Hutool CsvUtil | OpenCSV | Apache Commons CSV |
|---|---|---|---|
| 易用性 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ |
| 功能完整性 | ⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ |
| 依赖大小 | 小(整合) | 小 | 中 |
| 中文社区 | 好 | 一般 | 一般 |
对于日常简单的 CSV 操作,Hutool 的CsvUtil完全够用且更加简洁。