我用的方法是在表格的根组件外层赋一个div用来导出整个表格,所以antdesignvue、elementui、vxetable 或者原生的table写法应该全都适用,此处我用的框架为antdesignvue,包含合并单元格与二级标题,先看最终样式以及导出的效果:

导出的excel:

首先要引入三个库:

npm install file-saver --save

npm install xlsx --save

npm install xlsx-style --save

vue 2.0版本xlsx-style ./cptable' 报错:Can't resolve './cptable' in 'xxxx\nautical-front\node_modules_xlsx

解决:在vue的config文件中加如下代码

'./cptable': 'var cptable'

为了防止代码一致却有运行错误的情况 这里再列出我开发时用的插件的版本号:

"file-saver": "^2.0.5",
"xlsx": "^0.17.0",
"xlsx-style": "^0.8.13"

全部安装好后引入插件:

import XLSX from "xlsx";
import XLSXStyle from "xlsx-style";
import FileSaver from "file-saver";

先根据不同的框架渲染好表格的页面,外层套一层div:

<template>
<a-card :bordered="false">
<a-button @click="exportToExcel" >导出</a-button>
<div id="exportData" class="css_page_body" ref="css_page_body">
<a-table :columns="columns"
:data-source="data"
bordered
:pagination="false">
</a-table> </div>
</a-card>
</template>

下面是导出的方法:

 exportToExcel () {
let ws = XLSX.utils.table_to_sheet(document.getElementById('exportData'))
let ws2 = XLSX.utils.table_to_sheet(document.getElementById('exportData'))
//创建一个workbook对象
let wb = XLSX.utils.book_new()
//把worksheet对象添加进workbook对象,第三个参数是excel中sheet的名字
XLSX.utils.book_append_sheet(wb, ws, '月度统计报表')
XLSX.utils.book_append_sheet(wb, ws2, '隔离库')
this.setExlStyle(wb['Sheets']['月度统计报表']); // 设置列宽 字号等 如果无需多余的样式则省略
this.addRangeBorder(wb['Sheets']['月度统计报表']['!merges'],wb['Sheets']['月度统计报表']) //设置合并行的border
let wb_out = XLSXStyle.write(wb, { type: 'buffer'}) try {
FileSaver.saveAs(new Blob([wb_out], {
type: 'application/octet-stream'
}), 'WMS统计报表.xlsx'); // 导出的文件名
} catch (e) {
console.log(e, wb_out) ;
}
return wb_out;
},
setExlStyle(data) {
let borderAll = { //单元格外侧框线
top: {
style: 'thin',
},
bottom: {
style: 'thin'
},
left: {
style: 'thin'
},
right: {
style: 'thin'
}
};
data['!cols'] = [];
for (let key in data) {
// console.log(key)
if (data[key] instanceof Object) {
data[key].s = {
border: borderAll,
alignment: {
horizontal: 'center', //水平居中对齐
vertical:'center'
},
font:{
sz:11
},
bold:true,
numFmt: 0
}
data['!cols'].push({wpx: 115});
}
}
return data;
},
addRangeBorder (range, ws) {
let cols = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
range.forEach(item => {
console.log(item)
let style = {
s: {
border: {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' }
}
}
}
// 处理合并行
for (let i = item.s.c; i <= item.e.c; i++) {
ws[`${cols[i]}${Number(item.e.r) + 1}`] = ws[`${cols[i]}${Number(item.e.r) + 1}`] || style
// 处理合并列
for (let k = item.s.r + 2; k <= item.e.r + 1; k++) {
ws[cols[i] + k] = ws[cols[k] + item.e.r] || style
}
}
})
return ws;
},

以上就是全部有关导出表格的内容,以下是全部的代码:

