文章目录
前言
前段时间,工作上需要在一个界面增加一个数据导出功能,按照以前的思路方法,一般会去通过后端编写接口进行导出excel,其实现在很多的项目框架,它们也自带封装好了这个功能。在自己遇到这个需求后,首先发现项目的框架里并没有,然后最近一直在学vue,因此想用vue去实现这个功能。废话不多说自己开干。
一、前端界面
首先现在界面上引出一个导出按钮(这里我用的是element ui框架里的)
<el-button type="primary" icon="el-icon-download" size="small" @click="exportExcel">导出</el-button>
二、引入写好的js文件(它就是用来构造excel表格的界面的)
import {export_json_to_excel} from '@/util/exportExcel.js'
1.引入的export_json_to_exce方法的代码如下:
import XLSX from 'xlsx' (记得在js文件中导入xlsx)
export function export_json_to_excel({
header,
data,
filename,
autoWidth = true,
bookType= 'xlsx'
} = {}) {
/* original data */
filename = filename || 'excel-list'
data = [...data]
data.unshift(header);
var ws_name = "SheetJS";
var wb = new Workbook(),
ws = sheet_from_array_of_arrays(data);
if (autoWidth) {
/*设置worksheet每列的最大宽度*/
const colWidth = data.map(row => row.map(val => {
/*先判断是否为null/undefined*/
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
};
}
}))
/*以第一行为初始值*/
let 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;
}
/* add worksheet to workbook */
wb.SheetNames.push(ws_name);
wb.Sheets[ws_name] = ws;
var wbout = XLSX.write(wb, {
bookType: bookType,
bookSST: false,
type: 'binary'
});
saveAs(new Blob([s2ab(wbout)], {
type: "application/octet-stream"
}), `${filename}.${bookType}`);
}
function sheet_from_array_of_arrays(data, opts) {
var ws = {};
var range = {
s: {
c: 10000000,
r: 10000000
},
e: {
c: 0,
r: 0
}
};
for (var R = 0; R != data.length; ++R) {
for (var 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;
var cell = {
v: data[R][C]
};
if (cell.v == null) continue;
var 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;
}
2.获取数据
代码如下(这部分代码是我们导入按钮的vue界面)
exportExcel: throttle(function () {
//这个是请求数据的接口(我这里懒省事,直接调的页面table的接口,给size传了个999999)
findList({
userName: this.query.userName
page: this.page.currentPage,
size: 9999999
})
.then(res => {
let json_data = res.data
if(json_data.length <= 0){
this.$message.error('导出数据为空,请先搜索内容')
return false
}
let tHeader = ["单号", "状态","部门","工号","姓名","邮箱"]
let filterVal = ["objectId","status","dept","usrId","userName","email"]
let excelList = json_data
let filename='申请明细列表'+ excelNameTime()
let data = this.formatJson(filterVal, excelList);
export_json_to_excel({
header:tHeader,
data,
filename
})
})
.catch(error => {
reject(error);
})
}, 2000),
//这个方法是对数据进行处理的,比如说状态返回的可能是数字,而excel里要展示的是文字
formatJson(filterVal, excelList) {
let that = this
return excelList.map(v =>
filterVal.map(j => {
if (j === "status") {
if(v.status == '0'){
return "待审批"
} else if(v.status == '1'){
return '审批通过"
} else if(v.status == '2'){
return "审批不通过"
}
}
return v[j];
})
);
},
上面这部分代码里有一个我写的时间处理方法和一个throttle节流(推荐创建一个util.js文件引入,我这里就了一个新的js文件)
import {excelNameTime,throttle} from '@/util/util'
export const throttle = (fn, gapTime) => {
if (gapTime == null || gapTime == undefined) {
gapTime = 1500
}
let _lastTime = null
// 返回新的函数
return function () {
let _nowTime = + new Date()
if (_nowTime - _lastTime > gapTime || !_lastTime) {
fn.apply(this, arguments) //将this和参数传给原函数
_lastTime = _nowTime
}
}
}
export const excelNameTime = () =>{
var myDate = new Date();
var mon = myDate.getMonth() + 1; //getMonth()返回的是0-11,则需要加1
if (mon <= 9) {
mon = "0" + mon; //如果小于9的话,则需要加上0
}
var day = myDate.getDate(); //getdate()返回的是1-31,则不需要加1
if (day <= 9) {
day = "0" + day; //如果小于9的话,则需要加上0
}
return (myDate.getFullYear().toString() +
mon.toString() +
day.toString() +
myDate.getHours().toString() +
myDate.getMinutes().toString() +
myDate.getSeconds().toString())
}
总结
以上就是使用vue的完整导出功能了,其实对于后端,没有什么要求,只要返回要导出的数据就可以了。谢谢各位学习!
版权归原作者 小马ovO 所有, 如有侵权,请联系我们删除。