前端万级数据量表格预览及前端导出Excel方案组件封装(基于vxetable虚拟滚动和web worker)
Posted Sure小硕
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端万级数据量表格预览及前端导出Excel方案组件封装(基于vxetable虚拟滚动和web worker)相关的知识,希望对你有一定的参考价值。
如题,本文主要解决前端展示渲染大数据量table数据及导出Excel的问题,主要是通过使用v3版本的vxetable和webworker来实现的。亲测可以表格可渲染30w条数据,可在10s内导出30w条数据Excel。
框架:vue2;
一、安装vxetable
可参考官网:https://vxetable.cn/v3/#/table/start/use
- 安装按需加载的插件
npm install babel-plugin-import -D
- 修改文件 .babelrc 或 babel.config.js
"plugins": [
[
"import",
"libraryName": "vxe-table",
"style": true // 样式是否也按需加载
]
]
3. main.js中全局按需引入模块
import VXETable, Icon, Column, Table from 'vxe-table'
Vue.use(Icon).use(Column).use(Table).use(VXETable)
这样VXETable就已经在项目中安装注册完成,接下来进行安装vue-worker
二、安装vue-worker
- 首先安装vue-worker插件;
npm install vue-worker -S
- 在main.js中引入
import VueWorker from 'vue-worker'
Vue.use(VueWorker)
- 引入导出XLSX的包
这里有两种方式
第一种方式:在web worker中使用XLSX的外部CDN链接
importScripts('https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.15.3/xlsx.core.min.js')
然后就可以在web worker中全局使用XLSX了
第二张方式:将上面👆包的js链接下载到本地,放到项目的public文件夹下,可以再建一个workers文件夹存放,如下
然后再web worker中使用
//importScripts('https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.15.3/xlsx.core.min.js')
importScripts(location.origin + '/workers/xlsx.core.min.js')
//因为woker中是有loaction变量的,所以可以通过服务器的绝对路径进行访问,以获得XLSX。
const ws = XLSX.utils.aoa_to_sheet(data)
三、封装相应的table组件
下面是我封装的组件,如果是使用elementUI可以直接引入,若没有使用可以把elementUi相关标签删除替换即可。
vxe-table的Api文档:https://vxetable.cn/v3/#/table/api
组件传参说明:仅有两个参数
rowList | 行记录数据 |
---|---|
colList | 列记录数据 |
<result-table :rowList="rowList" :colList="colList"> </result-table>
<template>
<div style="height: 100%">
<div style="display: flex; justify-content: flex-end">
<el-pagination
background
layout="sizes,prev, pager, next,total"
:page-sizes="[10, 50, 100, 500, 1000]"
:current-page="currentPageNum"
:page-size="currentPageSize"
:total="rowListTotal"
@current-change="currentChange"
@size-change="handleSizeChange"
>
</el-pagination>
<el-button
type="primary"
@click="handleLargeDataExport"
size="small"
icon="el-icon-download"
style="z-index: 99; margin-right: 10px"
>导出全部</el-button
>
</div>
<div style="height: calc(100% - 80px); padding: 5px 10px">
<vxe-table
border
ref="xTable1"
height="100%"
empty-text="暂无数据"
show-overflow="title"
style="overflow: visible"
show-header-overflow
:row-config=" isHover: true "
:tooltip-config=" showAll: true "
>
<vxe-column
v-for="item in colList"
:field="item.name"
:resizable="true"
min-width="120"
:title="item.name"
:key="item.name"
></vxe-column>
</vxe-table>
</div>
</div>
</template>
<script>
export default
data()
return
currentList: [], //当前页数据
currentPageNum: 1, //当前页码
currentPageSize: 50, //当前页尺寸
rowListTotal: 0 //结果总条数
,
props:
//行数据
rowList:
type: Array,
default: []
,
// 列数据
colList:
type: Array,
default: []
,
created() ,
watch:
rowList:
handler(newVal, oldVal)
console.log('rowListHandle')
this.rowListTotal = newVal.length
this.currentList = newVal.slice(0, this.currentPageSize)
this.currentPageNum = 1
,
immediate: true
,
currentList:
handler(newVal, oldVal)
console.log('currentListHandle')
this.$refs.xTable1.loadData(newVal)
,
methods:
//当前页尺寸改变
handleSizeChange(pageSize)
this.currentPageSize = pageSize
this.currentList = this.rowList.slice(
(this.currentPageNum - 1) * this.currentPageSize,
this.currentPageNum * this.currentPageSize
)
,
// 当前页码改变
currentChange(pageNum)
this.currentPageNum = pageNum
this.currentList = this.rowList.slice(
(this.currentPageNum - 1) * this.currentPageSize,
this.currentPageNum * this.currentPageSize
)
,
// 全部结果导出
handleLargeDataExport()
let handleData = this.rowList
if (handleData.length == 0)
return this.$message('暂无数据!')
this.$message('正在导出,请稍后...')
this.$worker
.run(
(handleData) =>
// console.time('handelExcel')
let data = handleData.map((item, index) =>
let tempArr = []
for (let itemKey in item)
tempArr.push(item[itemKey])
return tempArr
)
let keyArr = []
for (let itemKey in handleData[0])
keyArr.push(itemKey)
data.unshift(keyArr)
importScripts(location.origin + '/workers/xlsx.core.min.js')
// importScripts('https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.15.3/xlsx.core.min.js')
const ws = XLSX.utils.aoa_to_sheet(data)
const wb = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(wb, ws, 'data')
const buf = XLSX.write(wb, type: 'array', bookType: 'xlsx' )
// console.timeEnd('handelExcel')
return buf
,
[handleData]
)
.then((res) =>
this.$message(
message: '已生成文件!',
type: 'success',
duration: 2000
)
const url = window.URL.createObjectURL(new Blob([res]))
const link = document.createElement('a')
link.href = url
link.download = `全部结果_$new Date().getTime().xlsx`
link.click()
)
.catch((err) =>
console.log(err)
)
</script>
以上是关于前端万级数据量表格预览及前端导出Excel方案组件封装(基于vxetable虚拟滚动和web worker)的主要内容,如果未能解决你的问题,请参考以下文章
基于Vue + axios + WebApi + NPOI导出Excel文件