最近做一个项目,遇到了一个问题,就是导出Excel功能。多普通呀,多大众化,哪里都有,可惜我们后台说给我JSON数据,自己处理。我果断拒绝了,拒绝的里有是我菜,实现不了啊。然后后台开发看不下去了,就是转成文件流给我吧。他们那里是分布式部署,也没有办法持久化存储。遂发生了一下的故事
没有怎么做过,肯定是百度啦,然后找打了一段代码,代码内容如下
function download() {
var xmlResquest = new XMLHttpRequest();
xmlResquest.open("POST", "/eksoft/fileUpload/download", true);
xmlResquest.setRequestHeader("Content-type", "application/json");
xmlResquest.setRequestHeader("Authorization", "Bearer 6cda86e3-ba1c-4737-972c-f815304932ee");
xmlResquest.responseType = "blob";
xmlResquest.onload = function (oEvent) {
var content = xmlResquest.response;
var elink = document.createElement('a');
elink.download = "test.xlsx";
elink.style.display = 'none';
var blob = new Blob([content]);
elink.href = URL.createObjectURL(blob);
document.body.appendChild(elink);
elink.click();
document.body.removeChild(elink);
};
xmlResquest.send();
}
var content = 'content';
var elink = document.createElement('a');
var blob = new Blob([content]);
elink.download = "test.xlsx";
elink.style.display = 'none';
elink.href = URL.createObjectURL(blob);
elink.click();
createObjectURL
URL.createObjectURL()
, 静态方法,会创建一个DOMString
,其中包含一个表示参数中给出的对象URL。这个URL的生命周期和创建他的窗口中的document
绑定,这个新的URL对象表示File
对象或者Blob
对象。objectURL = URL.createObjectURL(blob);
revokeObjectURL
URL.revokeObjectURL
静态方法。 来释放之前通过调用createObjectURL
创建的已经存在的对象。当结束使用某个URL对象时,应该通过这个方法来访浏览器知道不再需要这个文件的引用了。window.URL.revokeObjectURL(objectURL);
bjectURL: 是一个 DOMString
,表示通过调用 URL.createObjectURL
方法产生的 URL 对象String
。null
传递给接受DOMString的方法或参数时通常会把其stringifies为“null”。/**
* 导出文件工具方法
* 需要将返回的文件流对象直接传入,
* 如果没有数据, 返回一个对象
*/
export let exportFile = (data, name = 'name') => {
return data.blob().then((blob) => {
// js无法判断文件刘是否存在,只能通过类型
// 文件流没有数据的时候转码是/html结尾,我这个直接返回一个对象,方便调用的时候处理
if (blob.type.endsWith('/html')) {
return {
msg: "暂无数据"
}
}
let downloadUrl = window.URL.createObjectURL(blob);
let anchor = document.createElement("a");
let filename = data.headers.get('Content-Disposition');
anchor.href = downloadUrl;
anchor.download = filename.replace('filename=', '');
anchor.click();
window.URL.revokeObjectURL(downloadUrl);
})
}
// 调用文件导出方法
async function export () {
let res = await axios.post('http://xxx.com', {})
let err = await exportFile(res.data, '推送日志')
if (err) message.warning(err.msg)
}
export()
/**
* 导出文件工具方法
* 需要将返回的文件流对象直接传入,
* 如果没有数据, 返回一个对象
* 文件命名规范为手动传入一个文件名,然后加上日期,时分秒
*/
export let exportFile = (data, name = 'name') => {
return data.blob().then((blob) => {
if (blob.type.endsWith('/html')) {
return {
msg: "暂无数据"
}
}
let downloadUrl = window.URL.createObjectURL(blob);
let anchor = document.createElement("a");
anchor.href = downloadUrl;
anchor.download = `${name}${Format(new Date(), 'yyyyMMddhhmmss')}.csv`;
anchor.click();
window.URL.revokeObjectURL(downloadUrl);
})
}
到了这里,简单的文件处理就结束了,后台又差了一下,说这个会有兼容性问题,然后有一段处理兼容的代码,我这里目前没有管ie,遂没有验证,但是还是把代码贴过来,留着总是好的
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, filename);
} else {
var a = document.createElement('a');
blob.type = "application/excel";
var url = createObjectURL(blob);
a.href = url;
a.download = filename;
a.click();
window.URL.revokeObjectURL(url);
}