跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Layui表格怎么实现点击导出按钮后显示自定义的进度条

应放弃table.exportFile,手写导出逻辑:获取数据与列配置→手动显示进度条→分片处理+requestIdleCallback更新进度→CSV转义→Blob构造→a标签触发下载。 导出时进度条不显示?先确认是否在异步操作中更新了 DOM layui 的
table.exportFile
是同步触发下载的,它不会等待数据准备完成,更不会提供导出过程中的进度回调。所以直接调用它,根本没机会插入进度条逻辑——你看到的“没反应”,其实是导出瞬间完成(小数据)或浏览器直接接管(大数据),DOM 根本来不及渲染。 真正可行的路径是:**放弃
table.exportFile
,自己手写导出逻辑,把数据获取、格式化、Blob 构建、a 标签触发下载拆成可控步骤,并在其中插入进度提示。** 用
table.getData('yourTableId')
或
table.cache['yourTableId']
拿原始数据(注意分页情况,需判断是否要导出全部) 用
table.config['yourTableId'].cols
获取列配置,提取
field
和
title
用于生成表头 导出前手动显示一个带
layui.layer
或纯 DOM 的进度条容器,比如
避免阻塞主线程:大数据量时,用
setTimeout
分块处理行数据,每处理一批就更新一次进度宽度 怎么用原生 JS + layui layer 做轻量级进度条 不用引入额外 UI 库,用
layer.open
弹一个无标题、无按钮、仅含进度条的浮层最稳妥。关键点在于 layer 实例必须保留引用,才能后续更新内容。
let progressLayer = layer.open({ type: 1, title: false, closeBtn: 0, shade: 0.3, area: ['300px', '80px'], content: '
正在导出...
' }); // 后续用 document.getElementById('progress-fill').style.width = '50%';
务必给
progress-fill
加
transition
,否则宽度变化会突兀 layer 默认关闭动画可能干扰进度感知,可加
anim: -1
关闭动画 导出完成或失败后,必须显式调用
layer.close(progressLayer)
,否则浮层残留 如果导出逻辑里用了
Promise
或
async/await
,记得在
catch
块里也关闭 layer 并提示错误 大数据量导出卡死?必须分片 + requestIdleCallback 当表格有上万行,一次性拼 CSV 字符串会让浏览器卡顿甚至崩溃。不能只靠 setTimeout 削峰,得结合浏览器空闲时间调度。 基于Layui自定义内容轮播插件 基于Layui自定义内容轮播插件是一款表格数据为ajax加载的本地json数据,本地查看会有跨域问题导致数据不能显示。 下载 把全部数据按每 500 行切片,用
requestIdleCallback
逐片处理并更新进度,兼容性差时降级为
setTimeout(..., 0)
CSV 转义别硬拼:字段含逗号、换行、双引号时,必须用双引号包裹,且内部双引号要转义为两个双引号(
"
→
""
),否则 Excel 打开会错乱 最终 Blob 构造要用
new Blob([csvString], {type: 'text/csv;charset=utf-8;'})
,charset 不加可能导致中文乱码 触发下载别用
window.location
,用
URL.createObjectURL(blob)
+
a.download
+
a.click()
,更可靠 为什么不能监听
table.exportFile
的底层行为 因为 layui 的
exportFile
内部是直接调用
location.href = 'data:text/csv;base64,...'
或创建隐藏 form 提交,全程不暴露任何钩子函数,也没有事件广播机制。你无法拦截、无法 await、无法注入中间状态。 有人试图重写
layui.table.exportFile
方法,但该方法是闭包内私有函数,外部覆盖无效;也有人想监听
beforeunload
,但那是页面卸载事件,和导出进度无关,且现代浏览器已限制其使用。 真正需要进度反馈的场景,从来都不是“调个 API 就完事”,而是你清楚知道数据在哪、有多大、怎么转、何时结束——这些信息,只有你自己掌控导出流程时才拿得到。

相关文章