vue+xlsx实现表格导出进度提示功能
作者:^Rocky
这篇文章主要为大家详细介绍了vue如何结合ant-design和xlsx 实现表格导出进度提示功能,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下
引言
在处理大数据量(10万+条)表格导出时,常面临以下问题:
- 浏览器卡顿无响应
- 导出进度不可见
- 导出失败无反馈
本文将深度扩展以下功能:
- 分片数据加载机制
- 实时进度可视化
- 异常中断处理
- 性能优化策略
通过Ant Design Vue的Progress组件与自定义Hook,打造企业级导出体验。
一、进度提示核心原理
1.1 分片加载模型
数据总量 → 分片大小 → 当前分片 → 进度百分比
↑ ↑ ↑
100,000条 5,000条/片 20次迭代
1.2 异步处理流程
二、完整实现方案
2.1 进度条组件集成
<template> <a-modal v-model:open="exportVisible" :footer="null"> <a-progress :percent="progress" status="active" /> <div style="margin-top: 16px"> {{ progress }}% 完成 | 当前处理:{{ currentChunk }} / {{ totalChunks }} 分片 </div> </a-modal> </template> <script setup> import { ref } from 'vue' const exportVisible = ref(false) const progress = ref(0) const currentChunk = ref(0) const totalChunks = ref(0) </script>
2.2 核心导出Hook(useExportProgress)
import { ref } from 'vue' import * as XLSX from 'xlsx/xlsx.mjs' import { saveAs } from 'file-saver' export const useExportProgress = () => { const isExporting = ref(false) const progress = ref(0) let workbook = null let worksheet = null const initWorkbook = () => { workbook = XLSX.utils.book_new() worksheet = XLSX.utils.aoa_to_sheet([]) XLSX.utils.book_append_sheet(workbook, worksheet, '大数据报表') } const exportData = async (config) => { return new Promise(async (resolve, reject) => { try { isExporting.value = true initWorkbook() const { chunkSize, total, fetchData } = config const totalChunks = Math.ceil(total / chunkSize) for (let i = 0; i < totalChunks; i++) { const data = await fetchData(i, chunkSize) appendData(data) updateProgress(i, totalChunks) } const blob = generateFile() saveAs(blob, '大数据报表.xlsx') resolve() } catch (error) { reject(error) } finally { isExporting.value = false resetState() } }) } const appendData = (data) => { const startRow = worksheet['!ref'] ? worksheet['!ref'].split(':')[1].replace(/[^0-9]/g, '') + 1 : 1 XLSX.utils.sheet_add_json(worksheet, data, { origin: startRow, skipHeader: true }) } const updateProgress = (current, total) => { progress.value = Math.round((current / total) * 100) } const generateFile = () => { return new Blob([XLSX.write(workbook, { bookType: 'xlsx', type: 'array' })], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }) } const resetState = () => { workbook = null worksheet = null progress.value = 0 } return { isExporting, progress, exportData } }
2.3 调用示例
<script setup> import { useExportProgress } from './hooks/useExportProgress' const { isExporting, progress, exportData } = useExportProgress() // 模拟分片数据获取 const fetchDataChunk = async (page, pageSize) => { const start = page * pageSize const end = start + pageSize return new Promise(resolve => { setTimeout(() => { const mockData = Array.from({ length: pageSize }, (_, i) => ({ id: start + i + 1, value: Math.random().toFixed(4) })) resolve(mockData) }, 50) }) } const handleExport = async () => { try { await exportData({ chunkSize: 5000, total: 100000, fetchData: fetchDataChunk }) } catch (error) { console.error('导出失败:', error) } } </script>
三、性能优化策略
3.1 内存管理优化
// 修改appendData方法 const appendData = (data) => { // 每次处理后释放内存 const tempData = [...data] XLSX.utils.sheet_add_json(worksheet, tempData, { origin: -1, skipHeader: true }) tempData.length = 0 // 手动GC }
3.2 Web Worker方案
// worker.js self.onmessage = async (e) => { const { config, chunkIndex } = e.data const data = await config.fetchData(chunkIndex, config.chunkSize) self.postMessage({ chunkIndex, data }) } // 主线程调用 const worker = new Worker('./worker.js') worker.postMessage({ config, chunkIndex: i })
3.3 虚拟滚动优化
// 分片加载时动态创建Worksheet if (i === 0) { XLSX.utils.book_append_sheet(workbook, worksheet, '数据分片1') } else { const newSheet = XLSX.utils.aoa_to_sheet([]) XLSX.utils.book_append_sheet(workbook, newSheet, `数据分片${i+1}`) }
四、异常处理方案
4.1 断点续传实现
// 添加本地存储 const saveProgress = (current) => { localStorage.setItem('exportProgress', JSON.stringify({ currentChunk: current, timestamp: Date.now() })) } // 启动时检查 const checkResume = () => { const saved = localStorage.getItem('exportProgress') if (saved && Date.now() - saved.timestamp < 300000) { return JSON.parse(saved).currentChunk } return 0 }
4.2 错误边界处理
<template> <ErrorBoundary @error="handleError"> <YourExportComponent /> </ErrorBoundary> </template> <script setup> const handleError = (error) => { console.error('捕获到导出错误:', error) // 发送错误日志到服务端 } </script>
五、生产级增强建议
导出日志记录:记录每次导出的关键指标(耗时、数据量、异常)
权限校验:在exportData方法前添加Token验证
格式预设:预先定义单元格样式模板
多格式支持:扩展CSV/PDF导出选项
总结
通过本文实现的进度提示方案,可获得以下提升:
- 用户体验:实时反馈增强操作信心
- 系统稳定性:分片加载降低内存压力
- 可维护性:Hook封装提高代码复用
- 错误可追溯:完善的异常处理机制
到此这篇关于vue+xlsx实现表格导出进度提示功能的文章就介绍到这了,更多相关vue表格导出内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!