百万数据Excel导出功能如何实现?( 二 )


需要在maven的pom.xml文件中引入easyexcel的jar包:
 
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.0.2</version></dependency>

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
 
之后,使用起来非常方便 。
读excel数据非常方便:
 
@Testpublic void simpleRead() {String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
 
写excel数据也非常方便:
 
@Testpublic void simpleWrite() {String fileName = TestFileUtil.getPath() + "write" + System.currentTimeMillis() + ".xlsx";// 这里 需要指定写用哪个class去读,然后写到第一个sheet,名字为模板 然后文件流会自动关闭// 如果这里想使用03 则 传入excelType参数即可EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
 
easyexcel能大大减少占用内存的主要原因是:在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析 。
3、分页查询百万级别的数据,从数据库一次性查询出来,是一件非常耗时的工作 。
即使我们可以从数据库中一次性查询出所有数据,没出现连接超时问题,这么多的数据全部加载到应用服务的内存中,也有可能会导致应用服务出现OOM问题 。
因此,我们从数据库中查询数据时,有必要使用分页查询 。比如:每页5000条记录,分为200页查询 。
 
public Page<User> searchUser(SearchModel searchModel) {List<User> userList = userMApper.searchUser(searchModel);Page<User> pageResponse = Page.create(userList, searchModel);pageResponse.setTotal(userMapper.searchUserCount(searchModel));return pageResponse;}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
 
每页大小pageSize?和页码pageNo,是SearchModel类中的成员变量,在创建searchModel对象时,可以设置设置这两个参数 。
然后在MyBatis?的sql文件中,通过limit语句实现分页功能:
 
limit #{pageStart}, #{pageSize}
  • 1.
 
其中的pagetStart参数,是通过pageNo和pageSize动态计算出来的,比如:
 
【百万数据Excel导出功能如何实现?】pageStart = (pageNo - 1) * pageSize;
  • 1.
 
4、多个sheet我们知道,excel对一个sheet存放的最大数据量,是有做限制的,一个sheet最多可以保存1048576行数据 。否则在保存数据时会直接报错:
 
invalid row number (1048576) outside allowable range (0..1048575)
  • 1.
 
如果你想导出一百万以上的数据,excel的一个sheet肯定是存放不下的 。
百万数据Excel导出功能如何实现?

文章插图
因此我们需要把数据保存到多个sheet中 。
百万数据Excel导出功能如何实现?

文章插图
5、计算limit的起始位置我之前说过,我们一般是通过limit语句来实现分页查询功能的:
 
limit #{pageStart}, #{pageSize}
  • 1.
 
其中的pagetStart参数,是通过pageNo和pageSize动态计算出来的,比如:
 
pageStart = (pageNo - 1) * pageSize;
  • 1.
 
如果只有一个sheet可以这么玩,但如果有多个sheet就会有问题 。因此,我们需要重新计算limit的起始位置 。
例如: