您现在的位置是:首页 >学无止境 >vue3中Table导出Excel网站首页学无止境
vue3中Table导出Excel
简介vue3中Table导出Excel
项目中涉及到Table表格的很大概率会有需求是导出Excel,在项目中一般使用xlsx插件导出
思路
先来理一下实现这个需求的大纲
1. 首先是安装插件并使用
2. 获取到要导出的数据
3. 编写导出方法
4. 处理成xlsx插件接收的数据
5. 导出表格定制化
安装插件
npm install xlsx
npm install xlsx-js-style --save
npm install file-saver --save
npm install xlsx
npm install xlsx-js-style --save
npm install file-saver --save
import * as XLSX from ‘xlsx’ //导XLSX插件
import XLSXJSStyle from ‘xlsx-js-style’ //定制化XLSX的样式插件
import FileSaver from ‘file-saver’ //添加样式后需要用fileSaver到处(如果不使用xlsx-js-style可以直接 用xlsx的导出方法)
import * as XLSX from 'xlsx' //导XLSX插件
import XLSXJSStyle from 'xlsx-js-style' //定制化XLSX的样式插件
import FileSaver from 'file-saver' //添加样式后需要用fileSaver到处(如果不使用xlsx-js-style可以直接用xlsx的导出方法)
获取到要导出的数据
我项目中用的antdv 所以这里就不过多展示
编写导出方法
我们的项目需求中要求合并单元格,具体数据格式后面展示
/**
*
* @param tableData 要导出的数据(必填)
* @param columns 要导出的数据的表头(必填)因为是用的表格组件所以我这里直接传的就是table组件要求的columns
* @param name 导出文件名称默认为test
* @param sheetName
* @param merges 要合并行/列 格式为 [{s:{r:x,c:x},e:{}}]
*/
export function exportExcel(
tableData,
columns,
name = 'test',
sheetName = 'sheetName',
merges: any = [],
) {
/* convert state to workbook */
const data: any[] = []
const keyArray: any[] = columns.map((item) => item.key) //获取key
const titleArr: any[] = columns.map((item) => item.title) //获取表头
// keyArray为英文字段表头
tableData.forEach((item) => {
const arr: any[] = keyArray.map((key) => {
return item[key]
})
data.push(arr)
})
data.splice(0, 0, titleArr)
// data.split(0,0,keyArray,titleArr) 如果需要英文表头的话
console.log('data', data)
const ws: any = XLSX.utils.aoa_to_sheet(data)
const wb = XLSX.utils.book_new()
// 此处隐藏英文字段表头
// const wsrows = [{ hidden: true }]
// ws['!rows'] = wsrows // ws - worksheet
ws['!merges'] = merges
console.log(ws)
for (const key in ws) {
if (key != '!rows' && key != '!merges' && key != '!ref') {
ws[key].s = {
alignment: {
horizontal: 'center', //水平居中
vertical: 'center', //垂直居中
},
}
}
}
XLSX.utils.book_append_sheet(wb, ws, sheetName)
const wbout = XLSXJSStyle.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })
try {
FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), `${name}.xlsx`)
} catch (error) {}
}
处理成xlsx想要的数据
我们的数据中是一条数据里某个字段是数组形式,所以导出的时候要根据这个字段拆分成对应数据,然后再把重复的字段合并,我以我们项目中的字段为例了就,数据格式如下
[
{
createTime: '',
deviceID: '',
deviceSN: '',
firewallVersion: '',
lastActiveTime: '',
online: '',
productID: '',
productName: '',
projectList: [
{
projectAddress: '',
projectID: '',
projectName: '',
projectShortName: '',
},
],
},
]
//导出方法具体使用
function exportSelectFun() {
let tableData = JSON.parse(JSON.stringify(state.selectedRows))
let { arr, merges } = formatData(tableData, true) //拆分数据,以及处理合并单元格的数据
exportExcel(
arr,
[
{
title: '序号',
dataIndex: 'index',
key: 'index',
ellipsis: true,
},
...columns.filter((item) => item.key != 'operation'),
],
'智能终端设备列表',
'sheetName',
merges,
)
}
/**
*拆分数据以及处理数据
*target 目标数据
*flag 是否要拆分
*/
function formatData(target, flag = false) {
let arr: any[] = []
let merges: any[] = []
target.forEach((item, index) => {
let newArr = item.projectList.map((v) => {
let obj = {
...item,
...v,
index: index + 1,
}
obj.location = obj.projectAddress
if (flag) {
obj.monitorItemName = ''
obj.monitorPointName = ''
if (Array.isArray(obj.monitorPointList)) {
obj.monitorItemName = removeDuplicates(
obj.monitorPointList.map((point) => point.monitorItemName),
)?.join(',')
obj.monitorPointName = obj.monitorPointList
.map((point) => point.monitorPointName)
?.join(',')
}
}
return obj
})
//调用getMerges生成合并的数据
//这里用的取巧的办法
// 1.start传的是arr的长度,因为每次循环都会把拆分的数据重新添加到arr中所以我们start就用arr.length
// 2.end参数传的是newArr的长度,因为每次拆分好的数据是newArr 所以我要合并单元格的结束位置就是这个newArr,首次的时候newArr.length,之后就要变成arr.length+length了
if (arr.length == 0) {
merges.push(...getMerges(arr.length, newArr.length))
} else {
merges.push(...getMerges(arr.length, arr.length + newArr.length))
}
arr.push(...newArr)
})
return { arr, merges }
}
/*
* 处理合并单元格参数merges
* start 起始位置
* end 结束位置
* num 是要合并几列
*/
function getMerges(start, end, num = 5) {
let merges: any[] = []
start += 1 //因为合并的时候要去除表头所以start要+1
for (let index = 0; index < num; index++) {
merges.push({ s: { r: start, c: index }, e: { r: end, c: index } })
}
console.log(merges)
return merges
}
导出展示
结语
比较仓促的结束,因为要下班了,打工人从不加班哈哈哈哈
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。