大数跨境
0
0

OpenCSV太炸裂了,一行代码搞定 CSV 读写

OpenCSV太炸裂了,一行代码搞定 CSV 读写 Spring全家桶实战案例
2025-04-20
0
导读:OpenCSV太炸裂了,一行代码搞定 CSV 读写
Spring Boot 3实战案例锦集PDF电子书已更新至100篇!

🎉🎉《Spring Boot实战案例合集》目前已更新117个案例,我们将持续不断的更新。文末有电子书目录。

💪💪永久更新承诺

我们郑重承诺,所有订阅合集的粉丝都将享受永久免费的后续更新服务

💌💌如何获取
订阅我们的合集点我订阅,并通过私信联系我们,我们将第一时间将电子书发送给您。

→ 现在就订阅合集

环境:SpringBoot3.4.2



1. 简介

CSV 代表 "逗号分隔值"(comma-separated values)。CSV 文件大多用于创建数据文件,以便导出或导入数据。Java 语言并未提供任何原生支持来有效处理 CSV 文件。如果不使用第三方库,我们最终可能不得不自己编写一个 CSV 解析器。通常,重新发明轮子(即重复造轮子)并无优势,因此建议使用这类第三方工具来解析 CSV 文件。

OpenCsv 是一个易于使用的 CSV(逗号分隔)解析库,可用于在 Java 中读取 CSV 文件或将数据写入 CSV 文件。它的开发源于当时所有的 CSV 解析器都不具备商业友好的许可证。目前,该库支持的最低 Java 版本是 Java 8。

OpenCsv核心类

CSVParser:一个非常简单的 CSV 解析器。它仅实现了将单行拆分为字段的功能。

CSVReader:读取 CSV 文件时,大部分时间都会使用这个类。这个类提供了许多有用的构造函数,以便使用不同的选项和能力构建 CSVReader。例如,你可以指定不同的分隔符字符(默认是逗号)、不同的引用字符(默认是双引号),甚至可以指定解析应开始的初始行号。

CSVWriter:与 CSVReader 一样,CSVWriter 也具有高度可定制性。在写 CSV 文件时,可以使用自定义分隔符、自定义引用字符或自定义行终止符。

CsvToBean:当你想要从 CSV 文件内容中填充 Java Bean 时,将使用此类。

BeanToCsv:将java bean对象到处到CSV文件。

ColumnPositionMappingStrategy:如果你计划使用 CsvToBean(或 BeanToCsv)来导入 CSV 数据,将使用此类将 CSV 字段映射到 Java Bean 字段。

接下来,我们将以案例的方式介绍上面核心类。

2. 实战案例

2.1 逐行读取CSV文件

我们将通过上面介绍的 CSVReader 类来读取 CSV 文件。

  • 通过 CSVParserBuilder 来指定任何自定义分隔符字符

  • 通过 CSVReaderBuilder 来指定要跳过的行数。这在 CSV 文件首行包含标题而我们不想读取标题时非常有用

     

