easyExcel导出大数据量EXCEL文件,前端实现进度条或者遮罩层

需求:页面点击导出,先按照页面条件去数据库查询,然后将查询到的数据导出。

问题:由于查询特别耗时,所以点击之后页面会看上去没有反应

方案1:就在点击之后在页面增加了一个进度条,等待后端查询结束之后,导出时,进度条会显示导出进度,导出结束之后进度条会消失。效果如下:

方案2:点击导出时前端增加一个遮罩层,遮罩层中间显示正在下载,导出完成后遮罩层消失,好处是可以既给用户提示,还可以阻止用户再次点击导出按钮。效果如下:

注意点:后端需要在响应头中设置ContentLength,前端需要用这个更新进度

response.setContentLength(excelBytes.length); // 设置Content-Length

方案1:进度条

html代码:

导 出

下载进度: 0%

css:

#progressContainer {
width: 100%;
background-color: #f3f3f3;
border: 1px solid #ccc;
border-radius: 5px;
}
#progressBar {
width: 0%;
height: 20px;
background-color: #4caf50;
border-radius: 5px;
}

js代码:

//进度条
$(‘#export_btn’).on(‘click’, function () {
// 获取表单数据并构建FormData对象
var formData = $(‘#searchForm’).serializeArray();
var form = new FormData();

$.each(formData, function () {
form.append(this.name, this.value);
});

// 添加额外的参数
form.append(‘publishFrom’, ‘${RequestParameters.type}’);

// 创建XHR对象
var xhr = new XMLHttpRequest();
xhr.open('POST', '路径/exportData', true);
xhr.responseType = 'blob'; // 设置响应类型为blob

// 显示进度条
$('#progressContainer').show();
$('#progressText').show();
$('#progressBar').css('width', '0%');
$('#progressText').text('下载进度: 0%');

// 设置请求头以模拟表单提交
// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

// 监听下载进度
xhr.onprogress = function (event) {
    if (event.lengthComputable) {
        var percentComplete = Math.round((event.loaded / event.total) \* 100);
        console.log('Loaded:', event.loaded, 'Total:', event.total);
        $('#progressBar').css('width', percentComplete + '%');
        $('#progressText').text('下载进度: ' + percentComplete + '%');
    } else {
        console.log('无法计算进度');
    }
};

// 下载完成后处理
xhr.onload = function () {
    if (xhr.status === 200) {
        // 隐藏进度条
        $('#progressContainer').hide();
        $('#progressText').hide();

        // 创建下载链接并触发下载
        var blob = xhr.response;
        var downloadUrl = URL.createObjectURL(blob);
        var a = document.createElement('a');
        a.href = downloadUrl;
        // 从响应头中获取文件名
        var disposition = xhr.getResponseHeader('Content-Disposition');
        var fileName = '下载文件.xlsx';
        if (disposition && disposition.indexOf('filename\*=utf-8''') !== -1) {
            var filenameRegex = /filename\*=utf-8''(.+)/;
            var matches = filenameRegex.exec(disposition);
            if (matches != null && matches\[1\]) {
                fileName = decodeURIComponent(matches\[1\]);
            }
        }
        a.download = fileName;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(downloadUrl);
    } else {
        alert('下载失败,请重试。');
        $('#progressContainer').hide();
        $('#progressText').hide();
    }
};

// 发送请求
xhr.send(form);

});

后端代码,使用easyExcel导出

//数据查询
List sellList = this.search();

// 将Excel写入ByteArrayOutputStream
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
// 使用EasyExcel将数据写入ByteArrayOutputStream
EasyExcel.write(baos, Sell.class)
.sheet(“列表”)
.doWrite(sellList);

// 获取Excel字节数组
byte\[\] excelBytes = baos.toByteArray();

// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode("列表导出\_Sell", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-Disposition", "attachment;filename\*=utf-8''" + fileName + ".xlsx");
response.setHeader("Cache-Control", "max-age=0");
response.setContentLength(excelBytes.length); // 设置Content-Length

// 将Excel字节数组写入响应
try (OutputStream out = response.getOutputStream()) {
    out.write(excelBytes);
    out.flush();
}

} catch (IOException e) {
e.printStackTrace();
}

方案2:遮罩层

html代码:

正在导出中...

css:

.loading-mask {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 9999;
display: flex;
justify-content: center;
align-items: center;
}

.loading-content {
text-align: center;
color: #fff;
}

.spinner {
border: 8px solid rgba(255, 255, 255, 0.3);
border-top: 8px solid #fff;
border-radius: 50%;
width: 60px;
height: 60px;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}

@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

button:disabled {
opacity: 0.6;
cursor: not-allowed;
}

js代码(阻止了有遮罩层时用户仍然可以通过键盘或其他方式触发多次点击):

