先说下业务需求,1.JSON转Excel表必须用xlsx格式,2.前端不能使用关于excel转换的插件,3.不能在后台生成相应的文件
前端纯js只能生成xls格式的Excel,因为公司前端环境比较稳定,在前端不能使用其他Excel插件的情况下,只能在后台用插件进行相关操作。但是因为不能生成文件,所以不能用传统的导出URL的方法。最后决定通过后台传blob的方法,再由前端转成文件。
导出
只有一个步骤,将要导出的数据发给后端即可。
前端
前端使用了fetch进行请求,如果用不了fetch,用ajax什么都可以,不过需要处理blob,百度上有很多。
let sendData = {
FileName: "单元连接", //表名
data: dataMsg, //json数据
keys: ["Id","Desc","DataType","OperationType"] //EXCEL里需要展示的json字段
};
fetch(`${window.serverURL}/api/entXlsxExport/download`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization:window.localStorage.token
},
body:JSON.stringify(sendData)
}).then(response => response.blob()) //*注意:fetch的response自带blob()功能,需要将返回值先转一道
.then(blob => {
let url = window.URL.createObjectURL(blob);
let a = document.createElement('a');
a.href = url;
a.download = `${sendData.FileName}.xlsx`;
document.body.appendChild(a);
a.click();
a.remove();
}).catch(error => {
console.log(error);
})
后端
这里使用了“node-xlsx”的插件,他可以生成xlsx的buffer并返回;
使用"express"搭的服务。passport是一个验证token的方法,不需要的可以删掉
const nodeXlsx = require('node-xlsx');
//将json转成Excel.elsx 格式并下载
app.post('/api/entXlsxExport/download',passport.authenticate('jwt', {session: false}), function (req, res) {
try {
const {FileName, data, keys} = req.body;
// let data = [{name:"杜指导",job:"司机"},{name:"甘教练",job:"篮球"},{name:"施爹爹",job:"歌王"},{name:"朱行长",job:"翻墙"}];
// let FileName = 'shoes_club'; //表名,文件名 ************参数传入
// let keys = ["name","job"]; //这里设置表头 ********参数传入
let sheet = [];
if (!!data && data.length > 0) {
if (!sheet[FileName]) {
sheet[FileName] = {sheet: [], value: []};
}
sheet[FileName].sheet = keys;
let values = []; //用来存储每一行json的数值,
data.forEach( (item, index) => {
values = [];
keys.forEach( key => {
values.push(item[key])
});
sheet[FileName].value[index] = values;
});
}
sheet[FileName].value.unshift(sheet[FileName].sheet);
let fileSheet = sheet[FileName].value;
let obj = [{name: FileName, data: fileSheet}];
let file = nodeXlsx.build(obj); //这一步将符合要求的数据拼成buffer
res.setHeader('Content-Type', 'application/vnd.openxmlformats'); //setHeader一定要写在生成buffer的下面
res.setHeader("Content-Disposition", "attachment; filename=" + ` ${encodeURIComponent(FileName)}_${Date.now()}.xlsx`); //不能使用中文
res.writeHead(200);
res.end(file);
}
catch (err) {
return res.status(500).json({success: false, data: err.message});
}
});