当前位置: 首页 > news >正文

微服务超大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时经常会碰到文件过大&#xff0c;导出特别慢 2、微服务限制了请求超时时间&#xff0c;文件过大情况必然超时 优化思路&#xff1a; 1、文件过大时通过文件拆分、打包压缩zip&#xff0c;然后上传到oss,并设置有效期&#xff08;30天过期&#xff09; 2、把…...

论文阅读之Multimodal Chain-of-Thought Reasoning in Language Models

文章目录 简介摘要引言多模态思维链推理的挑战多模态CoT框架多模态CoT模型架构细节编码模块融合模块解码模块 实验结果总结 简介 本文主要对2023一篇论文《Multimodal Chain-of-Thought Reasoning in Language Models》主要内容进行介绍。 摘要 大型语言模型&#xff08;LLM…...

灯塔:CSS笔记(2)

一 选择器进阶 后代选择器&#xff1a;空格 作用&#xff1a;根据HTML标签的嵌套关系&#xff0c;&#xff0c;选择父元素 后代中满足条件的元素 选择器语法&#xff1a;选择器1 选择器2{ css } 结果&#xff1a; *在选择器1所找到标签的后代&#xff08;儿子 孙子 重孙子…...

基于Springboot的志愿服务管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的志愿服务管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…...

保姆级讲解 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二识

图片&#xff0c;音频&#xff0c;视频标签 标签描述<img>定义图片<audio>定义音频<video>定义视频 定义图片&#xff1a; src&#xff1a;规定显示图片的URL&#xff08;统一资源定位符&#xff09;height&#xff1a;定义图像的高度 单位&#xff1a;px…...

[BUUCTF]-PWN:starctf_2019_babyshell解析(汇编\x00开头绕过+shellcode)

查看保护 查看ida 这里就是要输入shellcode&#xff0c;但是函数会有检测。 在shellcode前面构造一个以\x00机器码开头的汇编指令&#xff0c;这样就可以绕过函数检查了。 完整exp&#xff1a; from pwn import* context(log_leveldebug,archamd64) pprocess(./babyshell)she…...

uniapp 手写 简易 时间轴 组件

一、案例如图 该案例设计条件&#xff1a; 左侧时间 和竖线、点、内容都是居中对其的&#xff0c;上下时间点中间要有一段距离 二、编写逻辑 1. 布局结构&#xff1a;一共三个元素&#xff0c;左侧是时间和黑点&#xff0c;中间是线条&#xff0c;右侧是内容 2. 样式难点&#…...

实现HttpServletRequest下多次获取流数据

HttpServletRequest下多次获取流数据 背景示例错误的尝试全局替换执行顺序 背景 ​众所周知request的输入流只能读取一次&#xff0c;不能重复读取。而在HttpServletRequest中&#xff0c;获取请求体数据的流&#xff08;通过getInputStream()方法&#xff09;默认只能被读取一…...

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商店&#xff08;公司内部用&#xff09;的&#xff0c;一些flutter的第三方库不合适我&#xff0c;我需要用的是从网上下载再安装&#xff08;从服务下&#xff09;&#xff0c;网上也找了花了我好几天时间。不全又乱&#xff0c;这我自己做一下备份…...

Pinctrl子系统_04_Pinctrl子系统主要数据结构

引言 本节说明Pinctrl子系统中主要的数据结构&#xff0c;对这些数据结构有所了解&#xff0c;也就是对Pinctrl子系统有所了解了。 前面说过&#xff0c;要使用Pinctrl子系统&#xff0c;就需要去配置设备树。 以内核面向对象的思想&#xff0c;设备树可以分为两部分&#x…...

设计模式(十):抽象工厂模式(创建型模式)

Abstract Factory&#xff0c;抽象工厂&#xff1a;提供一个创建一系列相关或相互依赖对 象的接口&#xff0c;而无须指定它们的具体类。 之前写过简单工厂和工厂方法模式(创建型模式)&#xff0c;这两种模式比较简单。 简单工厂模式其实不符合开闭原则&#xff0c;即对修改关闭…...

计算机网络概论01

计算机系统基础知识 基本组成 计算机系统由硬件和软件组成。 硬件由五大部分&#xff0c;他们分别是&#xff1a; 运算器 执行算数运算和逻辑运算控制器 控制cpu的工作&#xff0c;决定了计算机运行过程的自动化。包括指令控制逻辑、时序控制逻辑、总线控制逻辑和中断控制逻辑…...

新零售SaaS架构:订单履约系统架构设计(万字图文总结)

什么是订单履约系统&#xff1f; 订单履约系统用来管理从接收客户订单到将商品送达客户手中的全过程。 它连接了上游交易&#xff08;客户在销售平台下单环&#xff09;和下游仓储配送&#xff08;如库存管理、物流配送&#xff09;&#xff0c;确保信息流顺畅、操作协同&…...

Hive SQL 开发指南(三)优化及常见异常

在大数据领域&#xff0c;Hive SQL 是一种常用的查询语言&#xff0c;用于在 Hadoop上进行数据分析和处理。为了确保代码的可读性、维护性和性能&#xff0c;制定一套规范化的 Hive SQL 开发规范至关重要。本文将介绍 Hive SQL 的基础知识&#xff0c;并提供一些规范化的开发指…...

Spring Boot 自动装配的原理!!!

