04-08-03-easyexcel的使用
一.Excel导入导出的应用场景
1.数据导入:减轻录入的工作量
2.数据导出:统计信息归档
3.数据传输:异构系统之间数据传输
二。EasyExcel简介
1.EasyExcel特点
Java领域解析,生成Excel比较有名的框架有Apache poi,jxl等,但他们都存在一个严重的问题就是非常的耗内存,如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或者JVM频繁的full gc.
EasyExcel是阿里巴巴开源的一个excel处理框架,以使用简单,节省内存著称,EasyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。
EasyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)。
(copy的)
后面的读取有点乱不是很清楚,可以看的大佬的 https://www.cnblogs.com/liuyi13535496566/p/12634898.html
2,maven项目创建
easyexcel的pom依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.7</version>
</dependency>
</dependencies>
新建数据 bean stu
@Data @NoArgsConstructor @AllArgsConstructor public class Stu { private Integer id; private String name; private Integer age; private Double weight; private Date birthday; }
新建数据 bean stu2
@Data @NoArgsConstructor @AllArgsConstructor public class Stu2 { @ExcelProperty(value = "编号" ,index = 8 ) //value指定id属性生成的表头名称 , index代表属性写入到excel文档中列的索引 private Integer id; @ExcelProperty(value = "姓名" , index = 7) private String name; @ExcelIgnore //忽略此属性 @ExcelProperty(value = "年龄") //不指定index的从左向右依次插入 private Integer age; @ExcelProperty(value = "体重") @NumberFormat(value = "#.##") //小数点后的一个#代表保留一位 private Double weight; @ExcelProperty(value = "生日") @DateTimeFormat(value = "yyyy年MM月dd日 HH时") //时间日期格式化 private Date birthday; }
新建测试类 测试easyexcel 写数据
//1、将内存中的数据写入到excel文档中 @Test public void testWrite(){ //excel 中存数据的方式和数据库表一致,一行代表一个关系(对象),一列代表一个属性 //完整路径:路径+文件名 //xls是2003版excel格式,最多一次性写入65535行数据+1行表头 //xlsx是2007的格式,写数据行数没有限制 节省磁盘空间 EasyExcel.write("F:/excel/demo05"+ ExcelTypeEnum.XLSX.getValue()) //新建一个名叫demo05 的文件, + 号后面的意思是给这个新建的文件后缀是 xlsx .sheet(0) //数据写入到excel文件的第一个工作簿 .head(Stu2.class) //表头:可以使用excel中的每一行数据对应的类的属性名 // 就是把数据bean里面的实体放在第一行 .doWrite(data());//数据集合:和head中表头的类型一致 。。跟据数据bean的格式把数据写入excel,其中data就是引用下面的数据 } public List<Stu2> data(){ //新建需要写入的数据 在excel中一行就是一个对象,所以是list,List<stu2> 表示按照stu2的格式来 ,方法名叫data List<Stu2> data = new ArrayList<>(); //实例化 for (int i = 0; i <= 65535; i++) { data.add(new Stu2(100000+i , "pipaxing"+i , RandomUtils.nextInt(19,30) , //这里的这个data也是 List<Stu2> data = new ArrayList<>(); 里面的data
RandomUtils.nextDouble(60 , 100), new Date())); } return data;//这里返回的是 List<Stu2> data = new ArrayList<>(); 里面的data
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
测试读取数据
读取需要先新建一个监听器 这个监听器需要继承 AnalysisEventListener
@Data public class StuDataExcelListener extends AnalysisEventListener<StuExcelData> {//泛型:easyexcel读取到一行数据后会自动封装为该类型的对象 List<StuExcelData> data = new ArrayList<>(); int limit = 500; //easyexcel每读取一行数据都会回调一次该方法处理数据 @Override public void invoke(StuExcelData stuExcelData, AnalysisContext analysisContext) { data.add(stuExcelData); //设置阈值,当集合中的数据到达阈值时,批量保存到数据库一次 if(data.size()==500){ System.out.println("开始批量保存数据到数据库...."); data.clear(); } } //excel文档解析完毕后回调一次 @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { //可以将data数据解析批量插入到数据库 System.out.println("excel文档解析完毕..."); //判断如果data中仍有没存到数据库的,最后保存一次 if(data.size()>0){ System.out.println("最后保存数据到数据库....."); data.clear(); } } }
测试。。。。。
@Test public void testRead(){ //1、先为要读取的excel数据创建对应的javabean:StuExcelData //2、easyexcel读取数据时使用回调方式来处理读取的数据:easyexcel负责解析excel文件,每读取一行数据,它会 //调用我们设置给它的监听器对象的回调方法,回调方法中可以处理改行的数据(处理数据的业务) //创建监听器 StuDataExcelListener listener = new StuDataExcelListener(); //3、通过easyexcel加载excel文件并读取数据 EasyExcel.read("F:/excel/demo04"+ExcelTypeEnum.XLSX.getValue()) .sheet(0) .head(StuExcelData.class) .registerReadListener(listener) .doRead(); //4、可以使用listener中解析到的数据 //System.out.println(listener.getData().size()+" , "+ listener.getData().get(0)); }

浙公网安备 33010602011771号