微服务超大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 数字类型概述 数字是自然界计数活动的抽…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...