安装xlsx插件
代码语言:javascript复制npm install --save xlsx file-saver
开始实现步骤
引入xlsx
代码语言:javascript复制 import FileSaver from 'file-saver'
import XLSX from 'xlsx'
封装导出表格组件
代码语言:javascript复制<template>
<transition name="fadeIn" >
<div v-show='false'>
<el-table
:id="exportExcelInfo.excelId"
:data="tableDatas"
highlight-current-row style="width: 100%"
>
<template v-for="(item,index) in exportExcelArry">
<el-table-column v-if="!item.formatterFlag" :prop="item.prop" :label="item.label">
</el-table-column>
<el-table-column v-else :prop="item.prop" :label="item.label">
<template slot-scope="scope">
<span>{{formatter(scope.row[item.prop],item,scope.row,item.prop)}}</span>
</template>
</el-table-column>
</template>
</el-table>
</div>
</transition>
</template>
<script>
import FileSaver from 'file-saver'
import XLSX from 'xlsx'
export default {
name: 'ExportExcelCommon',
props: {
exportExcelInfo: {
type: Object,
default: {}
},
exportExcelArry: {
type: Array,
default: []
},
tableData: {
type: Array,
default: []
},
},
data(){
return {
dataItem:{},
tableDatas:this.tableData //通过data, 定义新变量currentSearch, 这样currentSearch的值变更时,不会影响父组件传来的search的值
}
},
watch:{
tableData:function(newList){
this.tableDatas = newList;
}
},
methods: {
//excel导出全部 合并sheet
exportOutAllByOrder(row) {
var xlsxParam = {
raw: true
} // 导出的内容只做解析,不进行格式转换
var workbook = XLSX.utils.book_new();
const allData2 = [];
for (var i = 0; i < row.length; i ) {
for (var j = 0; j < row[i].detaildata.length; j ) {
this.dataItem = row[i].detaildata[j];
delete this.dataItem.orderid;
this.dataItem.username = row[i].username
allData2.push(this.dataItem);
}
}
//展示的顺序,把data中对象的属性按照你想要的顺序排放就可以了,我这里把id移到了第一列展示
const header3 = ["username", "datetime", "ordername", "product", "linename", "procedureid","procedurename","number","price","s_total"];
//展示的名称
const headerDisplay3 = {username:"员工", datetime:"日期", ordername:"订单", product:"产品", linename:"线别", procedureid:"工序号", procedurename:"工序名", number:"数量", price:"单价", s_total:"总金额"};
//将表头放到原始数据里面去,要保证表头在数组的最前面
const newData3 = [headerDisplay3, ...allData2];
//加了一句skipHeader:true,这样就会忽略原来的表头
// let ws = XLSX.utils.table_to_sheet(document.querySelector('#' this.exportExcelInfo.excelId), xlsxParam);
let ws = XLSX.utils.json_to_sheet(newData3, {header:header3, skipHeader:true});
// 这里可以添加多个sheet页
XLSX.utils.book_append_sheet(workbook, ws, "总表");
for (var i = 0; i < row.length; i ) {
this.tableDatas = row[i].detaildata;
for (var j = 0; j < this.tableDatas.length; j ) {
delete this.tableDatas[j].username;
}
if(this.tableDatas != null){
//展示的顺序,把data中对象的属性按照你想要的顺序排放就可以了,我这里把id移到了第一列展示
const header = ["datetime", "ordername", "product", "linename", "procedureid","procedurename","number","price","s_total"];
//展示的名称
const headerDisplay = {datetime:"日期", ordername:"订单", product:"产品", linename:"线别", procedureid:"工序号", procedurename:"工序名", number:"数量", price:"单价", s_total:"总金额"};
//将表头放到原始数据里面去,要保证表头在数组的最前面
const newData = [headerDisplay, ...this.tableDatas];
//加了一句skipHeader:true,这样就会忽略原来的表头
// let ws = XLSX.utils.table_to_sheet(document.querySelector('#' this.exportExcelInfo.excelId), xlsxParam);
let ws = XLSX.utils.json_to_sheet(newData, {header:header, skipHeader:true});
// 这里可以添加多个sheet页
XLSX.utils.book_append_sheet(workbook, ws, row[i].username);
}
}
var wbout = XLSX.write(workbook, {
bookType: 'xlsx',
bookSST: true,
type: 'array'
})
try {
FileSaver.saveAs(new Blob([wbout], {
type: 'application/octet-stream'
}), this.exportExcelInfo.excelName)
} catch (e) {
if (typeof console !== 'undefined') console.log(e, wbout)
}
return wbout
},
//excel导出全部 合并sheet
exportOutAll(row) {
var xlsxParam = {
raw: true
} // 导出的内容只做解析,不进行格式转换
var workbook = XLSX.utils.book_new();
// 拼接总表需要的数据
const allData = [];
for (var i = 0; i < row.length; i ) {
for (var j = 0; j < row[i].detaildata.length; j ) {
this.dataItem = row[i].detaildata[j];
delete this.dataItem.orderid;
this.dataItem.username = row[i].username
allData.push(this.dataItem);
}
}
//展示的顺序,把data中对象的属性按照你想要的顺序排放就可以了,我这里把id移到了第一列展示
const header2 = ["username", "datetime", "ordername", "product", "linename", "procedureid","procedurename","number","price","s_total"];
//展示的名称
const headerDisplay2 = {username:"员工", datetime:"日期", ordername:"订单", product:"产品", linename:"线别", procedureid:"工序号", procedurename:"工序名", number:"数量", price:"单价", s_total:"总金额"};
//将表头放到原始数据里面去,要保证表头在数组的最前面
const newData2 = [headerDisplay2, ...allData];
//加了一句skipHeader:true,这样就会忽略原来的表头
// let ws = XLSX.utils.table_to_sheet(document.querySelector('#' this.exportExcelInfo.excelId), xlsxParam);
let ws = XLSX.utils.json_to_sheet(newData2, {header:header2, skipHeader:true});
// 这里可以添加多个sheet页
XLSX.utils.book_append_sheet(workbook, ws, "总表");
for (var i = 0; i < row.length; i ) {
this.tableDatas = row[i].detaildata;
for (var j = 0; j < this.tableDatas.length; j ) {
delete this.tableDatas[j].username;
}
if(this.tableDatas != null){
//展示的顺序,把data中对象的属性按照你想要的顺序排放就可以了,我这里把id移到了第一列展示
const header = ["datetime", "ordername", "product", "linename", "procedureid","procedurename","number","price","s_total"];
//展示的名称
const headerDisplay = {datetime:"日期", ordername:"订单", product:"产品", linename:"线别", procedureid:"工序号", procedurename:"工序名", number:"数量", price:"单价", s_total:"总金额"};
//将表头放到原始数据里面去,要保证表头在数组的最前面
const newData = [headerDisplay, ...this.tableDatas];
//加了一句skipHeader:true,这样就会忽略原来的表头
// let ws = XLSX.utils.table_to_sheet(document.querySelector('#' this.exportExcelInfo.excelId), xlsxParam);
let ws = XLSX.utils.json_to_sheet(newData, {header:header, skipHeader:true});
// 这里可以添加多个sheet页
XLSX.utils.book_append_sheet(workbook, ws, row[i].username);
}
}
var wbout = XLSX.write(workbook, {
bookType: 'xlsx',
bookSST: true,
type: 'array'
})
try {
FileSaver.saveAs(new Blob([wbout], {
type: 'application/octet-stream'
}), this.exportExcelInfo.excelName)
} catch (e) {
if (typeof console !== 'undefined') console.log(e, wbout)
}
return wbout
},
//excel导出
exportExcel() {
var xlsxParam = {
raw: true
} // 导出的内容只做解析,不进行格式转换
var wb = XLSX.utils.table_to_book(document.querySelector('#' this.exportExcelInfo.excelId), xlsxParam)
var wbout = XLSX.write(wb, {
bookType: 'xlsx',
bookSST: true,
type: 'array'
})
try {
FileSaver.saveAs(new Blob([wbout], {
type: 'application/octet-stream'
}), this.exportExcelInfo.excelName)
} catch (e) {
if (typeof console !== 'undefined') console.log(e, wbout)
}
return wbout
},
//表格formatter数据格式化
formatter(value, item, row, prop) {
//针对table中item多层对象层级的情况
if (prop.indexOf('.') > 0) {
let temp = prop.split('.')
//item中嵌套两层
if (temp.length == 2) {
let temp = prop.split('.')
if (item.formatterType == 'common-type') { //通用类型转换
let arry = item.formatterInfo
for (let i in arry) {
if (arry[i].value == row[temp[0]][temp[1]]) {
return arry[i].label
}
}
} else if (item.formatterType == 'time-type') { //时间标准格式化
return row[temp[0]][temp[1]].substring(0, row[temp[0]][temp[1]].length - 2)
} else if (item.formatterType == 'amount-type') { //金额转换
return (row[temp[0]][temp[1]] / 100).toFixed(2)
}
}
} else { //item中无嵌套对象
let temp = prop.split('.')
if (item.formatterType == 'common-type') { //通用类型转换
let arry = item.formatterInfo
for (let i in arry) {
if (arry[i].value == value) {
return arry[i].label
}
}
} else if (item.formatterType == 'time-type') { //时间标准格式化
return value
} else if (item.formatterType == 'amount-type') { //金额转换
return value
}
}
},
}
};
</script>
其实就是在页面创建了一个隐藏的表格,将需要导出的数据放进这个表格然后实现导出
在页面使用上述组件
代码语言:javascript复制import ExportExcelCommon from "../../../components/ExportExcelCommonOrigin";
components: {
ExportExcelCommon
},
导出方法
代码语言:javascript复制exportExcelAll () {
this.exportExcelInfo.excelName = '用户收入表.xlsx';
this.$confirm('导出列表数据到Excel', '提示', {
type: 'warning',
confirmButtonText: '确认',
cancelButtonText: '取消'
}).then( async () => {
this.tableAllData = this.incomeList;
setTimeout(()=>{
this.$refs.myChild.exportOutAll(this.incomeList);
},500)
}).catch(() => {
this.$message({message: '导出Excel失败!', type: 'warning'})
});
//获取到表格数据的值并赋给this.tableAllData
//同样延时调导出方法,需在initData('export-excel')方法执行成功后调this.$refs.myChild.exportExcel();方法
},
这样就可以实现将el_table中的数据导出并保存到本地excel了