一、EasyExcel简介

​     Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。easyexcel重写了poi对07版Excel的解析,能够原本一个3M的excel用POI sax依然需要100M左右内存降低到几M,并且再大的excel不会出现内存溢出,03版依赖POI的sax模式。在上层做了模型转换的封装,让使用者更加简单方便

二、使用方法

1.引入依赖

<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.8</version>
</dependency>

2.读取excel

(1)默认方式读取

通过EasyExcel.read()方式进行,参数依次为文件路径、要读取成指定文件的类、读取文件类的监听器,sheet中默认读取第一个sheet,也可以自己制定,读取文件时从第二行开始,可以按批次读取,也可以自定义读取

@Test
public void easyExcelRead(){String path = "D:\\city_district.xlsx";EasyExcel.read(path, TeleCity.class, new TeleCityListener(teleCityService)).sheet("city市区表").doRead();
}

监听器TeleCityListener,这里是继承了AnalysisEventListener,需要指定读取的类,因为没有被spring管理,所以这里需要new TeleCityListener(teleCityService),传入的teleCityService需要注入,方式来创建实例,通过构造器方式传入注入的dao或者service来赋值,调用相应的方法,插入数据库,也可以使用默认构造器,不会对数据库进行操作

@Slf4j
public class TeleCityListener extends AnalysisEventListener<TeleCity> {/*** 假设这个是一个DAO,当然有业务逻辑这个也可以是一个service。当然如果不用存储这个对象没用。*/private TeleCityService teleCityService;/*** 如果使用了spring,请使用这个构造方法。每次创建Listener的时候需要把spring管理的类传进来** @param teleCityService*/public TeleCityListener(TeleCityService teleCityService) {this.teleCityService = teleCityService;}public TeleCityListener(){}/*** 每隔100条存储数据库,实际使用中可以3000条,然后清理list ,方便内存回收*/private static final int BATCH_COUNT = 100;List<TeleCity> list = new ArrayList<TeleCity>();/*** 这个每一条数据解析都会来调用** @param teleCity*            one row value. Is is same as {@link AnalysisContext#readRowHolder()}* @param analysisContext*/@Overridepublic void invoke(TeleCity teleCity, AnalysisContext analysisContext) {log.info("解析到一条数据:{}", JSON.toJSONString(teleCity));list.add(teleCity);// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOMif (list.size() >= BATCH_COUNT) {saveData();// 存储完成清理 listlist.clear();}}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {}/*** 加上存储数据库*/private void saveData() {log.info("{}条数据,开始存储数据库!", list.size());teleCityService.insertTeleCityList(list);log.info("存储数据库成功!");}
}

(2)使用自定义的通用监听器读取文件

通过泛型和继承AnalysisEventListener来自定义通用的一个读取监听器,只读取数据,读到的数据全都封装在list里面,通过getList()即可得到返回的数据,想要处理哪种格式就传入相应的类即可

@Slf4j
public class GeneralListener<T> extends AnalysisEventListener<T> {private List<T> list= Lists.newArrayList();@Overridepublic void invoke(T data, AnalysisContext context) {Assert.notNull(data,"导入数据不能为null");log.info("start read list of data :{}",JSON.toJSONString(data));list.add(data);}@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {log.info("read data complete!");}public List<T> getList() {return list;}
}

创建一个实例,读取完毕后,调用getlist()方法

@Test
public void generalExcelRead(){String path = "D:\\city_district.xlsx";//建立一个通用读取监听器,读取数据到这个里面,通过getList方式获取读取的数据GeneralListener<TeleCity> teleListener=new GeneralListener<>();//EasyExcel进行读取try{EasyExcel.read(path,TeleCity.class,teleListener).sheet("city市区表").doRead();}catch (Exception e){log.error("读取数据失败!",e);}log.info("读取到的数据大小为:{}", JSON.toJSONString(teleListener.getList().size()));//进行数据库插入操作teleCityService.insertTeleCityList(teleListener.getList());
}

3.导出文件为Excel

使用EasyExcel.write()即可,里面参数为文件路径,要转出的文件内容,和sheet名称以及要导出的数据

@Test
public void generateExcelWrite(){List<TeleCity> list=teleCityService.getList();List<TeleCityExcelDTO> exportList=JSON.parseArray(JSON.toJSONString(list),TeleCityExcelDTO.class);log.info("开始写入数据!");String path = "D:\\demo.xlsx";try {EasyExcel.write(path, TeleCityExcelDTO.class).sheet("模板").doWrite(exportList);}catch (Exception e){log.error("写入数据失败!",e);}log.error("写入数据成功!大小为{}", JSON.toJSONString(list.size()));
}

定义导出的数据文件格式:通过注释来指定哪些列不需要导出,导出列位置和名称以及相应的高度、宽度等

@Data
public class TeleCityExcelDTO implements Serializable {/*** 忽略不读取和写入*/@ExcelIgnoreprivate static final long serialVersionUID = 8372588291576645501L;/*** 强制读取第三个 这里不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配*/@ExcelProperty(index = 0,value = "id")@ColumnWidth(10)private Long id;@ExcelProperty(index = 1,value = "城市名称")@ColumnWidth(20)private String cityName;@ExcelProperty(index = 2,value = "组织编码")@ColumnWidth(20)private String orgCode;@ExcelProperty(index = 3,value = "物流编码")@ColumnWidth(20)private String logisticCode;@ExcelProperty(index = 4,value = "省份Id")@ColumnWidth(10)private Long provinceId;@ExcelProperty(index = 5,value = "创建时间")@ColumnWidth(20)private String createTime;@ExcelProperty(index = 6,value = "更新时间")@ColumnWidth(20)private String updateTime;
}

4.Download下载文件

类似于上面导出文件,需要自定义导出文件内容格式。实际是将导出的文件写入response中,需要指定编码格式和输出流格式等。这里特别注意是需要使用Get方式请求的,将下载的数据在当前界面作为附件方式下载,不会打开新的界面

