使用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 }
测试结果: