Springboot---后台导出功能,easyExcel
Sprintboot+vuejs+easyExcel实现excel导出功能
一、背景
前段时间,有个需求,想要做一个excel导出功能,用来把查询到的数据进行导出。第一次做,所以搜了大量的资料,分为两种,一个是查询出来前端用XLSX和File-saver导出,一个是springboot导出,返回文件流。这次就做一个后端导出的记录吧!
二、几种excel导出方式比较
用 Apache 开源框架 poi, 或者 jxl 都可以实现。
传统 Excel 框架的不足:Apache poi、jxl 都存在生成 excel 文件不够简单优雅快速外,它们都还存在一个严重的问题,那就是非常耗内存,严重时会导致内存溢出。
POI 虽然目前来说,是 excel 解析框架中被使用最广泛的,但这个框架并不完美。
为什么这么说呢?
开发者们大部分使用 POI,都是使用其 userModel 模式。而 userModel 的好处是上手容易使用简单,随便拷贝个代码跑一下,剩下就是写业务转换了,虽然转换也要写上百行代码,但是还是可控的。
然而 userModel 模式最大的问题是在于,对内存消耗非常大,一个几兆的文件解析甚至要用掉上百兆的内存。现实情况是,很多应用现在都在采用这种模式,之所以还正常在跑是因为并发不大,并发上来后,一定会OOM或者频繁的 full gc。
三、easyExcel
由阿里出品的easyExcel,gitHub地址:https://github.com/alibaba/easyexcel
四、快速上手
1.添加依赖
<!--alibaba easyexcel-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>1.1.2-beta5</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
lombok这个依赖在后面如果使用model接受数据设置excel的列名的时候需要用到。
2.pojo设置列名(创建需要写入的数据集)
正常业务中,这块都是从数据库中查询出来的。
@Data
public class WriteModel extends BaseRowModel { @ExcelProperty(value = "姓名", index = 0)
private String name; @ExcelProperty(value = "密码", index = 1)
private String password; @ExcelProperty(value = "年龄", index = 2)
private Integer age;
}
ExayExcel 提供注解的方式, 来方便的定义 Excel 需要的数据模型:
- ①:首先,定义的写入模型必须要继承自
BaseRowModel.java
; - ②:通过
@ExcelProperty
注解来指定每个字段的列名称,以及下标位置;
3.逻辑代码,生成excel
1)生成到本地
public void writeExcel1(String pathName,List<? extends BaseRowModel> dataInfo) throws Exception {
// 文件输出位置
OutputStream out = new FileOutputStream(filePath); ExcelWriter writer = EasyExcelFactory.getWriter(out); // 写仅有一个 Sheet 的 Excel 文件, 此场景较为通用
Sheet sheet1 = new Sheet(1, 0, WriteModel.class); // 第一个 sheet 名称
sheet1.setSheetName("第一个sheet"); // 写数据到 Writer 上下文中
// 入参1: 创建要写入的模型数据
// 入参2: 要写入的目标 sheet
writer.write(dataInfo, sheet1); // 将上下文中的最终 outputStream 写入到指定文件中
writer.finish(); // 关闭流
out.close();
}
2)生成文件流返回给前端
public void cooperation(HttpServletResponse response,String fileName,String sheetName,List<? extends BaseRowModel> dataInfo,Class<? extends BaseRowModel> clazz) {
ExcelWriter writer = null;
OutputStream out = null;
out = response.getOutputStream();
writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
Sheet sheet1 = new Sheet(1, 0,clazz);
sheet1.setSheetName("第一个sheet");
writer.write(dataInfo, sheet1);
writer.finish();
response.setContentType("multipart/form-data");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename="+fileName+".xlsx");
response.setHeader("FileName", fileName+".xlsx");
out.flush();
}
}
前端主要是发送请求,当成功的时候,就接受文件流,创建一个超链接a,点击
axios({
method: "post",
url: "/excel",
data:this.query.data,
responseType: "blob"
})
.then(res => {
// console.log(decodeURI(res.headers['filename']));
const link = document.createElement("a");
let blob = new Blob([res.data], { type: "multipary/form-data" });
link.style.display = "none";
link.href = URL.createObjectURL(blob);
link.setAttribute("download", decodeURI(res.headers['filename']));
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch(error => {
this.$Notice.error({
title: "错误",
desc: "系统数据错误"
});
console.log(error);
});
},
3)动态生成excel的表头
有的时候我们不知道表头是什么,什么形式,有哪些,需要通过查询数据库才能获得,这个时候我们就需要mybatis先查出数据库中的字段名,然后创建表头,之后再进行数据填充
因为easyExcel的函数编写,需要给他List<List<String>> 类型的表头信息,以及List<List<object>>类型的表内容信息
而mybatis中生成返回的仅仅是List<String >和List<HashHap<String,String>>类型的,所以需要自己进行转换一下
public void cooperation(HttpServletResponse response,String fileName,String sheetName,List<List<Object>> dataInfo,List<List<String>> params) {
ExcelWriter writer = null;
OutputStream out = null;
out = response.getOutputStream();
writer = new ExcelWriter(out, ExcelTypeEnum.XLSX);
Sheet sheet1 = new Sheet(1, 0);
sheet1.setSheetName("第一个sheet");
sheet1.setHead(params);
writer.write1(dataInfo, sheet1);
writer.finish();
response.setContentType("multipart/form-data");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename="+fileName+".xlsx");
response.setHeader("FileName", fileName+".xlsx");
out.flush();
}
}
以上就是我在写的过程中用到的三种生成excel的方法。更多详细的内容可以去github查看
Springboot---后台导出功能,easyExcel的更多相关文章
- SpringCloud微服务实战——搭建企业级开发框架(三十):整合EasyExcel实现数据表格导入导出功能
批量上传数据导入.数据统计分析导出,已经基本是系统必不可缺的一项功能,这里从性能和易用性方面考虑,集成EasyExcel.EasyExcel是一个基于Java的简单.省内存的读写Excel的开源项 ...
- SpringBoot图文教程9—SpringBoot 导入导出 Excel 「Apache Poi」
有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...
- ActiveReports中如何在后台导出运行时绑定数据源报表
ActiveReports支持运行时绑定数据源功能,这种绑定数据源方法使用较为普及,然而很多系统中都需要在后台导出报表文件,所以用户就很困惑,ActiveReports中如何在后台导出运行时绑定数据源 ...
- 用SpringMvc实现Excel导出功能
以前只知道用poi导出Excel,最近用了SpringMvc的Excel导出功能,结合jxl和poi实现,的确比只用Poi好,两种实现方式如下: 一.结合jxl实现: 1.引入jxl的所需jar包: ...
- 利用Aspose.Cells完成easyUI中DataGrid数据的Excel导出功能
我准备在项目中实现该功能之前,google发现大部分代码都是利用一般处理程序HttpHandler实现的服务器端数据的Excel导出,但是这样存在的问题是ashx读取的数据一般都是数据库中视图的数据, ...
- [转载]ecshop 实现订单导出功能 指定订单导出 EXCEL 数据文件
当下很多功能都觉得理所当然,但是实际作为2012年停更的ECSHOP来说,很多功能其实都是缺少的,好比今天的要说的功能 订单导出 这个功能对于现在的产品设计来说,应该属于一个比较常规的功能,但是ECS ...
- 实现excel导入导出功能,excel导入数据到页面中,页面数据导出生成excel文件
今天接到项目中的一个功能,要实现excel的导入,导出功能.这个看起来思路比较清楚,但是做起了就遇到了不少问题. 不过核心的问题,大家也不会遇到了.每个项目前台页面,以及数据填充方式都不一样,不过大多 ...
- xadmin后台导出时gunicorn报错ascii
django + xadmin + nginx + gunicorn部署后,xadmin后台导出model数据报错,gunicorn日志记录为:UnicodeEncodeError: 'ascii' ...
- asp.net导出excel-一行代码实现excel、xml、pdf、word、html、csv等7种格式文件导出功能而且美观-SNF快速开发平台
分享: 腾讯微博 新浪微博 搜狐微博 网易微博 腾讯朋友 百度贴吧 豆瓣 QQ好友 人人网 作者:王春天 原文地址:http://www.cnblogs.com/spring_ ...
随机推荐
- Jmeter工具使用-分布式架构和服务器性能监控解决方案
在对项目做大并发性能测试时,常会碰到并发数比较大(比如需要支持10000并发),单台电脑的配置(CPU和内存)可能无法支持,这时可以使用Jmeter提供的分布式测试的功能来搭建分布式并发环境. 一.J ...
- JVM(八),垃圾回收标记算法
八.垃圾回收标记算法 1.对象被判定成垃圾的标准 没有被其他对象引用 2.判断对象是否为垃圾的算法 (1)引用计数法 优点and缺点 (2)可达性分析算法
- 灰度图像--图像分割 Marr-Hildreth算子(LoG算子)
学习DIP第49天 转载请标明本文出处:*http://blog.csdn.net/tonyshengtan *,出于尊重文章作者的劳动,转载请标明出处!文章代码已托管,欢迎共同开发: https:/ ...
- js监听transition过渡事件
html <div id="mydiv"> </div> style #mydiv{ width:100px; height:100px; backgrou ...
- AcWing:175. 电路维修(bfs)
达达是来自异世界的魔女,她在漫无目的地四处漂流的时候,遇到了善良的少女翰翰,从而被收留在地球上. 翰翰的家里有一辆飞行车. 有一天飞行车的电路板突然出现了故障,导致无法启动. 电路板的整体结构是一个R ...
- Codeforces 785 E. Anton and Permutation(分块,树状数组)
Codeforces 785 E. Anton and Permutation 题目大意:给出n,q.n代表有一个元素从1到n的数组(对应索引1~n),q表示有q个查询.每次查询给出两个数l,r,要求 ...
- Hive 利用 on tez 引擎 合并小文件
Hive 利用 on tez 引擎 合并小文件 标签(空格分隔): Hive \[f(N) + \sum_{i=2}^N f(N-i+1)*X_i\] SET hive.exec.dynamic.pa ...
- 修改jupyter notebook的字体等样式
方法一 /lib/site-packages/notebook/static/custom/ 里面有个custom.css文件,你只要修改这个文件就可以了. /* jupyter notebook中显 ...
- 8 Linux 文件类型
Linux 系统中的文件是没有扩展名的. 1.通过 ls -l 文件名,看第一个字符判断文件类型: - 普通文件(文本文件.二进制文件.压缩文件.电影.图片等) d 目录文件 b 设备文件(块设 ...
- Python: sklearn库——数据预处理
Python: sklearn库 —— 数据预处理 数据集转换之预处理数据: 将输入的数据转化成机器学习算法可以使用的数据.包含特征提取和标准化. 原因:数据集的标准化(服从均值为 ...