超好用的Excel异步导出功能

2024-04-16 15:32

本文主要是介绍超好用的Excel异步导出功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

之前也做过关于Excel的导出案例,此次也是在其基础上进行改造升级:

https://www.bilibili.com/video/BV1kf4y1i761?p=5

但是之前的导出存在这么几个问题:

  • 如果是数据量很大容易导致页面卡死(我曾导出30w条数据,直接导致OOM)
  • 用户体验很糟糕,数据量一多就会等很久,而且用户没办法做别的事情。
  • 每次点击导出都需要走一遍完整的导出过程(这个其实还好)
  • 没办法对每次导出的数据进一个规整

今天使用异步导出来解决上述问题。


一、UML图

1-1、导出图

前台 Controller ServiceA ServiceB 点击导出 往数据库插入记录 插入一条下载记录 id name文件名 rows 下载行数 (null) takeUpTime 下载耗时 (null) downloadUrl 下载地址(null) 异步下载 (id、startTime) success 下载成功,稍等片刻去【下载中心】下载 根据需求去获取对应的数据 把数据生成一个文件保存起来 根据Id获取刚刚插入的记录 完善以下数据 rows 下载行数 takeUpTime 下载耗时 downloadUrl 下载地址(null) 前台 Controller ServiceA ServiceB

1-2、下载图

前台 Controller 获取下载列表 返回下载列表 downLoadUrl 返回文件流 前台 Controller

从上面的图中可以看出,整个下载是异步的,用户不需要在页面等待,每次导出我们都生成一个记录和一个文件,用户可以多次下载。


二、功能实现

2-1、记录实体

/*** Excel列表数据** @author 小道仙97* @date 2021/8/8*/
public class ExcelList {/*** id*/private String id;/*** 文件名*/private String name;/*** 下载行数*/private Integer rows;/*** 下载耗时*/private Long takeUpTime;/*** 下载地址*/private String downloadUrl;
}

2-2、Controller

import javax.servlet.http.HttpServletResponse;
import java.util.*;/*** Excel导出** @author 小道仙97* @date 2021-08-08*/
@RestController
public class ExportExcelController {@Autowiredprivate ExportExcel exportExcel;// 模仿下载列表public static List<ExcelList> list = new ArrayList<>(10);/*** Excel 导出* @throws Exception*/@GetMapping("/excel/export")public void export() {Long startTime = System.currentTimeMillis();String name = "Excel异步导出测试" + UUID.randomUUID().toString() + ".xlsx";String id = UUID.randomUUID().toString();ExcelList excelList = new ExcelList();excelList.setId(id);excelList.setName(name);list.add(excelList);// 异步导出exportExcel.asyncExportExcel(id,name,startTime);}/*** 获取导出列表 - 模拟*/@GetMapping("/excel/list")public List<ExcelList> list() {return list;}/*** 文件下载*/@GetMapping("/excel/downLoad")public void downLoad(HttpServletResponse response,@RequestParam  String url) {FileUtils.download(url, response);}
}

2-3、异步下载实现

ExportExcel

注:使用异步注解@Async 需要先在启动类上开启 @EnableAsync

import org.springframework.scheduling.annotation.Async;public interface ExportExcel {/*** 异步导出* @param id 唯一记录Id* @param name 文件名称* @param startTime 下载开始时间*/@Asyncvoid asyncExportExcel(String id,String name,Long startTime);
}

TestExportExcelImpl