<template>
<a-card :bordered="false">
<a-button @click="exportToExcel" >导出</a-button>
<div id="exportData" class="css_page_body" ref="css_page_body">
<a-table :columns="columns"
:data-source="data"
bordered
:pagination="false">
</a-table> </div>
</a-card>
</template> <script>
import XLSX from "xlsx";
import XLSXStyle from "xlsx-style";
import FileSaver from "file-saver"; export default {
data () {
return {
columns:[
{
title: '学校', dataIndex: 'school', width: '25%',
scopedSlots: { customRender: 'school' }, align: 'center', key: 'school',
customRender (_, row) {
return {
children: row.school,
attrs: {
rowSpan: row.schoolRowSpan
}
}
}
},
{
title: '年级', dataIndex: 'grade', width: '25%',
scopedSlots: { customRender: 'grade' }, align: 'center', key: 'grade',
customRender (_, row) {
return {
children: row.grade,
attrs: {
rowSpan: row.gradeRowSpan
}
}
}
},
{
title: '班级', dataIndex: 'class', width: '25%',
scopedSlots: { customRender: 'class' }, align: 'center'
},
{
title: '姓名', dataIndex: 'name', width: '25%',
scopedSlots: { customRender: 'name' }, align: 'center'
},
{
title: '4月1日',
children: [
{
title: '周五',
dataIndex: 'companyAddress',
width: 100,
}
],
},
{
title: '4月1日',
children: [
{
title: '周五',
dataIndex: 'companyAddress2',
width: 100,
}
],
},
{
title: '4月1日',
children: [
{
title: '周五',
dataIndex: 'companyAddress3',
width: 100,
}
],
},
{
title: '4月1日',
children: [
{
title: '周五',
dataIndex: 'companyAddress4',
width: 100,
}
],
},
],
data:[ ]
}
},
methods: {
// 合并单元格
rowSpan (key, data) {
const arr = data
.reduce((result, item) => {
if (result.indexOf(item[key]) < 0) {
result.push(item[key])
}
return result
}, [])
.reduce((result, keys) => {
const children = data.filter(item => item[key] === keys)
result = result.concat(
children.map((item, index) => ({
...item,
[`${key}RowSpan`]: index === 0 ? children.length : 0
}))
)
return result
}, [])
return arr
},
// 表格合并
mergeRowCell (data) {
let tableData = this.rowSpan('school', data)
tableData = this.rowSpan('grade', tableData)
this.data = tableData },
exportToExcel () {
let ws = XLSX.utils.table_to_sheet(document.getElementById('exportData'))
let ws2 = XLSX.utils.table_to_sheet(document.getElementById('exportData'))
//创建一个workbook对象
let wb = XLSX.utils.book_new()
//把worksheet对象添加进workbook对象,第三个参数是excel中sheet的名字
XLSX.utils.book_append_sheet(wb, ws, '月度统计报表')
XLSX.utils.book_append_sheet(wb, ws2, '隔离库')
this.setExlStyle(wb['Sheets']['月度统计报表']); // 设置列宽 字号等
this.addRangeBorder(wb['Sheets']['月度统计报表']['!merges'],wb['Sheets']['月度统计报表'])
let wb_out = XLSXStyle.write(wb, { type: 'buffer'}) try {
FileSaver.saveAs(new Blob([wb_out], {
type: 'application/octet-stream'
}), 'WMS统计报表.xlsx'); //trade-publish.xlsx 为导出的文件名
} catch (e) {
console.log(e, wb_out) ;
}
return wb_out;
},
setExlStyle(data) {
let borderAll = { //单元格外侧框线
top: {
style: 'thin',
},
bottom: {
style: 'thin'
},
left: {
style: 'thin'
},
right: {
style: 'thin'
}
};
data['!cols'] = [];
for (let key in data) {
// console.log(key)
if (data[key] instanceof Object) {
data[key].s = {
border: borderAll,
alignment: {
horizontal: 'center', //水平居中对齐
vertical:'center'
},
font:{
sz:11
},
bold:true,
numFmt: 0
}
data['!cols'].push({wpx: 115});
}
}
return data;
},
addRangeBorder (range, ws) {
let cols = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
range.forEach(item => {
console.log(item)
let style = {
s: {
border: {
top: { style: 'thin' },
left: { style: 'thin' },
bottom: { style: 'thin' },
right: { style: 'thin' }
}
}
}
// 处理合并行
for (let i = item.s.c; i <= item.e.c; i++) {
ws[`${cols[i]}${Number(item.e.r) + 1}`] = ws[`${cols[i]}${Number(item.e.r) + 1}`] || style
// 处理合并列
for (let k = item.s.r + 2; k <= item.e.r + 1; k++) {
ws[cols[i] + k] = ws[cols[k] + item.e.r] || style
}
}
})
return ws;
},
},
mounted() {
this.data = []
for(let i=0;i<4;i++){
this.data.push( { school: '林州一中', grade: '高一', class: '二班', name: '徐强' } )
this.data.push( { school: '林州二中', grade: '高三', class: '一班', name: '徐强子' } )
}
this.mergeRowCell(this.data)
}
}
</script> <style lang="less" scoped>
</style>

参考的文章:

vue table复杂表格导出excel(支持多表头、合并单元格、边框、居中、背景等自定义样式)

前端复杂表格导出excel,一键导出 Antd Table 看这篇就够了(附源码)

vue页面table导出excel

vue导出Excel表格,utils未定义是版本原因

js xlsx使用说明(主要讲导出表格与设置表头相关)

XLSX-STYLE 的用法

JavaScript导出excel文件,并修改文件样式

最新文章

  1. Linux下的压缩和解压缩命令——zip/unzip
  2. HTML3
  3. BUG等级和严重等级关系
  4. 浅谈mybatis中的#和$的区别
  5. NHibernate Demo 和 效率测试
  6. TYVJ P1083 分糖果 Label:bfs
  7. Notepad++前端开发常用插件介绍 - BorisHuai前端修炼 - 博客频道 - CSDN
  8. jdk 1.5新特性说明
  9. tcp_tw_recycle和tcp_timestamps的文章汇总
  10. C程序第二章节:算法
  11. 数据泵导出/导入Expdp/impdp
  12. 原生js实现简单的全屏滚动
  13. Spring Boot 正常启动后访问Controller提示404
  14. RobotFramework + Appium 移动自动化实现
  15. Spring配置中的&quot;classpath:&quot;与&quot;classpath*:&quot;的区别研究(转)
  16. EF code first出现错误:列名 Discriminator 无效
  17. Cocos2d-x中文显示乱码
  18. springboot解决跨域问题
  19. P1019 单词接龙 字符串回溯
  20. [luogu P3216] [HNOI2011]数学作业

热门文章

  1. 【深入浅出 Yarn 架构与实现】4-2 RM 管理 Application Master
  2. CTFshow——funnyrsa1的wp理解
  3. MyBatis四大参数两种写法
  4. Spring中使用@RequestBody注解接收的实体类中的某些参数为null
  5. Kali Win-KeX Win
  6. IT编程相关内容汇总 - 进阶者系列 - 学习者系列文章
  7. mysql基础命令语法
  8. DLL的两种加载方式
  9. 视图,触发器,存储过程,流程控制等MySQL小知识点
  10. 基于APIView写接口