$(document).ready(function () { // 确保DOM加载完成后执行
$(‘#export_btn’).on(‘click’, function (e) {
e.preventDefault(); // 阻止默认表单提交行为

    var $exportBtn = $(this);

    // 禁用导出按钮,防止重复点击
    $exportBtn.prop('disabled', true);

    // 显示遮罩层
    $('#loadingMask').show();

    // 获取表单数据并构建FormData对象
    var formData = $('#searchForm').serializeArray();
    var form = new FormData();

    $.each(formData, function () {
        form.append(this.name, this.value);
    });

    // 添加额外的参数
    form.append('publishFrom', '${RequestParameters.type}');

    // 创建XHR对象
    var xhr = new XMLHttpRequest();
    xhr.open('POST', '路径/exportData', true);
    xhr.responseType = 'blob'; // 设置响应类型为blob

    // 监听下载完成后处理
    xhr.onload = function () {
        $('#loadingMask').hide(); // 隐藏遮罩层
        $exportBtn.prop('disabled', false); // 启用导出按钮

        if (xhr.status === 200) {
            // 创建下载链接并触发下载
            var blob = xhr.response;
            var downloadUrl = URL.createObjectURL(blob);
            var a = document.createElement('a');
            a.href = downloadUrl;

            // 从响应头中获取文件名
            var disposition = xhr.getResponseHeader('Content-Disposition');
            var fileName = '下载文件.xlsx';
            if (disposition && disposition.indexOf("filename\*=utf-8''") !== -1) { // 修改:修正单引号字符
                var filenameRegex = /filename\*=utf-8''(.+)/;
                var matches = filenameRegex.exec(disposition);
                if (matches != null && matches\[1\]) {
                    fileName = decodeURIComponent(matches\[1\]);
                }
            }
            a.download = fileName;
            document.body.appendChild(a);
            a.click();
            document.body.removeChild(a);
            URL.revokeObjectURL(downloadUrl);
        } else {
            alert('下载失败,请重试。');
        }
    };

    // 监听网络错误
    xhr.onerror = function () {
        $('#loadingMask').hide(); // 隐藏遮罩层
        $exportBtn.prop('disabled', false); // 启用导出按钮
        alert('网络错误,请检查您的连接。');
    };

    xhr.send(form); 
});

});

后端代码和方案1一致

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/941485.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

新版Android Studio 2024.1.2版本,如何通过无线wifi连接手机实现交互

1、首先,先确定手机是否启动了开发者选项 在我的设备 -> 全部参数 -> MIUI版本点击6下 (有的手机是 关于手机 -> 查看手机版本 ) 2、在设置中搜索 开启开发者选项 3、进入开发者选项后,在 调试 中选择 无线调试并选择…

CEF127 编译指南 MacOS 篇 - 编译 CEF(六)

1. 引言 经过前面的准备工作,我们已经完成了所有必要的环境配置。本文将详细介绍如何在 macOS 系统上编译 CEF127。通过正确的编译命令和参数配置,我们将完成 CEF 的构建工作,最终生成可用的二进制文件。 2. 编译前准备 2.1 确认环境变量 …

扩散模型经典问题:在Image-to-Image或Image-to-Video任务中,如何尽可能地保持住原始输入Image的特征?

AIGC算法工程师 面试八股文 2025年版本 在Image-to-Image或Image-to-Video任务中,如何尽可能地保持住原始输入Image的特征?你知道有哪些经典方法?这些方法各有什么优缺点? 目录 经典条件扩散模型 垫图法 Adapter方法 ControlNet方法 UNet中的ReferenceNet DiT中的Re…

0.96寸OLED显示屏详解

我们之前讲了 LCD1602,今天我们将它的进阶模块——OLED。它接线更少,性能更强,也能显示中文和图像了。 大家在学习单片机的时候是否会遇到调试的问题呢?例如 “这串代码我到底运行成功了没有” ,我相信很多刚开始学习…

windows下VSCode配置C++/CMake/Qt开发环境

文章目录 1 windows下vscode配置C/CMake开发环境2 windows下配置qt开发环境(qmakemingw)3 windows下配置qt开发环境(cmakemingwmsvc) 更多精彩内容👉内容导航 👈👉Qt开发经验 👈&…

项目代码第6讲:UpdownController.cs;理解 工艺/工序 流程、机台信息;前端的“历史 警报/工艺 记录”

一、UpdownController.cs 1、前端传入 当用户在下图的“记录查询”中的 两个界面选项 中,点击“导出”功能时,向后端发起请求,请求服务器下载文件的权限 【权限是在Program.cs中检测的,这个控制器里只需要进行“谁在哪个接口下载了文件”的日志记录】 【导出:是用户把…

30多种独特艺术抽象液态酸性金属镀铬封面背景视觉纹理MOV视频素材

