🎉🎉《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.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 recordString[] 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<User> setColumMapping() {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 {(column = "id", required = true)private Long id ;(column = "emp_name", required = true)private String name ;(column = "sfz", required = true)private String idNo ;(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文件。
public 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>() {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 时代!
高级开发!基于Spring Boot自定义注解@Interceptor动态注册拦截器,非常强大
高级开发!Controller接口参数与响应结果四种记录方式,第四种对性能无任何影响
高级开发!弃用@ControllerAdvice,这种异常处理方式性能更佳
学会这3招Spring AOP切面技巧,代码解耦效率直接翻倍
生产环境修改Spring Boot配置文件不重启也能实时生效
Jackson在Spring Boot高级应用技巧【Long精度丢失, @JsonValue, 数据脱敏】


