微服务超大Excel文件导出方案优化
1、在导出Excel时经常会碰到文件过大,导出特别慢
2、微服务限制了请求超时时间,文件过大情况必然超时
优化思路:
1、文件过大时通过文件拆分、打包压缩zip,然后上传到oss,并设置有效期(30天过期)
2、把同步下载改成异步
3、文件生成完成,更新任务状态
4、通过oss的下载链接下载文件
5、多模块复用,只需要实现各自查询Excel业务数据的接口即可
以下是部分参考代码:


public class TxnETExecutor extends AbstractExportTaskExecutor {private final MposScene mposScene;private final OssService ossService;@Overridepublic boolean support(int taskType) {return ExportTaskType.MPOS_TXN_BILL_EXPORT.ordinal() == taskType;}@Overridepublic int getFileSize(String reqBody, String audClientId, Long groupId) {TxnMposBillItemFindReq req = JSON.parseObject(reqBody, TxnMposBillItemFindReq.class);req.setAudClientId(audClientId);req.setLoginGroupId(groupId);req.setPage(1);req.setPageSize(1);req.setDiffStatus(true);Pageable pageable = mposScene.findByChannelBillItem(req);return pageable.getTotalPages().intValue();}public void execute(Long taskId, int fileSize, String reqBody, String audClientId, Long groupId) {TxnMposBillItemFindReq req = JSON.parseObject(reqBody, TxnMposBillItemFindReq.class);req.setAudClientId(audClientId);req.setLoginGroupId(groupId);req.setPage(1);req.setDiffStatus(true);int pageSize = Math.min(fileSize, DEFAULT_PAGE_SIZE);req.setPageSize(pageSize);Pageable pageable = mposScene.findByChannelBillItem(req);Long totalPages = pageable.getTotalPages();List<Map<String, Object>> first = parse(pageable.getItems());ByteArrayOutputStream outputStream = WebFluxUtils.buildExcelOutputStream(first, null);if (totalPages <= 1) {OssPutObjectResp objectResp = upload(audClientId, "xlsx", new ByteArrayInputStream(outputStream.toByteArray()));String fileUrl = objectResp.getFileUrl();update(CashierExportTaskUpdateReq.newBuilder().setId(taskId).setFileStatus(ExportTaskFileStatus.SUCCESS.ordinal()).setFileFormat("xlsx").setFileProgressRate("100%").setFileUrl(fileUrl).build());return;}Map<String, ByteArrayOutputStream> files = new HashMap<>();files.put(String.format("渠道对账单[%s-%s].xlsx", 1, totalPages), outputStream);for (int i = 2; i <= totalPages; i++) {req.setPage(i);Pageable pageableExportMore = mposScene.findByChannelBillItem(req);ByteArrayOutputStream j = WebFluxUtils.buildExcelOutputStream(parse(pageableExportMore.getItems()), null);files.put(String.format("渠道对账单[%s-%s].xlsx", i, totalPages), j);}Path tmp = zip(files);if (tmp == null) {update(CashierExportTaskUpdateReq.newBuilder().setId(taskId).setFileStatus(ExportTaskFileStatus.FAIL.ordinal()).setFileFormat("zip").setFileProgressRate("100%").build());return;}InputStream inputStream;try {inputStream = Files.newInputStream(tmp);} catch (IOException e) {e.printStackTrace();update(CashierExportTaskUpdateReq.newBuilder().setId(taskId).setFileStatus(ExportTaskFileStatus.FAIL.ordinal()).setFileFormat("zip").setFileProgressRate("100%").build());return;}try {OssPutObjectResp objectResp = upload(audClientId, "zip", inputStream);update(CashierExportTaskUpdateReq.newBuilder().setId(taskId).setFileStatus(ExportTaskFileStatus.SUCCESS.ordinal()).setFileFormat("zip").setFileProgressRate("100%").setFileUrl(objectResp.getFileUrl()).build());} catch (Exception e) {e.printStackTrace();update(CashierExportTaskUpdateReq.newBuilder().setId(taskId).setFileStatus(ExportTaskFileStatus.FAIL.ordinal()).setFileFormat("zip").setFileProgressRate("100%").build());} finally {try {Files.delete(tmp);} catch (IOException ignore) {}}}private List<Map<String, Object>> parse(Collection<TxnMposBillItemFindResp> items) {List<Map<String, Object>> result = new ArrayList<>();if (items == null || items.isEmpty()) {throw FibException.ofNotFound("暂无数据");}items.forEach(item -> {Map<String, Object> map = new LinkedHashMap<>();map.put("创建时间", item.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));map.put("批次号", item.getBatchNo());map.put("交易时间", item.getTransTime());map.put("交易月份", item.getTransMonth());map.put("平台订单号", item.getServerOrderId());......result.add(map);});return result;}private OssPutObjectResp upload(String audClientId, String suffix, InputStream inputStream) {return ossService.putObject(OssPutObjectReq.newBuilder().setBucketName(DEFAULT_BUCKET).setAudClientId(audClientId).setDirectoryPath("***").setSuffix(suffix).build(), inputStream);}
}
效果图:


相关文章:
微服务超大Excel文件导出方案优化
1、在导出Excel时经常会碰到文件过大,导出特别慢 2、微服务限制了请求超时时间,文件过大情况必然超时 优化思路: 1、文件过大时通过文件拆分、打包压缩zip,然后上传到oss,并设置有效期(30天过期) 2、把…...
论文阅读之Multimodal Chain-of-Thought Reasoning in Language Models
文章目录 简介摘要引言多模态思维链推理的挑战多模态CoT框架多模态CoT模型架构细节编码模块融合模块解码模块 实验结果总结 简介 本文主要对2023一篇论文《Multimodal Chain-of-Thought Reasoning in Language Models》主要内容进行介绍。 摘要 大型语言模型(LLM…...
灯塔:CSS笔记(2)
一 选择器进阶 后代选择器:空格 作用:根据HTML标签的嵌套关系,,选择父元素 后代中满足条件的元素 选择器语法:选择器1 选择器2{ css } 结果: *在选择器1所找到标签的后代(儿子 孙子 重孙子…...
基于Springboot的志愿服务管理系统(有报告)。Javaee项目,springboot项目。
演示视频: 基于Springboot的志愿服务管理系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构…...
保姆级讲解 Stable Diffusion
目录 本文讲解思路介绍 一、引入 二、Diffusion Model 三、原文的摘要和简介 四、Stable Diffusion 4.1、组成模块 4.2、感知压缩 4.3、条件控制 五、图解 Stable Diffusion 5.1、潜在空间的扩散 5.2、条件控制 5.3、采样 5.4、Diffusion Model 与 Stable Diffusion …...
HTML二识
图片,音频,视频标签 标签描述<img>定义图片<audio>定义音频<video>定义视频 定义图片: src:规定显示图片的URL(统一资源定位符)height:定义图像的高度 单位:px…...
[BUUCTF]-PWN:starctf_2019_babyshell解析(汇编\x00开头绕过+shellcode)
查看保护 查看ida 这里就是要输入shellcode,但是函数会有检测。 在shellcode前面构造一个以\x00机器码开头的汇编指令,这样就可以绕过函数检查了。 完整exp: from pwn import* context(log_leveldebug,archamd64) pprocess(./babyshell)she…...
uniapp 手写 简易 时间轴 组件
一、案例如图 该案例设计条件: 左侧时间 和竖线、点、内容都是居中对其的,上下时间点中间要有一段距离 二、编写逻辑 1. 布局结构:一共三个元素,左侧是时间和黑点,中间是线条,右侧是内容 2. 样式难点&#…...
实现HttpServletRequest下多次获取流数据
HttpServletRequest下多次获取流数据 背景示例错误的尝试全局替换执行顺序 背景 众所周知request的输入流只能读取一次,不能重复读取。而在HttpServletRequest中,获取请求体数据的流(通过getInputStream()方法)默认只能被读取一…...
uviewplus在uniapp中的配置使用
版本: "uview-plus": "^3.1.45"在page.json中配置: "easycom": {"autoscan": true,"custom": {"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue","^up-(.*)": "uview-plus/componen…...
C++11 新特性之future和packaged_task
C11 新特性之future #include <iostream> #include <thread> #include <future> #include <chrono>void test(std::promise<int>& probj){std::this_thread::sleep_for(std::chrono::seconds(5));probj.set_value(20); }int main(){std::pr…...
Flutter APP下载更新
由于我做的项目不是放在APP商店(公司内部用)的,一些flutter的第三方库不合适我,我需要用的是从网上下载再安装(从服务下),网上也找了花了我好几天时间。不全又乱,这我自己做一下备份…...
Pinctrl子系统_04_Pinctrl子系统主要数据结构
引言 本节说明Pinctrl子系统中主要的数据结构,对这些数据结构有所了解,也就是对Pinctrl子系统有所了解了。 前面说过,要使用Pinctrl子系统,就需要去配置设备树。 以内核面向对象的思想,设备树可以分为两部分&#x…...
设计模式(十):抽象工厂模式(创建型模式)
Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对 象的接口,而无须指定它们的具体类。 之前写过简单工厂和工厂方法模式(创建型模式),这两种模式比较简单。 简单工厂模式其实不符合开闭原则,即对修改关闭…...
计算机网络概论01
计算机系统基础知识 基本组成 计算机系统由硬件和软件组成。 硬件由五大部分,他们分别是: 运算器 执行算数运算和逻辑运算控制器 控制cpu的工作,决定了计算机运行过程的自动化。包括指令控制逻辑、时序控制逻辑、总线控制逻辑和中断控制逻辑…...
新零售SaaS架构:订单履约系统架构设计(万字图文总结)
什么是订单履约系统? 订单履约系统用来管理从接收客户订单到将商品送达客户手中的全过程。 它连接了上游交易(客户在销售平台下单环)和下游仓储配送(如库存管理、物流配送),确保信息流顺畅、操作协同&…...
Hive SQL 开发指南(三)优化及常见异常
在大数据领域,Hive SQL 是一种常用的查询语言,用于在 Hadoop上进行数据分析和处理。为了确保代码的可读性、维护性和性能,制定一套规范化的 Hive SQL 开发规范至关重要。本文将介绍 Hive SQL 的基础知识,并提供一些规范化的开发指…...
Spring Boot 自动装配的原理!!!
SpringBootApplication SpringBootConfiguration:标识启动类是一个IOC容器的配置类 EnableAutoConfiguration: AutoConfigurationPackage:扫描启动类所在包及子包中所有的组件,生…...
Linux运维_Bash脚本_编译安装Wayland-1.22.0
Linux运维_Bash脚本_编译安装Wayland-1.22.0 Bash (Bourne Again Shell) 是一个解释器,负责处理 Unix 系统命令行上的命令。它是由 Brian Fox 编写的免费软件,并于 1989 年发布的免费软件,作为 Sh (Bourne Shell) 的替代品。 您可以在 Linu…...
Python数字类型
文章目录 Python数字类型1. 数字类型1.1 数字类型概述1.2 整数类型1.3 浮点数类型1.4 复数 2. 数字类型的操作2.1 内置的数值运算操作符2.2 内置的数值运算函数2.3 内置的数字类型转换函数 思考与练习 Python数字类型 1. 数字类型 1.1 数字类型概述 数字是自然界计数活动的抽…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
全面解析数据库:从基础概念到前沿应用
在数字化时代,数据已成为企业和社会发展的核心资产,而数据库作为存储、管理和处理数据的关键工具,在各个领域发挥着举足轻重的作用。从电商平台的商品信息管理,到社交网络的用户数据存储,再到金融行业的交易记录处理&a…...
快速排序算法改进:随机快排-荷兰国旗划分详解
随机快速排序-荷兰国旗划分算法详解 一、基础知识回顾1.1 快速排序简介1.2 荷兰国旗问题 二、随机快排 - 荷兰国旗划分原理2.1 随机化枢轴选择2.2 荷兰国旗划分过程2.3 结合随机快排与荷兰国旗划分 三、代码实现3.1 Python实现3.2 Java实现3.3 C实现 四、性能分析4.1 时间复杂度…...
【1】跨越技术栈鸿沟:字节跳动开源TRAE AI编程IDE的实战体验
2024年初,人工智能编程工具领域发生了一次静默的变革。当字节跳动宣布退出其TRAE项目(一款融合大型语言模型能力的云端AI编程IDE)时,技术社区曾短暂叹息。然而这一退场并非终点——通过开源社区的接力,TRAE在WayToAGI等…...
