easyexcel导出excel,大数据量100万以内分页查询zip格式导出
easyexcel导出excel,大数据量100万以内分页查询zip格式导出
- 准备工作
- 整体思路
- controller层
- service层
- mapper层
- VO
- 表结构
- 测试
- 备注
- easyExcel
准备工作
maven+springboot+mybatis
pom添加.
// maven依赖
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.6</version>
</dependency>
整体思路
因为之前的项目一直使用poi进行excel的导出导入,而poi对大数据的的导出对内存使用较大,数据量一大很容易出现OOM。而此时使用的easyExcel对poi的这些问题进行了处理,这是alibaba出品的简单、省内存的Java解析Excel工具。
- 准备20万数据;
- 页面请求之后开始对文件生成做异步处理,文件生成后通知客户端已生成,客户端下载之后将文件从服务器删除;
- 对需要导出的数据做分页处理;
- 利用线程池将每一页数据导出一个excel;
- 最后压缩成一个zip文件供客户端下载;
- 通知客户端下载的url;
controller层
// controller层@GetMapping("excelUser")public String excelUser(){int size = 40000;String url = "http://localhost/fileName.zip";String fileName = userService.excelUser(size);url = url.replace("fileName", fileName);return url;}
service层
// service层@Overridepublic String excelUser(Integer size) {String fileName = String.valueOf(System.currentTimeMillis());ExcelUtil.pool.submit(()->{//查询总数int count = this.mapper.findCount();int totalPage = count % size == 0 ? count / size : count / size + 1;int beginIndex = 0;List<Callable<List<UserVO>>> tasks = new ArrayList<>();//分页查询for (int i = 0; i < totalPage; i++) {UserMapper mapper = this.mapper;int finalBeginIndex = beginIndex;Callable<List<UserVO>> task = () -> mapper.findByPage(finalBeginIndex, size);beginIndex = beginIndex + size ;tasks.add(task);}ZipOutputStream zipout = null;InputStream inputStream = null;try {//导出压缩文件的全路径(此地址改成服务器存放地址)String zipFilePath = "D:\\nginx\\html\\" + fileName +".zip";//导出zipFile zip = new File(zipFilePath);zipout = new ZipOutputStream(new FileOutputStream(zip));List<Future<List<UserVO>>> futures = ExcelUtil.pool.invokeAll(tasks);int num = 0;if (futures.size() > 0) {for (Future<List<UserVO>> future : futures) {//sheetName页名称String sheetName = "sheetName";ByteArrayOutputStream outputStream = new ByteArrayOutputStream();ExcelWriter writer = EasyExcel.write(outputStream, UserVO.class).build();WriteSheet writeSheet = EasyExcel.writerSheet(sheetName).build();//导出excelwriter.write(future.get(), writeSheet);writer.finish();inputStream = new ByteArrayInputStream(outputStream.toByteArray());//excel文件写入zipZipEntry zipEntry = new ZipEntry(fileName + "-" + num + ".xlsx");zipout.putNextEntry(zipEntry);int len;byte[] buf = new byte[1024];while ((len = inputStream.read(buf)) > 0) {zipout.write(buf, 0, len);}num ++;}}//通知客户端已完成log.info("success" + "==========================" + zipFilePath);} catch (Exception e) {log.error(e.getMessage());} finally {try {zipout.close();} catch (IOException e) {e.printStackTrace();}try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}});return fileName;}
mapper层
// mapper层<select id="findCount" resultType="java.lang.Integer">SELECT COUNT(id) FROM user;</select><select id="findByPage" resultType="com.eoil.entity.vo.UserVO">SELECT id, name, age, money, create_timeFROM user LIMIT #{begin}, #{size};</select>
VO
// VO
@Data
public class UserVO {@ExcelProperty(value = "id", index = 0)private Integer id;@ExcelProperty(value = "姓名", index = 1)private String name;@ExcelProperty(value = "年龄", index = 2)private Integer age;@ExcelProperty(value = "金额", index = 3)private String money;@ColumnWidth(22)@DateTimeFormat("yyyy-MM-dd HH:mm:ss")@ExcelProperty(value = "创建时间", index = 4)private Date createTime;
}
表结构
// 表结构
CREATE TABLE `user` (`id` bigint(10) NOT NULL AUTO_INCREMENT,`name` varchar(10) DEFAULT NULL,`age` int(10) DEFAULT NULL,`money` int(10) DEFAULT NULL,`create_time` datetime DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=262127 DEFAULT CHARSET=utf8;
测试
启动项目,访问http://ip:端口/excelUser将异步返回一段可下载的url,此时客服端无需等待,等程序处理完成可以使用webSocket,推送通知,等通知方式,告知客户端已完成(本文暂时没有这样做)。
访问url将返回一段可下载路径,例如我本地访问路径。
此时复制url进入浏览器下载即可
文件内容
打开第一个文件
打开最后一个文件
备注
1:这样解决了客户端同步阻塞式的下载方式。
2:减少服务器一次性查询大量数据和导出数据的压力。
3:主要的性能瓶颈和sql的性能有关,根据测试导出这么多数据大概需要6秒(无索引的情况下),索引是否全面覆盖,表数据量非常大,是否进行了分区,只要控制sql执行效率高,基本导出不会太慢。
easyExcel
链接: easyExcel官网.
easyexcel导出excel,大数据量100万以内分页查询zip格式导出相关推荐
- python读取大数据量xml_[C#]_[使用微软OpenXmlSDK (OpenXmlReader)读取xlsx表格] 读取大数据量100万条数据Excel文件解决方案...
1.OpenXmlSDK是个很好的类库,可惜只能通过C#调用,C#的童鞋又福气了. 2.服务端程序由于没法安装office,所以这个对asp.net网站来说是最理想的库了.需要.net 4.0版本以上 ...
- java 导出excel 大数据量 报错_java导出excel
上面导出PDF和EXCEL的问题是图片路径出错!!! 数据库中存存的图片路径是"../dishpic/722f464f-3883-42aa-901f-21706da9c582.png&quo ...
- 大数据量性能优化之分页查询
刷帖子翻页需要分页查询,搜索商品也需分页查询.当遇到上千万.上亿数据量,怎么快速拉取全量数据呢? 比如: 大商家拉取每月千万级别的订单数量到自己独立的ISV做财务统计 拥有百万千万粉丝的大v,给全部粉 ...
- Apache POI和EasyExcel 第三集:Apache POI的Excel大数据量写入(分为03版的xls、07版的xlsx、升级版SXSSF)
Apache POI和EasyExcel 第三集:Apache POI的Excel大数据量写入(分为03版的xls.07版的xlsx.升级版SXSSF) 一.结果 我的03跑了1.204秒,07跑了5 ...
- 【Apache POI】Excel操作(四):Excel大数据量的写入
迷茫代表着你身边还有选择,焦虑意味着你手上还有时间. 有目录,不迷路 前言 超量数据 速率比较 原因剖析 超级版本大救星 往期回顾 前言 之前在下面这期Excel操作: [Apache POI]Exc ...
- Java实现excel大数据量导入
情景分析: 通常我们通过poi读取excel文件时,若在用户模式下,由于数据量较大.Sheet较多,很容易出现内存溢出的情况 用户模式读取excel的典型代码如下: FileInputStream f ...
- PHP导出Excel时数据量过大的问题
1.设置脚本运行时间 set_time_limit(0) 2.运行内存设置 当数据量比较大时就需要设置memory_limit,来防止内存报错,但是这终究不是解决办法,因为系统的内存是有限的,比如你设 ...
- 读取excel大数据量详解
需求:导入大数据量excel文件到数据库(测试11MB,40w行数据) 首先说结论:都是大概时间,且其中有两个参数需要调,这里统一下参数大小. 监听器中的缓存list一次性存100000(测试过100 ...
- Excel大数据量单元格快速填充
个人简介:一个从会计转行数据分析师的三旬老汉 擅长领域:数据分析.数据仓库.大数据 博客内容:平时会将自己工作中遇到的问题进行归纳总结,分享给各位小伙伴,意在帮助大家少加班.不掉发,让我们相互学习,一 ...
最新文章
- 微信用户全局唯一标识_分布式系统的唯一ID生成算法对比
- Java数据结构和算法:二叉树
- linux c头文件#include<sys/types.h>和#include<fcntl.h>头文件总结
- php core模块,module.php
- 在开启bin-log日志下Mysql报错
- 如何查找MySQL中查询慢的SQL语句
- php server(),php的$_SERVER参数详解(附实例)
- 3ds max sdk导出插件编写的心得
- C++在windows下获得运行主机的硬件信息:CPU序列号、MAC地址、硬盘序列号、主板序列号
- ue4材质节点大全_UE4材质节点大全
- 【React之文件的运行】用webstorm运行npm,实现网页的刷新
- win服务器系统无法切换输入法,win8系统中文输入法切换不出来
- 可变卷积(Deformable ConvNets)算法的MXNet实现
- wps插入C/C++代码
- 【报告分享】汽车数字营销新度量衡-懂车帝(附下载)
- skinme找不到java_配置forge后,无法获取依赖
- python学习 - 多个npy文件的合并和读取 | numpy array
- Android效率组件篇 设置长按响应时间(时长)
- 干草的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
- 网上销售平台--需求分析(二)