使用opencsv实现Csv与Java对象转换(CSV)

OpenCSV 是一个用于 Java 的流行的库,用于读取和写入 CSV(逗号分隔值)文件。CSV 文件是一种常见的结构化数据存储和交换格式。OpenCSV 提供了一种简单和方便的方式来在 Java 应用程序中处理 CSV 文件。
以下是 OpenCSV 的一些关键特点和用法示例:
1、读取 CSV 文件:
2、写入 CSV 文件:
3、自定义 CSV 解析和写入:

OpenCSV 允许您自定义 CSV 解析和写入的各个方面,例如指定分隔符(默认是逗号)、处理引号等。

4、使用注解处理 CSV:

OpenCSV 支持使用注解将 Java 对象映射到 CSV 记录。可以使用注解来定义如何将字段映射到 CSV 列。

 @CsvBindByName通过列名来绑定字段。你可以使用 column 属性指定 CSV 文件中的列名,OpenCSV 将根据列名将数据映射到相应的字段。   

@CsvBindByName(column = "Name")
private String name;

 @CsvBindByPosition:通过列的位置(索引)来绑定字段。你可以使用 position 属性指定 CSV 文件中的列索引,OpenCSV 将根据索引将数据映射到相应的字段。

@CsvBindByPosition(position = 0)
private int id;

 @CsvBindByType:用于指定字段的数据类型。你可以使用 type 属性指定数据类型,OpenCSV 将尝试将 CSV 数据转换为指定的数据类型。

@CsvBindByType(type = BigDecimal.class)
private BigDecimal price;

 @CsvDate:用于处理日期字段。你可以使用 value 属性指定日期的格式,OpenCSV 将尝试将 CSV 数据解析为指定格式的日期。

@CsvDate("yyyy-MM-dd")
private Date birthDate;

 @CsvCustomBindByName:自定义绑定器。你可以使用 converter 属性指定一个自定义的绑定器类,该类负责将 CSV 数据转换为字段的值。

@CsvCustomBindByName(column = "Price", converter = CustomPriceConverter.class)
private BigDecimal price;

5、错误处理:

OpenCSV 提供了处理 CSV 解析和写入过程中错误的机制,例如处理格式不正确的 CSV 记录。

6、处理文件头:

可以通过单独读取文件头并使用文件头来映射数据到 Java 对象,轻松处理带有标题的 CSV 文件。

7、CSV Bean 映射:

OpenCSV 允许将 CSV 记录直接映射到 Java Bean,使用注解来定义映射关系,这样可以轻松处理结构化数据。

8、将 CSV 转换为 SQL:

OpenCSV 还可以用于读取 CSV 数据并将其插入到 SQL 数据库中。

 

Csv与Java对象转换示例如下:

1、引入相关依赖

1 <dependency>
2     <groupId>com.opencsv</groupId>
3     <artifactId>opencsv</artifactId>
4     <version>5.7.1</version>
5 </dependency>

2、创建实体类

 1 @Data
 2 public class User {
 3 
 4     @CsvBindByName(column = "name")
 5     @CsvBindByPosition(position = 0)
 6     private String name;
 7 
 8     @CsvBindByName(column = "age")
 9     @CsvBindByPosition(position = 1)
10     private Integer age;
11 
12     @CsvBindByName(column = "sex")
13     @CsvBindByPosition(position = 2)
14     private String sex;
15 }

 3、创建Csv工具类

 1 public class CsvUtils {
 2 
 3     /**
 4      * csv文件导入并转为java对象
 5      * @param fileName
 6      * @param clazz
 7      * @return
 8      * @param <T>
 9      */
10     public static <T> List<T> readCSVFile(String fileName, Class<T> clazz){
11         try {
12             FileReader reader = new FileReader(fileName);
13             CSVReader csvReader  = new CSVReader(reader);
14 
15             HeaderColumnNameMappingStrategy<T> strategy = new HeaderColumnNameMappingStrategy<>();
16             strategy.setType(clazz);
17 
18             CsvToBean<T> csvToBean = new CsvToBeanBuilder<T>(csvReader)
19                     .withType(clazz)
20                     //将第一行视为标题行
21                     .withMappingStrategy(strategy)
22                     .build();
23 
24             return csvToBean.parse();
25 
26         } catch (FileNotFoundException e) {
27             throw new RuntimeException(e);
28         }
29     }
30 
31     /**
32      * 将java对象转为csv文件导出
33      * @param fileName
34      * @param list
35      * @return
36      * @param <T>
37      */
38     public static <T> void writeCSVFile(String fileName, List<T> list) {
39 
40         try {
41             FileWriter writer = new FileWriter(fileName);
42 
43             StatefulBeanToCsv<T> beanToCsv = new StatefulBeanToCsvBuilder<T>(writer)
44                     .withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
45                     // 启用标题行
46                     .withOrderedResults(true)
47                     .build();
48 
49             // 添加标题行(将 Person 对象的字段名作为标题)
50             writer.write("Name, Age, Sex\n");
51 
52             beanToCsv.write(list);
53             writer.close();
54 
55         } catch (FileNotFoundException e) {
56             throw new RuntimeException(e);
57         } catch (CsvRequiredFieldEmptyException e) {
58             throw new RuntimeException(e);
59         } catch (CsvDataTypeMismatchException e) {
60             throw new RuntimeException(e);
61         } catch (IOException e) {
62             throw new RuntimeException(e);
63         }
64     }
65 }

这里对CSVReader 、CsvToBean、StatefulBeanToCsv等进行详细分析

3.1、CSVReader 

CSVReader 是 OpenCSV 库的核心类之一,用于读取 CSV 文件的内容并将其转换为 Java 对象或数据结构。它支持多种配置选项,可以适应不同的 CSV 文件格式和数据类型。

