三. Csv的操作使用
与上一章节的 Excel 操作例子相同
提取了一个工具类,用于获取数据
public class DataUtil { /** * 获取用户的数据 * @date 2021/11/8 13:51 * @author zk_yjl * @param name * @return java.util.List<top.yueshushu.learn.pojo.User> */ public static List<User> createDataList(String name) { List<User> result=new ArrayList<>(); for(int i=1;i<=10;i++){ User user=new User(); user.setId(i); user.setName(name+"_"+i); user.setSex(i%2==0?"女":"男"); user.setAge(20+i); user.setDescription("我是第"+i+"个,我的名字是:"+user.getName()); result.add(user); } return result; } }
不要忘记在 pom.xml 中添加依赖
<!--添加hutool-all, 处理csv文件解析--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.10</version> </dependency>
三.一 Csv写入文件
放置在 WriteTest 测试类里面
三.一.一 writeBeans 方式写入数据
/** * 简单的 csv文件写入 * @date 2021/11/8 13:51 * @author zk_yjl * @param * @return void */ @Test public void simpleWriteTest() throws Exception{ //1. 大批量的业务处理,最后获取组装相应的数据信息。 List<User> userList= DataUtil.createDataList("两个蝴蝶飞"); //2. 存储的文件地址 String filePath="D:\\csv\\simple.csv"; //获取 CsvWriter CsvWriter csvWriter = CsvUtil.getWriter(filePath, Charset.forName("UTF-8")); // 写入注释 csvWriter.writeComment("一个简单的csv文件"); //写入新的一行 csvWriter.writeLine(); //写入内容 csvWriter.writeBeans(userList); //关闭内容 csvWriter.close(); log.info("写入文件成功"); }
运行后,查看数据
标题行 是对应的 bean的属性值.
三.一.二 注解在实体上,自定义标题头输出
可以在实体类上,通过 @Alias 注解来自定义标题头
@Data public class User { @Alias("编号") private Integer id; @Alias("姓名") private String name; // @Alias("性别") private String sex; // @Alias("年龄") private Integer age; @Alias("描述信息") private String description; }
进行测试
/** * 写入标题头文件 * @date 2021/11/8 14:06 * @author zk_yjl * @param * @return void */ @Test public void headerTest() throws Exception{ //1. 大批量的业务处理,最后获取组装相应的数据信息。 List<User> userList= DataUtil.createDataList("两个蝴蝶飞"); //2. 存储的文件路径 String filePath="D:\\csv\\header.csv"; //3. 获取CsvWriter CsvWriter csvWriter = CsvUtil.getWriter(filePath, Charset.forName("UTF-8")); //4. 写入注入 csvWriter.writeComment("带着自定义标题头的文件"); //写入内容 csvWriter.writeBeans(userList); //关闭 csvWriter.close(); log.info(">>写入标题头文件成功"); }
编号,姓名,描述信息, 通过 @Alias 注解 进行了自定义标题.
一般开发中,导出 .csv 文件,都是采用 导出 Java Bean 的方式.
复杂的,就需要通过 CsvData 实体进行构建了.
三.一.三 CsvData 构造实现导出数据
/** * 写入CsvData数据 * @date 2021/11/8 14:06 * @author zk_yjl * @param * @return void */ @Test public void csvDataTest() throws Exception{ //1. 大批量的业务处理,最后获取组装相应的数据信息。 List<User> userList= DataUtil.createDataList("两个蝴蝶飞"); //2. 存储的文件路径 String filePath="D:\\csv\\data.csv"; //3. 获取CsvWriter CsvWriter csvWriter = CsvUtil.getWriter(filePath, Charset.forName("UTF-8")); //4. 写入注入 csvWriter.writeComment("写入CsvData文件"); //写入标题头 List<String> header=Arrays.asList("编号","姓名","性别","年龄","描述"); List<CsvRow> csvRowList=new ArrayList<>(); int i=0; //写入行 for(User user:userList){ //构建 headerMap Map<String, Integer> headerMap=new HashMap<>(); headerMap.put("编号",0); headerMap.put("姓名",1); headerMap.put("性别",2); headerMap.put("年龄",3); headerMap.put("描述",4); //放置该行的值 List<String> fieldList=new ArrayList<>(); fieldList.add(user.getId()+""); fieldList.add(user.getName()+""); fieldList.add(user.getSex()+""); fieldList.add(user.getAge()+""); fieldList.add(user.getDescription()+""); //构建 CsvRow 对象 CsvRow csvRow=new CsvRow(i,headerMap,fieldList); csvRowList.add(csvRow); i++; } CsvData csvData=new CsvData(header,csvRowList); csvWriter.write(csvData); //关闭 csvWriter.close(); log.info(">>写入CsvData 文件成功"); }
运行程序
三.二 Csv读取文件
放置在 ReadTest 测试类里面,读取的文件用刚才生成的那些文件.
三.二.一 简单读取数据
/** * 简单文件的读取 * @date 2021/11/8 14:15 * @author zk_yjl * @param * @return void */ @Test public void simpleTest(){ //1. 读取的文件路径 String filePath="D:\\csv\\simple.csv"; //构建 CsvReader 对象 CsvReader csvReader = CsvUtil.getReader(); //进行读取 CsvData csvData = csvReader.read(new File(filePath), Charset.forName("UTF-8")); //进行处理 //获取相应的内容 int rowCount = csvData.getRowCount(); log.info(">>>读取了{}行",rowCount); //获取行数据 List<CsvRow> rows = csvData.getRows(); for(CsvRow csvRow:rows){ //打印出该行的内容信息 List<String> rawList = csvRow.getRawList(); log.info(">>获取内容信息:"+rawList); } }
读取了 11行, 将 id,name,sex 这些应该是标题行的信息,变成了正常的内容形式.
可以通过 CsvReadConfig 进行相关的配置.
三.二.二 CsvReadConfig 读取配置简单使用
/** * 读取信息,读取成 CsvData 形式. * @date 2021/11/8 14:39 * @author zk_yjl * @param * @return void */ @Test public void config1Test(){ //1. 读取的文件路径 String filePath="D:\\csv\\simple.csv"; //2. 进行配置 CsvReadConfig csvReadConfig=new CsvReadConfig(); csvReadConfig.setSkipEmptyRows(true); //包括标题行 csvReadConfig.setContainsHeader(true); //进行了读取,设置 //构建 CsvReader 对象 CsvReader csvReader = CsvUtil.getReader(csvReadConfig); //进行读取 CsvData csvData = csvReader.read(new File(filePath), Charset.forName("UTF-8")); //进行处理 List<String> header = csvData.getHeader(); log.info(">>>读取的文件标题头为:"+header.toString()); //获取相应的内容 int rowCount = csvData.getRowCount(); log.info(">>>读取了{}行",rowCount); //获取行数据 List<CsvRow> rows = csvData.getRows(); for(CsvRow csvRow:rows){ List<String> rawList = csvRow.getRawList(); log.info(">>获取内容信息:"+rawList); } }
读取时,会默认把一行变成标题头,
剩余的是内容, 读取是正常的.
三.二.三 CsvReadConfig 读取配置较复杂使用
可以进行动态的配置,从哪一行开始读取,读取到第几行.
/** * 配置读取的信息 * @date 2021/11/8 14:39 * @author zk_yjl * @param * @return void */ @Test public void config2Test(){ //1. 读取的文件路径 String filePath="D:\\csv\\simple.csv"; //2. 进行配置 CsvReadConfig csvReadConfig=new CsvReadConfig(); csvReadConfig.setSkipEmptyRows(true); csvReadConfig.setContainsHeader(true); //设置最开始读取的行号, 注意,这一行,会被当成标题行的. csvReadConfig.setBeginLineNo(0); //读取的行号 csvReadConfig.setEndLineNo(6); //进行了读取,设置 //构建 CsvReader 对象 CsvReader csvReader = CsvUtil.getReader(csvReadConfig); //进行读取 CsvData csvData = csvReader.read(new File(filePath), Charset.forName("UTF-8")); //进行处理 List<String> header = csvData.getHeader(); log.info(">>>读取的文件标题头为:"+header.toString()); //获取相应的内容 int rowCount = csvData.getRowCount(); log.info(">>>读取了{}行",rowCount); //获取行数据 List<CsvRow> rows = csvData.getRows(); for(CsvRow csvRow:rows){ /* List<String> rawList = csvRow.getRawList(); log.info(">>获取内容信息:"+rawList);*/ log.info(">>>>"); Map<String, String> fieldMap = csvRow.getFieldMap(); for(Map.Entry<String,String> fieldEntry:fieldMap.entrySet()){ log.info(">>>>>>>>:"+fieldEntry.getKey()+":"+fieldEntry.getValue()); } } }
如果修改
csvReadConfig.setBeginLineNo(4); // 由0 变成4
再次运行
三.二.四 读取数据,封装成 Java Bean
/** * 读取信息,放置到bean 里面 * @date 2021/11/8 14:39 * @author zk_yjl * @param * @return void */ @Test public void headerTest() throws Exception{ //1. 读取的文件路径 String filePath="D:\\csv\\header.csv"; //进行了读取,设置 //2. 进行配置 CsvReadConfig csvReadConfig=new CsvReadConfig(); csvReadConfig.setSkipEmptyRows(true); csvReadConfig.setContainsHeader(true); //构建 CsvReader 对象 CsvReader csvReader = CsvUtil.getReader(csvReadConfig); //直接读取,封装成 Bean List<User> userList = csvReader.read(new FileReader(new File(filePath)), User.class); for(User user:userList){ log.info(">>"+user); } }
可以在 实体类上 通过 @Alias 注解 将文件中的标题与类中的属性进行关联起来.
这就是一些关于 Csv的基本操作.