需求:勾选行导出为excel表格(合并表头 )
一、安装插件
npm install --save file-saver xlsx
运行项目报如下警告的话 运行npm install xlsx@0.16.0 --save
来降低版本号(最初我安装的版本号是0.18.16的版本)再次运行项目就不会报如下警告了
二、新建一个excel.js文件
我存放的路径如下图(下面代码会引入此路径):
excel.js代码如下:
import { saveAs } from 'file-saver'
import XLSX from 'xlsx'
function generateArray(table) {
const out = []
const rows = table.querySelectorAll('tr')
const ranges = []
for (let R = 0; R < rows.length; ++R) {
const outRow = []
const row = rows[R]
const columns = row.querySelectorAll('td')
for (let C = 0; C < columns.length; ++C) {
const cell = columns[C]
let colspan = cell.getAttribute('colspan')
let rowspan = cell.getAttribute('rowspan')
let cellValue = cell.innerText
if (cellValue !== '' && cellValue === +cellValue) cellValue = +cellValue
ranges.forEach(function (range) {
if (
R >= range.s.r &&
R <= range.e.r &&
outRow.length >= range.s.c &&
outRow.length <= range.e.c
) {
for (let i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null)
}
})
if (rowspan || colspan) {
rowspan = rowspan || 1
colspan = colspan || 1
ranges.push({
s: {
r: R,
c: outRow.length,
},
e: {
r: R + rowspan - 1,
c: outRow.length + colspan - 1,
},
})
}
outRow.push(cellValue !== '' ? cellValue : null)
if (colspan) for (let k = 0; k < colspan - 1; ++k) outRow.push(null)
}
out.push(outRow)
}
return [out, ranges]
}
function datenum(v, date1904) {
if (date1904) v += 1462
const epoch = Date.parse(v)
return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000)
}
function sheet_from_array_of_arrays(data) {
const ws = {}
const range = {
s: {
c: 10000000,
r: 10000000,
},
e: {
c: 0,
r: 0,
},
}
for (let R = 0; R !== data.length; ++R) {
for (let C = 0; C !== data[R].length; ++C) {
if (range.s.r > R) range.s.r = R
if (range.s.c > C) range.s.c = C
if (range.e.r < R) range.e.r = R
if (range.e.c < C) range.e.c = C
const cell = {
v: data[R][C],
}
if (cell.v === null) continue
const cell_ref = XLSX.utils.encode_cell({
c: C,
r: R,
})
if (typeof cell.v === 'number') cell.t = 'n'
else if (typeof cell.v === 'boolean') cell.t = 'b'
else if (cell.v instanceof Date) {
cell.t = 'n'
cell.z = XLSX.SSF._table[14]
cell.v = datenum(cell.v)
} else cell.t = 's'
ws[cell_ref] = cell
}
}
if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range)
return ws
}
function Workbook() {
if (!(this instanceof Workbook)) return new Workbook()
this.SheetNames = []
this.Sheets = {}
}
function s2ab(s) {
const buf = new ArrayBuffer(s.length)
const view = new Uint8Array(buf)
for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
return buf
}
export function export_table_to_excel(id) {
const theTable = document.getElementById(id)
const oo = generateArray(theTable)
const ranges = oo[1]
const data = oo[0]
const ws_name = 'SheetJS'
const wb = new Workbook(),
ws = sheet_from_array_of_arrays(data)
ws['!merges'] = ranges
wb.SheetNames.push(ws_name)
wb.Sheets[ws_name] = ws
const wbout = XLSX.write(wb, {
bookType: 'xlsx',
bookSST: false,
type: 'binary',
})
saveAs(
new Blob([s2ab(wbout)], {
type: 'application/octet-stream',
}),
'test.xlsx'
)
}
export function export_json_to_excel({
multiHeader = [],
header,
data,
filename,
merges = [],
autoWidth = true,
bookType = 'xlsx',
} = {}) {
filename = filename || 'excel-list'
data = [...data]
data.unshift(header)
for (let i = multiHeader.length - 1; i > -1; i--) {
data.unshift(multiHeader[i])
}
const ws_name = 'SheetJS'
const wb = new Workbook(),
ws = sheet_from_array_of_arrays(data)
if (merges.length > 0) {
if (!ws['!merges']) ws['!merges'] = []
merges.forEach((item) => {
ws['!merges'].push(XLSX.utils.decode_range(item))
})
}
if (autoWidth) {
const colWidth = data.map((row) =>
row.map((val) => {
if (val === null) {
return {
wch: 10,
}
} else if (val.toString().charCodeAt(0) > 255) {
return {
wch: val.toString().length * 2,
}
} else {
return {
wch: val.toString().length,
}
}
})
)
const result = colWidth[0]
for (let i = 1; i < colWidth.length; i++) {
for (let j = 0; j < colWidth[i].length; j++) {
if (result[j]['wch'] < colWidth[i][j]['wch']) {
result[j]['wch'] = colWidth[i][j]['wch']
}
}
}
ws['!cols'] = result
}
wb.SheetNames.push(ws_name)
wb.Sheets[ws_name] = ws
const wbout = XLSX.write(wb, {
bookType: bookType,
bookSST: false,
type: 'binary',
})
saveAs(
new Blob([s2ab(wbout)], {
type: 'application/octet-stream',
}),
`${filename}.${bookType}`
)
}
上面代码中修改默认导出表格的名称
三、组件中引入使用
<template>
<div class="select-excel-container">
<el-form :inline="true">
<el-form-item>
<el-input v-model="filename" placeholder="请输出导出文件名称" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleDownload">
导出选中行
</el-button>
</el-form-item>
</el-form>
<el-table
ref="multipleTable"
border
:data="list"
@selection-change="handleSelectionChange"
>
<el-table-column align="center" type="selection" />
<el-table-column align="center" label="序号" width="55">
<template #default="{ $index }">
{{ $index + 1 }}
</template>
</el-table-column>
<el-table-column align="center" label="标题">
<template #default="{ row }">
{{ row.title }}
</template>
</el-table-column>
<el-table-column align="center" label="作者">
<template #default="{ row }">
<el-tag>{{ row.author }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="访问量" width="115">
<template #default="{ row }">
{{ row.pageViews }}
</template>
</el-table-column>
<el-table-column align="center" label="时间">
<template #default="{ row }">
<span>{{ row.datetime }}</span>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
name: "ExportSelectExcel",
data() {
return {
list: [
{
uuid: "3AAD8907-5Efb-9D3F-0219-8f80e67a5634",
id: "230000198507241209",
title: "Htqr",
description: "较无己文日需说事酸热由写来将两市细队。",
status: "published",
author: "贺娟",
datetime: "2010-09-29 07:43:20",
pageViews: 4179,
img:
"https://cdn.jsdelivr.net/gh/chuzhixin/image/table/vab-image-10.jpg",
switch: true,
percent: 90,
rate: 2,
percentage: 3,
},
{
uuid: "75E17e52-f7f5-CbB0-8DD5-Ef988cbe244D",
id: "820000202202052027",
title: "Nfxemhvce",
description: "集最度达边光设儿就管具七土维对多身。",
status: "draft",
author: "郝敏",
datetime: "1975-03-22 03:21:01",
pageViews: 3648,
img:
"https://cdn.jsdelivr.net/gh/chuzhixin/image/table/vab-image-25.jpg",
switch: true,
percent: 85,
rate: 3,
percentage: 36,
},
{
uuid: "d2f5cAE8-E1df-9997-918B-4C24cbCDbe82",
id: "460000199510077216",
title: "Dcpdyqjxpo",
description: "都际一这他派效政认治计百这。",
status: "published",
author: "乔超",
datetime: "2011-01-07 17:03:16",
pageViews: 3799,
img:
"https://cdn.jsdelivr.net/gh/chuzhixin/image/table/vab-image-3.jpg",
switch: true,
percent: 90,
rate: 2,
percentage: 87,
},
{
uuid: "daA2f356-1CAA-9FEA-DaE3-5ED6eFBd794C",
id: "630000200001199589",
title: "Hrhhzwj Drtf",
description: "第使道具所活交克小术表商认么。",
status: "draft",
author: "方磊",
datetime: "1990-03-07 20:29:11",
pageViews: 3816,
img:
"https://cdn.jsdelivr.net/gh/chuzhixin/image/table/vab-image-22.jpg",
switch: true,
percent: 90,
rate: 4,
percentage: 65,
},
{
uuid: "e989d59B-b2CE-33E9-2dFd-0B6e93EbadEB",
id: "520000201106102834",
title: "Kinltlj",
description: "方西严办政受定每组龙适老看同将。",
status: "draft",
author: "罗勇",
datetime: "1998-06-03 06:10:48",
pageViews: 322,
img:
"https://cdn.jsdelivr.net/gh/chuzhixin/image/table/vab-image-9.jpg",
switch: false,
percent: 82,
rate: 3,
percentage: 70,
},
{
uuid: "1DE3AEED-AFCC-bbf9-b5E8-C99e303Decdf",
id: "340000199509093035",
title: "Nhsfyt Ivuof",
description: "干导划此世由空单接马发型府头。",
status: "deleted",
author: "熊芳",
datetime: "1997-02-20 01:07:34",
pageViews: 1068,
img:
"https://cdn.jsdelivr.net/gh/chuzhixin/image/table/vab-image-28.jpg",
switch: false,
percent: 80,
rate: 3,
percentage: 35,
},
{
uuid: "fcE302cF-D71b-dAB6-c2D5-565efE1E8335",
id: "54000020161030747X",
title: "Wjomrsvy Gltuchp",
description: "外改也色入王表件回里把为且得。",
status: "published",
author: "卢秀英",
datetime: "2018-12-16 05:19:06",
pageViews: 2580,
img:
"https://cdn.jsdelivr.net/gh/chuzhixin/image/table/vab-image-10.jpg",
switch: true,
percent: 90,
rate: 3,
percentage: 90,
},
{
uuid: "8A868c6f-bAf6-A935-FbFC-DEAF2ad3EC3a",
id: "310000201202123580",
title: "Frmdpvb",
description: "般时将写中千该式备重见叫技。",
status: "deleted",
author: "孔涛",
datetime: "2012-10-10 04:59:24",
pageViews: 1969,
img:
"https://cdn.jsdelivr.net/gh/chuzhixin/image/table/vab-image-1.jpg",
switch: true,
percent: 87,
rate: 4,
percentage: 61,
},
],
multipleSelection: [],
downloadLoading: false,
filename: "",
};
},
created() {
},
methods: {
handleSelectionChange(val) {
this.multipleSelection = val;
},
handleDownload() {
if (this.multipleSelection.length) {
this.downloadLoading = true;
import("@/utils/excel").then((excel) => {
const multiHeader = [["Id", "Title", "", "", "Date","Description"]];
const tHeader = ["", "Title", "Author", "Readings", "","Description"];
const filterVal = ["id", "title", "author", "pageViews", "datetime","description"];
const list = this.multipleSelection;
const data = this.formatJson(filterVal, list);
const merges = ['A1:A2','B1:D1','E1:E2']
console.log(data);
console.log(list);
excel.export_json_to_excel({
multiHeader,
header: tHeader,
data,
filename: this.filename,
merges
});
this.$refs.multipleTable.clearSelection();
this.downloadLoading = false;
});
} else {
this.$message("请至少选择一行");
}
},
formatJson(filterVal, jsonData) {
return jsonData.map((v) => filterVal.map((j) => v[j]));
},
},
};
</script>
<style lang="less">
.select-excel-container {
margin-top: 50px;
}
</style>