常用方法:

  ▪ readNext():读取 CSV 文件的下一行数据,并将其返回为一个字符串数组。如果已经达到文件末尾,则返回 null。

  ▪ readAll():一次性读取整个 CSV 文件的所有行数据,并将其返回为一个 List,其中每个元素是一个字符串数组,表示一行数据。

  ▪ skip():跳过指定数量的行。可以用于跳过 CSV 文件的标题行或不需要处理的行。

  ▪ close():关闭 CSVReader,释放资源。在使用完 CSVReader 后,应该调用该方法以关闭文件流。

  ▪ getLinesRead():获取已经读取的行数。可以用于跟踪读取进度。

  ▪ setSkipEmptyRows():设置是否跳过空行。默认情况下,CSVReader 不会跳过空行,但你可以使用这个方法来配置它。

  ▪ setSafetySwitch():设置安全开关。当启用安全开关时,CSVReader 会检查文件是否以预期的行数结尾。如果不是,将抛出异常。

 

3.2、CsvToBean

CsvToBean 类是 OpenCSV 库的一部分,用于将 CSV 数据解析为 Java 对象或数据结构。它支持多种配置选项,以适应不同的 CSV 文件格式和数据类型。通常,CsvToBean 被用于将 CSV 行映射到 Java Bean 类,使得 CSV 数据可以更方便地在 Java 应用程序中处理。

常用方法:

  • parse():解析 CSV 数据并将其映射到 Java 对象。该方法返回一个包含 Java 对象的 List。

  • parse() 重载方法:除了简单的 parse() 方法,CsvToBean 还提供了一些重载方法,用于更精细地控制解析过程。这些方法接受一个 CSVReader 对象作为参数,允许你指定要解析的 CSV 数据源。

 

  ▪ withMappingStrategy():设置 CsvToBean 使用的映射策略,用于定义 CSV 行到 Java 对象的映射规则。通常,你需要创建一个自定义的映射策略类,并将其传递给 withMappingStrategy() 方法。

  ▪ withType():指定要映射到的目标 Java 类型。通常,你需要提供目标 Java Bean 类的类对象。

  ▪ withSeparator():设置 CSV 文件中的分隔符。默认情况下,分隔符是逗号,但你可以使用该方法来指定其他分隔符。

  ▪ withQuoteChar():设置用于引用包含特殊字符的字段的字符。默认情况下,引用字符是双引号,但你可以使用该方法来指定其他引用字符。

  ▪ withThrowExceptions():设置是否在解析过程中抛出异常。默认情况下,异常被抑制,但你可以使用该方法来启用异常。

  ▪ withOrderedResults():指定解析结果是否按照 CSV 文件中的顺序排序。默认情况下,结果是无序的,但你可以使用该方法来启用排序。

  ▪ withFilter():设置一个自定义的过滤器,用于过滤解析的数据行。

 

3.3、StatefulBeanToCsv

StatefulBeanToCsv 类是 OpenCSV 库的一部分,用于将 Java 对象或数据结构写入 CSV 文件。它支持多种配置选项,以适应不同的 CSV 文件格式和数据类型。通常,StatefulBeanToCsv 被用于将 Java 对象的列表写入 CSV 文件,或者将 Java Bean 对象的属性写入 CSV 行中。

常用方法:

  ▪ write():将 Java 对象的列表写入 CSV 文件。这个方法接受一个包含 Java 对象的列表作为参数,将它们写入 CSV 文件。

  ▪ write() 重载方法:除了简单的 write() 方法,StatefulBeanToCsv 还提供了一些重载方法,用于更精细地控制写入过程。这些方法允许你指定要写入的 Java 对象列表、字段选择策略等。

       其余方法与CsvToBean类相似

 

3.4、常用的 MappingStrategy 实现(即映射策略)

  ▪ ColumnPositionMappingStrategy<T>:这是 OpenCSV 默认的映射策略。它将 CSV 文件的列按照它们在文件中的位置与 Java Bean 的属性逐一对应。例如,CSV 文件的第一列数据将映射到 Java Bean 的第一个属性,第二列数据映射到 Java Bean 的第二个属性,依此类推。

  ▪ HeaderColumnNameMappingStrategy<T>:这个策略适用于包含列名称的 CSV 文件。它将 CSV 文件的列名称与 Java Bean 的属性名称逐一对应

  ▪ CustomMappingStrategy<T>:如果你需要更灵活的映射策略,可以实现自定义的 MappingStrategy。你可以在自定义策略中定义如何将 CSV 数据映射到 Java Bean,以满足特定的需求。

 

4、了解了这么多知识,下面让我们在测试类进行测试吧!

4.1、将Java对象转换为csv文件

 1 @Test
 2 void ToCsv(){
 3 
 4     User user1 = new User();
 5     user1.setName("Tom");
 6     user1.setAge(22);
 7     user1.setSex("男");
 8 
 9     User user2 = new User();
10     user2.setName("John");
11     user2.setAge(21);
12     user2.setSex("女");
13 
14     List<User> users = new ArrayList<>();
15     users.add(user1);
16     users.add(user2);
17 
18     //PATH = "C:\\Users\\16056\\Desktop\\test.csv"
19     CsvUtils.writeCSVFile(PATH, users);
20     System.out.println("执行完成");
21 
22 }

测试结果:

 4.2、将csv文件转换为Java对象

1 @Test
2 void toObject()  {
3 
4     //PATH = "C:\\Users\\16056\\Desktop\\test.csv"
5     List<User> users = CsvUtils.readCSVFile(PATH, User.class);
6     for (User user : users){
7         System.out.println(user);
8     }
9 }

测试结果:

 



posted @ 2023-09-18 11:03  xiaogh  阅读(4357)  评论(0)    收藏  举报