 @GetMapping("/test17")public void testExportExcel(HttpServletResponse response) {//导出数据List<TeleCity> list = teleCityService.getList();List<TeleCityExcelDTO> exportList = JSON.parseArray(JSON.toJSONString(list), TeleCityExcelDTO.class);// 设置为导出件格式为excelresponse.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");String filePrefix="测试文件";try {// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系String fileName = URLEncoder.encode(filePrefix, "UTF-8").replaceAll("\\+", "%20");//Content-disposition 的 attachment参数将文件作为附件下载response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");EasyExcel.write(response.getOutputStream(), TeleCityExcelDTO.class).sheet("模板").doWrite(exportList);} catch (Exception e) {log.error("下载文件失败!", e);throw new BizException(ResponseCode.EXPORT_FILE_FAILURE);}log.info("下载数据大小为:{}", exportList.size());}

5.Upload上传文件

类似于前面的读取excel文件,这里是通过前端选取文件,读入到输入流里面,然后通过监听器读取指定格式。注意接收文件的类型为:MultipartFile

@RequestMapping("/test18")
public Response testUpLoadExcel(MultipartFile file){log.info("文件名称:{}",file.getName());//构建上传文件的数据格式GeneralListener<TeleCityExcelDTO> generalListener=new GeneralListener<>();try {EasyExcel.read(file.getInputStream(), TeleCityExcelDTO.class, generalListener).sheet().doRead();} catch (IOException e) {log.error("上传文件失败!", e);throw new BizException(ResponseCode.UP_LOAD_FILE_FAILURE);}return new Response("0","读取数据成功!",generalListener.getList().size());
}

前端样式,注意读取文件的类型为:multipart/form-data,前端

<form action="/test/test18", method="post", enctype="multipart/form-data"><input type="file" name="file"/><input type="submit">
</form>

EasyExcel实现文件读取、导出、上传、下载操作相关推荐

  1. 如何在Webstorm/Phpstorm中设置连接FTP,并快速进行文件比较,上传下载,同步等操作...

    Phpstorm除了能直接打开localhost文件之外,还可以连接FTP,除了完成正常的数据传递任务之外,还可以进行本地文件与服务端文件 的异同比较,同一文件自动匹配目录上传,下载,这些功能是平常I ...

  2. linux curl 命令 http请求、下载文件、ftp上传下载

    1. curl 命令简介 cURL(CommandLine Uniform Resource Locator),是一个利用 URL 语法,在命令行终端下使用的网络请求工具,支持 HTTP.HTTPS. ...

  3. ie11 java 下载文件_Javaweb实现上传下载文件的多种方法

    在Javaweb中,上传下载是经常用到的功能,对于文件上传,浏览器在上传的过程中是以流的过程将文件传给服务器,一般都是使用commons-fileupload这个包实现上传功能,因为commons-f ...

  4. Java实现七牛云文件或图片上传下载

    写在前面 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家:人工智能学习网站 文章目录 写在前面 一.准备工作 1.1.为什么选择七牛云? 1.2.七牛云注册 二.ja ...

  5. C++ vs2017 - libcurl - http请求 代码大全(请求数据,上传下载文件,多线程上传下载文件)

    在网上搜寻各种libcurl的用法,将代码集合于此! 目录 一.配置curl项目 二.Curl 请求参数 1. CURLOPT_POST 2. CURLOPT_URL 3. CURLOPT_HTTPH ...

  6. 使用Git工具从GitHub上文件代码进行上传下载(图文详细)

    1.注册一个GitHub账号 GitHub: Where the world builds software · GitHub  此链接为GitHub官网 由于GitHub是国外的网站,访问会很慢,又 ...

  7. java jsch下载文件,JSch使用sftp协议实现服务器文件上传下载操作

    Jsch是什么? JSch 是SSH2的一个纯Java实现.它允许你连接到一个sshd 服务器,使用端口转发,X11转发,文件传输等等.你可以将它的功能集成到你自己的 程序中.同时该项目也提供一个J2 ...

  8. maven 项目 springMVC实现文件图片的上传下载功能详解(源码已提供,小白必看)

    文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作. ...

  9. Java Servlet实现文件上传下载操作

    1.配置对应的文件,导入相应的包 对应包下载地址:https://wws.lanzous.com/ipFtEoyv1je 2.编写jsp页面 代码如下: <%@ taglib prefix=&q ...

  10. flask 对excel上传下载操作和文件处理

    文件的下载 from flask import send_from_directory @excel_bp.route('/get_attachment/<path:filename>') ...

最新文章

  1. 操作系统期末复习重点题型归纳
  2. SAMBA配置文件所用到的参数
  3. Apache下部署Django 的样式问题
  4. 你常用的Nginx模块,用来做什么
  5. R语言编程艺术(3)R语言编程基础
  6. bootstrapselect使用 Bootstrap's dropdowns require Popper.js
  7. 重新写博+linux查找系列
  8. python 的__str__和__repr__有什么区别?
  9. Android获取手机号归属地
  10. php admin_priv,ECshop后台开发模块步骤
  11. 图论算法——Prim算法和Kruskal算法
  12. 行程匹配的算法python_节约里程算法的python实现
  13. 数据线CE测试标准 准备资料
  14. iconfont矢量图标库的引用方法
  15. cachecloud:安装部署(一)
  16. AI行为识别:安防主动预警
  17. android绘制view的撤销,DrawingView android 上的一个涂鸦控件。可以设置画笔的粗细,颜色,撤销上一笔涂鸦,提供保存图片的接口。 @codeKK Android开源站...
  18. git 删除远程的tag
  19. 【可视化大屏设计学习1】正式开始建设可视化平台了,学习路径写下来!大家一起沟通呀!~
  20. OI 刷题记录——每周更新

热门文章

  1. jmeter展示内存cpu_基于Docker的jmeter弹性压测(2)监控
  2. 华为手表用鸿蒙了吗,华为鸿蒙都2.0了,手机还不能用吗?
  3. android 调用本地第三方应用软件,如qq、微信、微博和视频播放器等
  4. 全面改进Transformer类预训练模型,自然语言任务超越BERT
  5. 图神经网络三剑客:GCN、GAT与GraphSAGE
  6. 第三届“达观杯”文本智能算法大赛参赛指南
  7. 近期知识图谱顶会论文推荐,另附超详笔记解读
  8. access找不到输入表或者dual_数据表dual表的用途是什么?
  9. flink 本地_Flink原理Apache Flink漫谈系列 State
  10. isulad代替docker_云原生时代的华为新“引擎”:iSula | Linux 中国