使用 Prismatic Flows 转换您的项目!这个包拥有 30 多种独特的液体背景和动画,为任何创意活动提供令人惊叹的视觉效果。 棱镜流 – 动画背景和迭加包括30多种不同的液体背景和动画。这些高质量的资源非常适合通过充满活力和动态的视觉效果来增强您的项目…

车载网关性能 --- 车载网关通用buffer分配需求

老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源,以现象替代逻辑,以情绪代替思考,把消极接受现实的懦弱,伪装成乐观面对不幸的豁达,往不幸上面喷“香水”来掩盖问题。 无人问津也好,技不…

PLSQL 客户端连接 Oracle 数据库配置

1. 安装Oracle客户端 首先,安装Oracle客户端。可以从Oracle官方网站下载Oracle Instant Client, 安装完成后,请记住安装路径,因为将在后续步骤中需要用到它。 2. 配置环境变量 添加环境变量 ORACLE_HOME 安装Oracle客户端后,配…

docker-harbor仓库的搭建(2024)

准备实验需要的软件 将软件拉入虚拟机中,解压压缩包 [rootlocalhost ~]# tar zxf harbor-offline-installer-v2.5.4.tgz 1.进入harbor目录拷贝文件,创建名为harbor.yml的备份文件 [rootlocalhost ~]# cd harbor/ [rootlocalhost harbor]# cp harbor.yml…

Jmeter分布式压力测试

1、场景 在做性能测试时,单台机器进行压测可能达不到预期结果。主要原因是单台机器压到一定程度会出现瓶颈。也有可能单机网卡跟不上造成结果偏差较大。 例如4C8G的window server机器,使用UI方式,最高压测在1800并发(RT 20ms以内)左右。如果…

Oracle下载安装(保姆级教学)

方法1 1. 官网下载安装包 对于 Oracle 软件的下载,建议通过官网免费下载,安全且有保证。 下载地址: https://www.oracle.com/database/technologies/oracle19c-windows-downloads.html 通过下载页面可以选择安装压缩包( WIND…

AOP 面向切面编程的实现原理

AOP是基于IOC的Bean加载来实现的,所以理解Spring AOP的初始化必须要先理解Spring IOC的初始化。然后就能找到初始化的流程和aop对应的handler,即parseCustomElement方法找到parse aop:aspectj-autoproxy的handler(org.springframework.aop.config.AopNam…

C# 范围判断函数

封装范围函数 public static class CommonUtil {/// <summary>/// 范围判断函数&#xff0c;检查给定的值是否在指定的最小值和最大值之间。/// 例如&#xff0c;可以用来判断当前日期是否在开始日期和结束日期之间。/// 该方法适用于任何实现了 IComparable 接口的类型…

搭建Elastic search群集

一、实验环境 二、实验步骤 Elasticsearch 是一个分布式、高扩展、高实时的搜索与数据分析引擎Elasticsearch目录文件&#xff1a; /etc/elasticsearch/elasticsearch.yml#配置文件 /etc/elasticsearch/jvm.options#java虚拟机 /etc/init.d/elasticsearch#服务启动脚本 /e…

0基础学前端-----CSS DAY5

0基础学前端-----CSS DAY5 视频参考&#xff1a;B站Pink老师 今天是CSS学习的第五天&#xff0c;今天开始的笔记对应Pink老师课程中的CSS第二天的内容。 本节重点&#xff1a;CSS的元素显示模式、三种元素显示模式的转换、CSS背景设置。 2. CSS的元素显示模式 2.1 什么是元素…

SMOOTHLLM Defending LLM Against Jailbreaking Attacks (1)

越狱llm 越狱攻击&#xff1a;通过设计输入 欺骗模型 生成不当内容。 上&#xff09;llm拒绝回应“告诉我如何制造炸弹”。 有毒内容的添加设计的后缀 后&#xff0c;对齐的llm可以被成功攻击&#xff0c;产生不好的响应。 越狱攻击-设计输入方式&#xff1a; 关键在于尽量…

基于springboot的健身俱乐部网站系统

博主介绍&#xff1a;java高级开发&#xff0c;从事互联网行业六年&#xff0c;熟悉各种主流语言&#xff0c;精通java、python、php、爬虫、web开发&#xff0c;已经做了多年的设计程序开发&#xff0c;开发过上千套设计程序&#xff0c;没有什么华丽的语言&#xff0c;只有实…

【H3CNE邓方鸣】IPv6+2024.12.23

文章目录 IPv4的问题IPv6的优势地址格式地址书写压缩网段划分地址分类单播地址组播地址任播地址 IPv6邻居发现协议IPv6地址自动配置 IPv4的问题 地址资源已经全部耗尽、终端用户配置不够简便&#xff0c;协议本身不具备安全性和QOS特性 IPv6的优势 几乎无尽的地址空间、终端…

基于微信小程序的短视频系统(SpringBoot)+文档

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…