EasyExcel的基本使用方法

  在Java语言领域,说到Excel处理工具,大家首先想到的可能是阿帕奇的poi,poi在处理数据量不大的excel文件上确实非常强大,但是随着后来excel从03(一个excel文件中最多有65536行,256列)版升级到07 版(一个excel文件最多1048576行,16384列),poi在处理大数据量的excel时显得力不从心,03版的excel  poi可以应对,但是对于行数几乎增加了15倍,列数增加了接近50倍的07版excel,poi很快达到了瓶颈,这是因为poi在处理excel时会将数据全部导入内存再进行数据的加工处理,当数据量过大内存很容易OOM。但是即便如此,poi在处理excel方面还是无人能及,后来在Alibaba的改造和包装下,EsayExcel应运而生,它首先解决的就是poi的OOM问题,为了解决这个问题,easyExcel对数据载入内存的处理思想相比于poi发生了改变,poi的思路是空间换时间(减少载入内存次数从而节约时间),而easyExcel的思路是时间换空间(运用sax模式一行一行解析,并将一行的解析结果以观察者的模式通知处理),这样就很好的解决了OOM问题,EasyExcel还有很多优点,比如容易上手,相比poi来说easyExcel对里面许多方法进行了封装,运用起来更加快捷方便。

  说excel最重要的操作一定属上传和下载了,上传是什么呢?下载又是什么呢?这些名词我们听的很多,但是可能并没有真正理解,用通俗一点的说法来说就是——上传指的是将Excel中的数据读取到数据库表中并存储起来,下载指的是将数据库中的数据导出到Excel文件中,当然,数据仓库不一定是数据库,还可以是其它,像redis这种也是可以的。这样我们就知道数据从哪里出发,终点在哪里了,是不是没有刚才那么迷茫了呢。接下来就上菜吧,菜名就是easyExcel,语言使用java语言,编译器是IDEA 2019。

 

1.通过easyExcel读取xlsx文件中的信息

有如下excel待读取:

9f4802fd206082c4e17e12d17b25bed0.png  

编码大体分为两步,第一步创建文件的属性PoJo类DemoData(还有book类):

package com.zzb.business.card.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.zzb.business.edison.excel.metadata.BaseRowModel;
import lombok.Data;
@Data
public class DemoData {
@ExcelProperty("编号")
private int no;
@ExcelProperty("朝代")
private String dynasty;
@ExcelProperty("开朝人")
private String king;
}

第二步创建第一步创建的pojo类的listener(还有book对应的listener):

 

package com.zzb.business.card.excel; 
import com.alibaba.excel.context.AnalysisContext;
 import com.alibaba.excel.event.AnalysisEventListener; 
import com.alibaba.fastjson.JSON;import java.util.ArrayList; 
import java.util.List;public class DemoDataListener extends AnalysisEventListener<DemoData> {   
 List<DemoData> list = new ArrayList<DemoData>();  
  /**   
  * 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来    
 */  
  public DemoDataListener() {}  
 /**   
 * 这个每一条数据解析都会来调用   
  * 
  * @param data    
 * @param context    
*/   
@Override  
  public void invoke(DemoData data, AnalysisContext context) {        
System.out.println( JSON.toJSONString(data));
list.add(data); }
/** * 所有数据解析完成了 都会来调用 * * @param context */ @Override public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println(JSON.toJSONString(list)); } }

这样,大体代码就已经写好了,接下来test

@Test
 public void readExcelShouldSuccess(){    
String fileName="src/main/resources/templates/dynasty.xlsx";    
EasyExcel.read(fileName, DemoData.class,new DemoDataListener()).sheet("朝代表").doRead(); EasyExcel.read(fileName, Book.class,new BookDataListener()).sheet("书籍信息").doRead(); } }

如果多个sheet的结构是一样的,那么可以用doReadAll()方法读取多个sheet:

EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).doReadAll();  

 文件内容存储在list中,输出如下:

a7ba26a6c43cecb2db48cefe39433684.png  

2.通过esayExcel将数据简单写入同一个Excel中(class类型不变)

此处的数据使用List来模拟:

//以list模拟数据库中导出的数据,因为list是excel操作时的桥梁
  List<Book> sheetOne=new ArrayList<>();   
Book book1=new Book();   
 book1.setNo(1);  
  book1.setAuthor("老舍");  
  book1.setBookName("三味书屋"); 
Book book2=new Book();
 book2.setNo(2);
 book2.setBookName("钢铁是怎样炼成的");
 book2.setAuthor("奥斯特洛夫斯基");
 sheetOne.add(book1); 
sheetOne.add(book2);
View Code

接下来写入一个sheet数据,这种写法只能写入一个sheet中的数据,如果再在同一个文件中写入其它sheet,前边的所有sheet都会被覆盖,只保留最后一个sheet的数据

EasyExcel.write(fileName,Book.class).sheet(1,"书籍列表").doWrite(sheetOne);

结果如下:

1803862c772e99af5ccac3dc60fe3479.png  

3.easyExcel写入多个sheet到同一个文件(sheet类型变动)

@Test  
public void writeComflixbelExcelShouldSuccess(){  
//以list模拟数据库中导出的数据,因为list是excel操作时的桥梁  
 List<Book> books=new ArrayList<>();  
 List<DemoData> dynastys=new ArrayList<>();      
Book book1=new Book();  book1.setNo(1);      
book1.setAuthor("老舍");     
book1.setBookName("三味书屋");  
Book book2=new Book();     
book2.setNo(2);     
book2.setBookName("钢铁是怎样炼成的");     
book2.setAuthor("奥斯特洛夫斯基");       
 books.add(book1);      
books.add(book2);     
DemoData dynasty=new DemoData();     
dynasty.setNo(1);      
dynasty.setDynasty("宋朝");     
dynasty.setKing("赵匡胤");     
dynastys.add(dynasty);      
String fileName="src/main/resources/templates/book.xlsx";       
ExcelWriter excelWriter=null; 
excelWriter = EasyExcel.write(fileName).build();
//写入多格式sheet只需要指定文件名,不用指定class类型
 for (int i = 0; i < 5; i++) {         
 if((i&1)==0){               
// 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样。这里注意DemoData.class 可以每次都变,我这里为了方便 所以用的同一个class 实际上可以一直变          
 WriteSheet writeSheet = EasyExcel.writerSheet(i, "朝代" + i).head(DemoData.class).build();              
// 分页去数据库查询数据 这里可以去数据库查询每一页的数据                
excelWriter.write(dynastys, writeSheet);
}else{ WriteSheet writeSheet = EasyExcel.writerSheet(i, "书籍" + i).head(Book.class).build(); // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
excelWriter.write(books, writeSheet);
} } excelWriter.finish(); }

结果如下:

39be2796d19ecb8656493341e8704570.png  
e7a00724933f1886919b234ebc34e0f3.png  

 

posted @ 2020-08-04 10:15  HexThinking  阅读(7827)  评论(0编辑  收藏  举报