public class ParserCSVReaderTest {  public static void main(String[] args) throws Exception {    File file = new File("D:\\pack\\data.csv") ;    // 构建解析器    CSVParser csvParser = new CSVParserBuilder()        .withSeparator(',')        .withIgnoreQuotations(true)        .build();    // CSV读取器    CSVReader csvReader = new CSVReaderBuilder(new FileReader(file))        .withSkipLines(1)        .withCSVParser(csvParser)        .build();    String[] nextLine;    while ((nextLine = csvReader.readNext()) != null) {      if (nextLine != null) {        System.out.println(Arrays.toString(nextLine)) ;      }    }  }}

运行结果

2.2 一次性读取全部CSV

上述示例是逐行读取 CSV 文件。该案例我们一次性读取完整的 CSV 文件,然后根据需要迭代数据,如下示例:

public class ParseFullCSVTest {  public static void main(String[] args) throws Exception {    File file = new File("D:\\pack\\data.csv") ;    CSVReader reader = new CSVReader(new FileReader(file));    // 读取全部内容    List<String[]> allRows = reader.readAll();    for (String[] row : allRows) {      System.out.println(Arrays.toString(row));    }  }}

2.3 写CSV文件

写入 CSV 文件与读取 CSV 文件一样简单。使用适当的配置选项创建一个 CSVWriter 实例,然后开始将数据写入 CSV 文件。

public class WritingCSVFileTest {  public static void main(String[] args) throws Exception {    File file = new File("d:\\pack\\data.csv");    CSVWriter writer = new CSVWriter(new FileWriter(file)) ;    String[] record = "21,Pack,35,男,1988-01-01,新疆乌鲁木齐".split(",") ;    writer.writeNext(record, false) ;    writer.close() ;  }}

运行结果

2.4 追加内容到CSV文件

上面2.3示例会创建一个新的 CSV 文件,并从开头(即第 0 行)开始写入数据。但在很多情况下,我们希望将数据追加到现有的 CSV 文件中,而不是写入一个新文件。我们可以通过将追加模式作为第二个参数传递给 FileWriter 实例来实现这一功能。

public class WritingCSVFileAppendTest {  public static void main(String[] args) throws Exception {    File file = new File("d:\\pack\\data.csv");    // FileWriter构造函数第二个参数设置为true,追加内容    CSVWriter writer = new CSVWriter(new FileWriter(file, true));    // Create record    String[] record = new String[] { "22""Spring全家桶实战案例源码""33""女""1989-01-01""台湾省" };    writer.writeNext(record, false);    writer.close();  }}

运行结果

2.5 CSV转Java对象

实体对象定义如下:

public class User {  private Long id ;  private String name ;  private Integer age ;  private String sex ;  private String birthday ;  private String address ;  // getters, setters, constructors}

使用CsvToBean对象进行转换

public class CSVToUserTest {  public static void main(String[] args) throws Exception {    File file = new File("d:\\pack\\data.csv");    CSVReader csvReader = new CSVReader(new FileReader(file));    CsvToBean<User> csv = new CsvToBean<>();    csv.setCsvReader(csvReader);    csv.setMappingStrategy(setColumMapping());    List<User> list = csv.parse();    list.forEach(System.err::println) ;  }  private static ColumnPositionMappingStrategy<UsersetColumMapping() {    ColumnPositionMappingStrategy<User> strategy = new ColumnPositionMappingStrategy<>();    strategy.setType(User.class);    String[] columns = new String[]{"id""name""age""sex""birthday""address"} ;     strategy.setColumnMapping(columns);    return strategy;  }}

运行结果

2.6 基于注解字段映射

CSV 文件应为文件中的所有字段设置表头名称,这些名称可以带来极大的便利。通过用对应表头的名称对 bean 字段进行注解(该表头的数据应写入该字段),opencsv 可以为你完成所有匹配和复制工作。

定义实体对象

public class Employee {  @CsvBindByName(column = "id"required = true)  private Long id ;  @CsvBindByName(column = "emp_name"required = true)  private String name ;  @CsvBindByName(column = "sfz"required = true)  private String idNo ;  @CsvBindByName(column = "addr"required = false)  private String address ;  // getters, setters, constructors}

读取CSV文件

public class AnnotationMappingFieldTest {  public static void main(String[] args) throws Exception {    File file = new File("d:\\pack\\employee.csv");    List<Employee> employees = new CsvToBeanBuilder<Employee>(new FileReader(file))        .withType(Employee.class)        .build()        .parse() ;    System.err.println(employees) ;  }}

输出结果

[  Employee [id=21, name=Pack, idNo=320311198512124567, address=新疆乌鲁木齐],   Employee [id=22, name=Spring全家桶实战案例源码, idNo=110105199003072345, address=台湾省]]

2.7 通过SQL导出CSV

我们将通过JDBC的ResultSet直接写数据到CSV文件。

@Servicepublic class UserService {  private final JdbcClient jdbcClient ;  public UserService(JdbcClient jdbcClient) {    this.jdbcClient = jdbcClient;  }  public void exportCsv() {    File file = new File("d:\\pack\\user.csv");    this.jdbcClient.sql("select * from x_user").query(new RowMapper<Object>() {      @Override      public Object mapRow(ResultSet rs, int rowNum) throws SQLException {        try(CSVWriter writer = new CSVWriter(new FileWriter(file))) {          writer.writeAll(rs, true) ;        } catch(Exception e) {          e.printStackTrace();         }        return null;      }    }).list() ;  }}

运行结果

当然你也可以查询出List数据后再写入到CSV文件。


以上是本篇文章的全部内容,如对你有帮助帮忙点赞+转发+收藏

推荐文章

@HttpExchange 强势登场,彻底终结 Feign 时代!

惊呆了!Controller接口返回值支持17种逆天类型

高级开发!基于Spring Boot自定义注解@Interceptor动态注册拦截器,非常强大

高级开发!Controller接口参数与响应结果四种记录方式,第四种对性能无任何影响

高级开发!弃用@ControllerAdvice,这种异常处理方式性能更佳

王炸!Spring AI+MCP 三步实现智能体开发

太强了!Spring AI调用本地函数,实时获取最新数据

学会这3招Spring AOP切面技巧,代码解耦效率直接翻倍

生产环境修改Spring Boot配置文件不重启也能实时生效

这6个Spring高级开发技巧掌握了吗?

Jackson在Spring Boot高级应用技巧【Long精度丢失, @JsonValue, 数据脱敏】

【声明】内容源于网络
0
0
Spring全家桶实战案例
Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
内容 832
粉丝 0
Spring全家桶实战案例 Java全栈开发,前端Vue2/3全家桶;Spring, SpringBoot 2/3, Spring Cloud各种实战案例及源码解读
总阅读285
粉丝0
内容832