感谢@robin给出的思路和建议。
vue2 导出Excel
注意xlsx-style0.8.13报错需处理
在\node_modules\xlsx-style\dist\cpexcel.js
var cpt = require('./cpt' + 'able'); 改为 var cpt = cptable;
配置页面:
<el-table
ref="report-table">
....
</el-table>
import FileSaver from 'file-saver';
import XLSXS from "xlsx-style";
import * as XLSX from 'xlsx';
export default {
data() {
return {
// 表格
table: {
loading: false,
loadingText: '',
data: [],
total: 0,
}
};
},
created() {
this.init();
},
methods: {
/** 导出按钮操作 */
handleExport(excelName) {
this.table.loading = true;
this.table.loadingText = '导出中,请稍后....';
setTimeout(() => {
try {
const $e = this.$refs['report-table'].$el;
let $table = $e.querySelector('.el-table__fixed');
if(!$table) {
$table = $e;
}
let wb = XLSX.utils.table_to_book($table, {raw:true});
this.xlsxStyle(wb);
var ws = XLSXS.write(wb, {
type: "buffer",
});
// const wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST:true, type: 'array'});
FileSaver.saveAs(
new Blob([ws],{type: 'application/octet-stream'}),
`${excelName}.xlsx`,
)
} catch (e) {
if (typeof console !== 'undefined') console.error(e);
}
this.table.loading = false;
this.table.loadingText = '';
}, 1000);
},
xlsxStyle(wb) {
let ws = wb.Sheets["Sheet1"];
for (let key in ws) {
// console.log(key, ws[key])
const num = key.slice(1, key.length);
// 表头
if (num === '1' && ws[key].t !== 'z') {
// 注意:border未开启,如果开启,在跨行、跨列的情况下会出现少边框的问题。
ws[key].s = {
font: { //字体相关样式
name: '宋体', //字体类型
sz: 11, //字体大小
color: { rgb: '' }, //字体颜色
bold: true, //是否加粗
},
// border: {
// top: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// left: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// right: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// bottom: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// },
alignment: {
/// 自动换行
wrapText: 1,
// 居中
horizontal: "center",
vertical: "center",
indent: 0
}
}
} else {
// 所有表格
if (key !== '!rows' && key !== '!cols' && key !== '!ref' && key !== '!fullref' && ws[key].t !== 'z') {
ws[key].s = {
font: {
//字体相关样式
name: "宋体", //字体类型
sz: 11, //字体大小
color: { rgb: "" }, //字体颜色
},
// border: {
// top: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// left: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// right: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// bottom: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// },
alignment: {
/// 自动换行
wrapText: 1,
// 居中
horizontal: "center",
vertical: "center",
indent: 0,
},
};
}
}
}
},
},
};
目前满足复杂表格的需求,只要el-table能画出来的表格,导出格式都没问题。
唯一的问题是,导出的表格,单元格字体样式修改未成功(已解决)。
单元格样式能够修改,使用xlsx-style插件。
vue3 导出Excel
配置页面:
<el-table
ref="report-table">
....
</el-table>
xlsx 0.18.5
xlsx-style-vite 0.0.2(npm官网的说明不好看,可以参考xlsx-style的,类似。)
FileSaver 0.10.0
import FileSaver from 'file-saver';
import XLSXS from "xlsx-style-vite";
import * as XLSX from 'xlsx';
export default {
data() {
return {
// 表格
table: {
loading: false,
loadingText: '',
data: [],
}
};
}
}
/** 导出按钮操作 */
handleExport2(excelName) {
this.table.loading = true;
this.table.loadingText = '导出中,请稍后....';
setTimeout(() => {
try {
const $e = this.$refs['report-table'].$el;
let $table = $e.querySelector('.el-table__fixed');
if(!$table) {
$table = $e;
}
let wb = XLSX.utils.table_to_book($table, {raw:true});
this.xlsxStyle(wb);
var ws = XLSXS.write(wb, { bookType:'xlsx', bookSST:false, type:'binary' });
// const wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST:true, type: 'array'});
FileSaver.saveAs(
new Blob([this.s2ab(ws)],{type:""}),
// new Blob([ws],{type: 'application/octet-stream'}),
`${excelName}.xlsx`,
)
} catch (e) {
if (typeof console !== 'undefined') console.error(e);
}
this.table.loading = false;
this.table.loadingText = '';
}, 1000);
},
s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
},
xlsxStyle(wb) {
let ws = wb.Sheets["Sheet1"];
for (let key in ws) {
// console.log(key, ws[key])
ws['!cols'].wpx = ['14', 100, '200', 200];
const num = key.slice(1, key.length);
// 表头
if (num === '1' && ws[key].t !== 'z') {
// 注意:border未开启,如果开启,在跨行、跨列的情况下会出现少边框的问题。
ws[key].s = {
font: { //字体相关样式
name: '宋体', //字体类型
sz: '11', //字体大小
color: { rgb: '' }, //字体颜色
bgColor: { rgb: 'e7e2e200' }, //字体颜色
bold: true, //是否加粗
},
// border: {
// top: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// left: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// right: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// bottom: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// },
alignment: {
/// 自动换行
wrapText: 1,
// 居中
horizontal: "center",
vertical: "center",
indent: 0
}
}
} else {
// 所有表格
if (key !== '!rows' && key !== '!cols' && key !== '!ref' && key !== '!fullref' && ws[key].t !== 'z') {
ws[key].s = {
font: {
//字体相关样式
name: "宋体", //字体类型
sz: '10', //字体大小
color: { rgb: "" }, //字体颜色
},
// border: {
// top: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// left: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// right: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// bottom: {
// style: "thin",
// color: {
// auto: 1,
// },
// },
// },
alignment: {
/// 自动换行
wrapText: 1,
// 居中
horizontal: "center",
vertical: "center",
indent: 0,
},
};
}
}
}
},
问题:
1.列宽设置失败;
2.表头背景设置失败。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。