摘自:https://www.cnblogs.com/54chensongxia/p/11990312.html

easyExcel简介#

Java领域解析、生成Excel比较有名的框架有Apache poi、jxl等。但他们都存在一个严重的问题就是非常的耗内存。如果你的系统并发量不大的话可能还行,但是一旦并发上来后一定会OOM或者JVM频繁的full gc。

easyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称

64M内存1分钟内读取75M(46W行25列)的Excel(当然还有急速模式能更快,但是内存占用会在100M多一点)

easyExcel能大大减少占用内存的主要原因是在解析Excel时没有将文件数据一次性全部加载到内存中,而是从磁盘上一行行读取数据,逐个解析。

下图是easyExcel和POI在解析Excel时的对比图。

easyExcel采用一行一行的解析模式,并将一行的解析结果以观察者的模式通知处理(AnalysisEventListener)。

上面简要介绍了easyExcel的特点和原理,关于easyExcel的其他问题可以先参考下这个文章。下面就通过代码来介绍下怎么使用easyExcel。

快速使用指南#

文件上传读取Excel#

下面通过一个读取用户信息的列子来展示下怎么使用easyExcel。

step1:创建用户信息类

Copy
@Data
public class UserInfo extends BaseRowModel { @ExcelProperty(index = 0)
private String name; @ExcelProperty(index = 1)
private int age; @ExcelProperty(index = 2)
private String address; }

step2:创建AnalysisEventListener子类

Copy
/**
* 每解析一行会回调invoke()方法。
* 整个excel解析结束会执行doAfterAllAnalysed()方法
*/ //有个很重要的点 不能被spring管理,要每次读取excel都要new。
//这边就会有一个问题:如果UserInfoDataListener中需要用到Spring中的主键怎么办?
public class UserInfoDataListener extends AnalysisEventListener<UserInfo> { Logger logger = LoggerFactory.getLogger(UserInfoDataListener.class); //每次读取100条数据就进行保存操作
private static final int BATCH_COUNT = 100;
//由于每次读都是新new UserInfoDataListener的,所以这个list不会存在线程安全问题
List<UserInfo> list = new ArrayList<>(); //这个组件是Spring中的组件,这边推荐两种方法注入这个组件
//第一种就是提供一个UserInfoDataListener的构造方法,这个方法提供一个参数是UserInfoDataListener类型
//另外一种方法就是将 UserInfoDataListener 这个类定义成 UserService 实现类的内部类(推荐这种方式)
//private UserService userService; @Override
public void invoke(UserInfo data, AnalysisContext analysisContext) {
logger.info("解析到一条数据:{}", JSON.toJSONString(data));
list.add(data);
if (list.size() >= BATCH_COUNT) {
saveData();
// 存储完成清理 list
list.clear();
}
} @Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
// 这里也要保存数据,确保最后遗留的数据也存储到数据库
saveData();
logger.info("所有数据解析完成!");
} private void saveData() {
logger.info("{}条数据,开始存储数据库!", list.size());
//保存数据
//userService.save(list);
logger.info("存储数据库成功!");
} }

step3: 读取excel

Copy

public class EasyExcelDemo { public static void main(String[] args) throws Exception {
InputStream fis = new FileInputStream("D:\\UserInfo.xlsx"); AnalysisEventListener listener = new UserInfoDataListener(); ExcelReader excelReader = EasyExcel.read(fis, UserInfo.class, listener).build();
ReadSheet readSheet = EasyExcel.readSheet(0).build();
ReadSheet readSheet2 = EasyExcel.readSheet(1).build();
excelReader.read(readSheet);
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
excelReader.finish();
} }

只需要上面3步就能进行Excel的读取了。

文件下载Excel#

Copy

public class ExcelUtil { public static OutputStream getOutputStream(String fileName, HttpServletResponse response)
throws Exception{
try{
fileName = URLEncoder.encode(fileName,"utf-8");
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
//此处指定了文件类型为xls,如果是xlsx的,请自行替换修改
response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xls");
response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "no-store");
response.addHeader("Cache-Control", "max-age=0");
return response.getOutputStream();
} catch (IOException e){
throw new Exception("导出文件失败!");
}
} public static void writeExcel(HttpServletResponse response, List<? extends BaseRowModel> list, String fileName,
String sheetName, Class clazz) throws Exception {
ExcelWriter writer = new ExcelWriter(getOutputStream(fileName, response), ExcelTypeEnum.XLS);
Sheet sheet = new Sheet(1, 0, clazz);
sheet.setSheetName(sheetName);
writer.write(list, sheet);
writer.finish();
} }

在Controller中我们只要像下面这种方式调用就行了。

Copy

@RequestMapping(value = "/file/testExcelDownload")
public void testExcelDownload(HttpServletRequest request,HttpServletResponse response){
//以下信息从数据库中查出
List<ExcelInfo> excelInfos = new ArrayList<>();
ExcelInfo info1 = new ExcelInfo();
ExcelInfo info2 = new ExcelInfo();
excelInfos.add(info1);
excelInfos.add(info2);
info1.setIssuerName("name1");
info1.setRiskLevel("level1");
info2.setIssuerName("name1");
info2.setRiskLevel("level1");
try {
String fileName = "excelInfo";
String sheetName = "sheet1";
ExcelUtil.writeExcel(response, excelInfos, fileName, sheetName, ExcelInfo.class);
} catch(Exception e){
log.error("模板下载失败",e);
} }