@Service
public class TestExportExcelImpl implements ExportExcel {@Overridepublic void asyncExportExcel(String id,String name,Long startTime) {// 模拟查询数据过程String[] header = new String[]{"姓名","年纪"};String[] keys = new String[]{"name","age"};List<Map<String, Object>> content = new ArrayList<>();Map<String, Object> map1 = new HashMap<>();map1.put("name","小道仙");map1.put("age","23");content.add(map1);Map<String, Object> map2 = new HashMap<>();map2.put("name","小道仙97");map2.put("age","97");content.add(map2);try {// 获取Excel导出文件流ByteArrayOutputStream os = new ByteArrayOutputStream();ExcelUtils.exportExcel(header,keys,content,"first",os);byte[] content1 = os.toByteArray();InputStream inputStream = new ByteArrayInputStream(content1);// 上传文件 返回下载地址String url = FileUtils.uploadInputStream(inputStream, name);/*** 找到当前数据并封装结果集** 其实这里很简单并无这么复杂,实际情况我们只需要一个 update 语句就可以搞定*/for (ExcelList item : ExportExcelController.list) {if (item.getId().equals(id)) {item.setRows(content.size());item.setDownloadUrl(url);item.setTakeUpTime(System.currentTimeMillis() - startTime);break;}}}catch (Exception e){e.printStackTrace();}}
}

三、演示

下面的演示的前提都是在启动了项目的基础上

3-1、导出

因为没有做任何的返回值,所以是空返回,这里也可以自定义任何提示返回。

http://127.0.0.1:8888/excel/export


3-2、下载列表

http://127.0.0.1:8888/excel/list

返回结果如下:

[{"id": "d3cb3551-cb33-445e-8e60-9534197f6647","name": "Excel异步导出测试80d50264-3930-4667-8bc5-2d4a1cfe0d9d.xlsx","rows": 2,"takeUpTime": 5,"downloadUrl": "2021/8/8/Excel异步导出测试80d50264-3930-4667-8bc5-2d4a1cfe0d9d.xlsx"}
]

3-3、下载

http://127.0.0.1:8888/excel/downLoad?url=2021/8/8/Excel异步导出测试80d50264-3930-4667-8bc5-2d4a1cfe0d9d.xlsx



视频看讲解地址:https://www.bilibili.com/video/BV1kf4y1i761

关注微信公众号回复:xdxFrameSimple 获取源码。

在这里插入图片描述

这篇关于超好用的Excel异步导出功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/909180

相关文章

springboot集成easypoi导出word换行处理过程

《springboot集成easypoi导出word换行处理过程》SpringBoot集成Easypoi导出Word时,换行符n失效显示为空格,解决方法包括生成段落或替换模板中n为回车,同时需确... 目录项目场景问题描述解决方案第一种:生成段落的方式第二种:替换模板的情况,换行符替换成回车总结项目场景s

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

oracle 11g导入\导出(expdp impdp)之导入过程

《oracle11g导入导出(expdpimpdp)之导入过程》导出需使用SEC.DMP格式,无分号;建立expdir目录(E:/exp)并确保存在;导入在cmd下执行,需sys用户权限;若需修... 目录准备文件导入(impdp)1、建立directory2、导入语句 3、更改密码总结上一个环节,我们讲了

Python实现批量CSV转Excel的高性能处理方案

《Python实现批量CSV转Excel的高性能处理方案》在日常办公中,我们经常需要将CSV格式的数据转换为Excel文件,本文将介绍一个基于Python的高性能解决方案,感兴趣的小伙伴可以跟随小编一... 目录一、场景需求二、技术方案三、核心代码四、批量处理方案五、性能优化六、使用示例完整代码七、小结一、

Debian 13升级后网络转发等功能异常怎么办? 并非错误而是管理机制变更

《Debian13升级后网络转发等功能异常怎么办?并非错误而是管理机制变更》很多朋友反馈,更新到Debian13后网络转发等功能异常,这并非BUG而是Debian13Trixie调整... 日前 Debian 13 Trixie 发布后已经有众多网友升级到新版本,只不过升级后发现某些功能存在异常,例如网络转

Python异步编程之await与asyncio基本用法详解

《Python异步编程之await与asyncio基本用法详解》在Python中,await和asyncio是异步编程的核心工具,用于高效处理I/O密集型任务(如网络请求、文件读写、数据库操作等),接... 目录一、核心概念二、使用场景三、基本用法1. 定义协程2. 运行协程3. 并发执行多个任务四、关键

基于Java和FFmpeg实现视频压缩和剪辑功能

《基于Java和FFmpeg实现视频压缩和剪辑功能》在视频处理开发中,压缩和剪辑是常见的需求,本文将介绍如何使用Java结合FFmpeg实现视频压缩和剪辑功能,同时去除数据库操作,仅专注于视频处理,需... 目录引言1. 环境准备1.1 项目依赖1.2 安装 FFmpeg2. 视频压缩功能实现2.1 主要功

使用Python实现无损放大图片功能

《使用Python实现无损放大图片功能》本文介绍了如何使用Python的Pillow库进行无损图片放大,区分了JPEG和PNG格式在放大过程中的特点,并给出了示例代码,JPEG格式可能受压缩影响,需先... 目录一、什么是无损放大?二、实现方法步骤1:读取图片步骤2:无损放大图片步骤3:保存图片三、示php

深度解析Python yfinance的核心功能和高级用法

《深度解析Pythonyfinance的核心功能和高级用法》yfinance是一个功能强大且易于使用的Python库,用于从YahooFinance获取金融数据,本教程将深入探讨yfinance的核... 目录yfinance 深度解析教程 (python)1. 简介与安装1.1 什么是 yfinance?