SpringBootApplication SpringBootConfiguration&#xff1a;标识启动类是一个IOC容器的配置类 EnableAutoConfiguration&#xff1a; AutoConfigurationPackage&#xff1a;扫描启动类所在包及子包中所有的组件&#xff0c;生…...

Linux运维_Bash脚本_编译安装Wayland-1.22.0

Linux运维_Bash脚本_编译安装Wayland-1.22.0 Bash (Bourne Again Shell) 是一个解释器&#xff0c;负责处理 Unix 系统命令行上的命令。它是由 Brian Fox 编写的免费软件&#xff0c;并于 1989 年发布的免费软件&#xff0c;作为 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 数字类型概述 数字是自然界计数活动的抽…...

3个步骤让MedSAM医疗影像分割模型成为你的AI诊断助手

3个步骤让MedSAM医疗影像分割模型成为你的AI诊断助手 【免费下载链接】MedSAM Segment Anything in Medical Images 项目地址: https://gitcode.com/gh_mirrors/me/MedSAM 你是一名放射科医生&#xff0c;面对堆积如山的CT扫描图像&#xff0c;需要快速准确地标注出肿瘤…...

别再当老实人了!用博弈论拆解程序员薪资谈判,教你多拿20%的Offer

程序员薪资谈判实战&#xff1a;用博弈论思维多拿20% Offer 在技术行业&#xff0c;薪资谈判往往是决定职业发展速度的关键环节。许多开发者花费数月刷题准备技术面试&#xff0c;却在最后谈薪阶段草草收场&#xff0c;殊不知这个环节的博弈可能直接影响未来三年的总收入增长曲…...

FreeRTOS临界区避坑指南:taskENTER_CRITICAL()用不对,你的系统可能随时崩溃

FreeRTOS临界区避坑指南&#xff1a;taskENTER_CRITICAL()用不对&#xff0c;你的系统可能随时崩溃 调试嵌入式系统时最令人抓狂的瞬间&#xff0c;往往是那些看似毫无规律的随机崩溃——比如某个传感器数据偶尔错位、系统突然卡死、或是中断服务程序莫名丢失事件。上周我就遇到…...

Rust构建的番茄小说下载器:现代化本地阅读生态的技术架构解析

Rust构建的番茄小说下载器&#xff1a;现代化本地阅读生态的技术架构解析 【免费下载链接】Tomato-Novel-Downloader 番茄小说下载器不精简版 项目地址: https://gitcode.com/gh_mirrors/to/Tomato-Novel-Downloader 在网络小说阅读领域&#xff0c;内容可移植性与阅读体…...

小程序生态联动:如何设计一个优雅的跨小程序用户流程与数据共享方案

小程序生态联动&#xff1a;如何设计一个优雅的跨小程序用户流程与数据共享方案 在移动互联网生态中&#xff0c;小程序以其轻量化和即用即走的特性&#xff0c;逐渐成为连接用户与服务的重要桥梁。当业务场景需要多个小程序协同工作时&#xff0c;如何实现无缝跳转与数据共享&…...

不止于调试:挖掘J-Link Commander隐藏命令,玩转芯片信息读取与安全启动

深入探索J-Link Commander&#xff1a;解锁芯片信息读取与安全启动的高级技巧 当大多数开发者将J-Link视为简单的调试工具时&#xff0c;它实际上隐藏着令人惊讶的硬件交互能力。想象一下&#xff0c;你不仅能调试代码&#xff0c;还能直接与芯片内部的各种寄存器对话&#xff…...

【AGI发展里程碑】:SITS2026官方路线图深度解码——5大技术跃迁节点与3年落地时间表

第一章&#xff1a;SITS2026发布&#xff1a;AGI发展路线图 2026奇点智能技术大会(https://ml-summit.org) SITS2026正式发布了《通用人工智能发展路线图&#xff08;2026–2035&#xff09;》&#xff0c;标志着AGI研发从碎片化工程实践转向系统性科学治理。该路线图由全球4…...

RexUniNLU多场景验证:在微博短文本、论文长段落、公文正式语体中稳定表现

RexUniNLU多场景验证&#xff1a;在微博短文本、论文长段落、公文正式语体中稳定表现 1. 引言&#xff1a;一个模型应对所有中文文本场景 在日常工作中&#xff0c;我们经常需要处理各种类型的中文文本&#xff1a;刷微博时的简短动态、阅读学术论文的长篇段落、撰写正式公文…...

XXL-Job适配PostgreSQL踩坑实录:版本差异、SQL改写与MyBatis Mapper的那些坑

XXL-Job适配PostgreSQL实战&#xff1a;从版本差异到SQL优化的完整指南 在分布式任务调度领域&#xff0c;XXL-Job凭借其轻量级设计和易用性赢得了众多开发者的青睐。然而当我们需要将其默认的MySQL存储切换到PostgreSQL时&#xff0c;会遇到一系列意料之外的挑战。本文将分享我…...

红队实战复盘:如何用Viper+Docker快速搭建一个可协作的内网渗透测试环境

红队协作渗透实战&#xff1a;基于容器化框架的高效团队作战指南 当企业安全团队需要模拟真实攻击场景时&#xff0c;传统单兵作战模式往往面临环境搭建复杂、进度难以同步、数据无法共享等痛点。本文将分享如何利用容器化技术快速构建支持多人协作的渗透测试平台&#xff0c;通…...