EasyCSV:Java读取CSV文件最简单的工具(支持千万级数据CSV文件的读取)
最近有一个项目需要读取客户将自己库里的数据导出到新项目的库里,由于后续还会有新数据接入,于是这个项目暴露出一个文件上传的接口(及用户通过接口上传Excel文件,程序自动读取、加工然后存入新库)。开始的文件为excel,Java读取excel的工具是阿里的EasyExcel,但是用户的数据太多了,导出的excel文件多达1个多G!!!!excel文件有个弊端,最多只能存一百多万条数据,所以用户需要分为多次导出表格,这样很麻烦,于是想到了csv,我目前所知csv的数据量理论上无限大,于是考虑读CSV文件。但是我没有找到一个比较称心的csv读取工具,像EasyExcel那样方便,且可以很容易的读取超大数据表格(重写监听器方式)。于是我就想着自己开发一款csv读取工具类,主要用到了反射、自定义注解、java流等技术。。。。。。。
最近俺比较忙,写的文档比较草率,后续会慢慢补上,欢迎各位大神批评!!!
先上Demo代码,代码下面有详细介绍
package test;
import com.xykj.easycsv.EasyCsv;
import com.xykj.easycsv.entity.Rule;
import java.util.List;
public class TestEasyCsv {
public static String fileName="C:\\Users\\it\\Desktop\\北京周报临时数据\\owid_covid_data_2022-02-28.csv";
/**
* 读取全量数据测试
*/
public static void readAllTest(){
final List<OwidEntity> all = new EasyCsv().readAll(fileName, OwidEntity.class);
System.out.println("======================");
for (OwidEntity owidEntity : all.subList(0, 20)) {
System.out.println(owidEntity);
}
OwidListener owidListener=new OwidListener();
}
/**
* 重写监听器的方式运行
*/
public static void testDoRead(){
new EasyCsv().doRead("C:\\Users\\it\\Documents\\WXWork\\1688857922266493\\Cache\\File\\2022-04\\住院三年.csv"
, PatientInfo.class,new PatientInfoListener());
}
/**
* 测试自定义规则
*/
public static void testRule(){
Rule rule = new Rule("\"", "\"", ",");
final List<Student> students = new EasyCsv(rule).readAll("C:\\Users\\it\\Documents\\WXWork\\1688857922266493\\Cache\\File\\2022-04\\测试.csv"
, Student.class);
System.out.println(students);
}
public static void main(String[] args) {
testDoRead();
}
}
PS:默认支持读取CSV文件为普通的逗号分隔符 例:name,age,sex,adress,如果csv文件特殊的话后面有应对策略。 ]()
一、简单读
1、样例数据
2、样例代码
2.1、创建实体类
@Data //这里的Data是Lombok的注解,或者您也可以自己写一下get、set方法,注意!!!!一定要有set方法。
public class OwidEntity {
/**
这里我只写了部分属性,并没写全
**/
@CsvProperty("iso_code")
String code;
@CsvProperty("continent")
String continent;
@CsvProperty("location")
String location;
@CsvProperty("date")
String date;
@CsvProperty("total_vaccinations")
long totalVaccinations;
@CsvProperty("people_vaccinated")
long peopleVaccinated;
}
2.2、读取文件
String fileName="C:\\Users\\it\\Desktop\\owid_covid_data_2022-02-28.csv";
List<OwidEntity> all = new EasyCsv().readAll(fileName, OwidEntity.class);
是不是非常简单V
二、重写监听器方式的读(当数据量比较大,内存一下存不了的时候用此方法)
在这里我们还用上个文件和OwidEntity实体类。
实例代码:
1.创建实体类 略
2.重写监听器
public class OwidListener implements CsvListener<OwidEntity> {
int i=0;
@Override
public void invoke(OwidEntity data, String sourceColumn) {
i++;
System.out.println("读取第"+i+"条数据:"+data);
}
@Override
public void invokeHead(Map<String, Integer> titleIndexMap, String sourceColumn) {
System.out.println(titleIndexMap);
}
@Override
public void onError(Exception e,String sourceColumn) {
}
@Override
public void readOver() {
System.out.println("所有数据读取完毕");
}
}
3.读取数据
new EasyCsv().doRead(fileName, OwidEntity.class,new OwidListener ());//这里我只演示了一下基本的使用方法,请您根据您的需要重写监听器即可,我试过一个700万数据的csv文件,完全没问题。
比如您的表格有七百万数据,您可以让他去批量插入数据库,您可以像这样重写监听器,额这个代码不全对,我相信您能看出来,我只是表达一些这个意思嘿嘿。
public class HospitalIliListener extends CsvListener<HospitalIliExcel> {
List<HospitalIli> dataList=new ArrayList<>();
public HospitalIliListener(HospitalIliDao hospitalIliDao) {
this.hospitalIliDao = hospitalIliDao;
}
private HospitalIliDao hospitalIliDao;
@Override
public void invoke(HospitalIliExcel data, AnalysisContext context) {
if (dataList.size()==10000){
hospitalIliDao.insert(dataList);
dataList.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
hospitalIliDao.insert(dataList);
dataList.clear();
}
}
特殊格式的CSV文件
有些时候csv文件并不是那么规范(我们默认读取的为纯逗号分割例如:name,age,sex这种格式的),我们需要给EasyCsv对象传入一个Rule对象,具体使用如下:
样例数据:
Rule rule = new Rule("\"", "\"", ",");//1、创建rule对象 三个参数一次为为1、单元格前置符,2、单元格后置符,3、单元格分割符
//把rule传给EasyCsv对象,然后读,,,,,,,,,,,监听器模式下同理
final List<Student> students = new EasyCsv(rule).readAll("C:\\Users\\it\\Documents\\WXWork\\1688857922266493\\Cache\\File\\2022-04\\测试.csv"
, Student.class);
System.out.println(students);