在导出Excel的部分,easyExcel还提供了自定义样式,插入表格,插入图片等其他功能,还有一个比较有意思的功能就是Excel模板填充的功能。详细的功能信息参考官方文档

作者:写代码的木公

出处:https://www.cnblogs.com/54chensongxia/p/11990312.html

版权:本站使用「CC BY 4.0」创作共享协议,转载请在文章明显位置注明作者及出处。

 
分类: 软件工具
标签: easyExcel
 

easyExcel简介#的更多相关文章

  1. 【软件工具】easyExcel简明使用指南

    easyExcel简介 Java领域解析.生成Excel比较有名的框架有Apache poi.jxl等.但他们都存在一个严重的问题就是非常的耗内存.如果你的系统并发量不发的话可能还行,但是一旦并发上来 ...

  2. 一行代码完成 Java的 Excel 读写--easyexcel

    最近我在 Github 上查找一个可以快速开发 excel 导入导出工具,偶然发现由阿里开发 easyexcel 开源项目,尝试使用后感觉这款工具挺不错的,下面分享一下我的 easyexcel 案例使 ...

  3. POI和EasyExcel的使用

    1.POI使用 1.1 什么是POI POI简介(Apache POI),Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office ...

  4. 海量数据Excel报表利器——EasyExcel(开场篇)

    EasyExcel 简介篇 互联网的精髓就是共享,可以共享技术.共享经验.共享情感.共享快乐~ 很多年前就有这个想法了,从事IT行业时间也不短了,应该把自己工作和业余所学习的东西记录并分享出来,和有缘 ...

  5. 阿里 EasyExcel 7 行代码优雅地实现 Excel 文件生成&下载功能

    欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 资深架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...

  6. Excel解析工具easyexcel全面探索

    1. Excel解析工具easyexcel全面探索 1.1. 简介 之前我们想到Excel解析一般是使用POI,但POI存在一个严重的问题,就是非常消耗内存.所以阿里人员对它进行了重写从而诞生了eas ...

  7. EasyExcel引入

    好久没更了,都在有道云上面记录,没时间搬过来. easyexcel是最近项目做优化涉及的一个改善点吧. 简介 导出是后台管理系统的常用功能,当数据量特别大的时候会内存溢出和卡顿页面,曾经自己封装过一个 ...

  8. 阿里出品Excel工具EasyExcel使用小结

    前提 笔者做小数据和零号提数工具人已经有一段时间,服务的对象是运营和商务的大佬,一般要求导出的数据是Excel文件,考虑到初创团队机器资源十分有限的前提下,选用了阿里出品的Excel工具EasyExc ...

  9. SpringBoot基于EasyExcel解析Excel实现文件导出导入、读取写入

    1. 简介   Java解析.生成Excel比较有名的框架有Apache poi.jxl.但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题 ...

随机推荐

  1. 谈谈对Spring IOC的理解(转发)

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  2. ssh下known_hosts的作用

    原文地址:http://blog.csdn.net/yasaken/article/details/7348441 在平时工作中,有时候需要SSH登陆到别的Linux主机上去,但有时候SSH登陆会被禁 ...

  3. [转载]IMDB文件格式

    [转载]IMDB文件格式 来源:LMDB的全称是Lightning Memory-Mapped Database,闪电般的内存映射数据库.它文件结构简单,一个文件夹,里面一个数据文件,一个锁文件.数据 ...

  4. [转载]java中import作用详解

    [转载]java中import作用详解 来源: https://blog.csdn.net/qq_25665807/article/details/74747868 这篇博客讲的真的很清楚,这个作者很 ...

  5. C#/.net中出现 "GDI+中发生一般性错误"解决方案

    有时我们在读取本地图片,调用 Image.Save() 方法,将其另保存为其他格式时,经常会碰到一个错误:“GDI+中发生一般性错误”:一般出现这种错误有 3 种可能: 1.保存路径不存在或者错误: ...

  6. 记一次线上dubbo服务超时和线程池满问题排查

    线上某dubbo服务A调用dubbo服务B的接口X方法,调用端A日志中出现了很多超时的情况,提供端B该接口X超时时间设置为60s: 查看提供端B的日志,报了很多线程池满的异常: Caused by: ...

  7. rabbitmq 使用PhpAmqpLib

    rabbitmq类 rabbitmq.php <?php require_once __DIR__ . '/vendor/autoload.php'; use PhpAmqpLib\Connec ...

  8. 在php中连接数据库 pdo

    在php中连接数据库 pdo //数据库信息 $mysql_conf = array( 'host' => '127.0.0.1', 'db' => 'meteorolog_foreign ...

  9. OpenCV视觉处理核心课程

    OpenCV视觉处理核心课程 观看链接:https://www.bilibili.com/video/av29500928?from=search&seid=47008639320014639 ...

  10. Vmvare 虚拟机固定IP

    首先我们打开虚拟机的虚拟网络编辑器,打开vmvare菜单栏的编辑,选择虚拟网络编辑器.   在打开的网络虚拟器中,会看到相关信息,虚拟机网络类型采用的NAT模式,子网地址是192.168.89.0,虚 ...