文件导出方法的思路
这里主要讲解blob导出的思路
1. 首先设置一个方法名,接受payload={method='get', url, param, fileName}和options={header},返回promise
function downBlob(payload: payloadType, options?: optionsType) { return new Promise(((resolve, reject) => { })); }
2. 然后,创建一个请求XMLHttpRequest,设置返回blob类型为文件流等配置参数 const { method = 'GET', url = '', param, fileName = '' } = payload;
const requrstUrl = method === 'GET' ? `${url}?${param}` : url;
let name = fileName;
// 获取 XMLHttpRequest
const xmlResquest = new XMLHttpRequest();
// 发起请求
xmlResquest.open(method, requrstUrl, true);
// 返回类型为文件流
xmlResquest.responseType = 'blob';
// 设置请求头类型
xmlResquest.setRequestHeader('Content-type', 'application/json');
// 设置header, options.headers 看情况需要,可支持
Object.entries(options.headers || {}).forEach(item => {
const [k, v] = item;
xmlResquest.setRequestHeader(k, v);
});
3. 设置返回方法 onload,然后发送请求
xmlResquest.onload = (oEvent) => {
// 处理下载的文件
const content = xmlResquest.response;
const blob = new Blob([content]);
// 请求失败
if (xmlResquest.status != 200) {
message.error('请求失败');
return;
}
// 从这个字段获取 filename
const contentDisposition = xmlResquest.getResponseHeader('content-disposition');
if (!name && contentDisposition) {
const matched = contentDisposition.match(/filename*=(.*)/) || contentDisposition.match(/filename=(.*)/);
// 获取filename的值
const filename = matched && matched[1];
name = filename ? decodeURIComponent(filename) : '';
}
// 如果是IE10及以上,不支持download属性,采用msSaveOrOpenBlob方法,但是IE10以下也不支持msSaveOrOpenBlob
if ('msSaveOrOpenBlob' in navigator) {
navigator.msSaveOrOpenBlob(blob, name);
return;
}
};
if (method === 'GET') xmlResquest.send();
if (method === 'POST') xmlResquest.send(JSON.stringify(param));
4. 还需要兼容下ie10以下浏览器
const reader = new FileReader();
reader.onload = (event) => {
// json成功表示服务器报错,将错误信息提示出来
try {
const res = JSON.parse(reader.result);
message.error(res.errorMsg);
reject(res);
} catch (e) {
// json化失败,表示是一个文件流,将文件流下载下来
// 组装a标签
const elink = document.createElement('a');
// 设置下载文件名
elink.download = name || `${timestamp}.xlsx`;
elink.style.display = 'none';
const blobUrl = URL.createObjectURL(blob);
elink.href = blobUrl;
document.body.appendChild(elink);
elink.click();
document.body.removeChild(elink);
URL.revokeObjectURL(blobUrl);
resolve(true);
}
};
reader.readAsText(content);
};
5. 总代码合并起来
function fileDownBlob(payload, options) {
return new Promise(((resolve, reject) => {
const { method = 'GET', url = '', param, fileName = '' } = payload;
const requrstUrl = method === 'GET' ? `${url}?${param}` : url;
let name = fileName;
// 获取 XMLHttpRequest
const xmlResquest = new XMLHttpRequest();
// 发起请求
xmlResquest.open(method, requrstUrl, true);
// 返回类型为文件流
xmlResquest.responseType = 'blob';
// 设置请求头类型
xmlResquest.setRequestHeader('Content-type', 'application/json');
// 设置header, options.headers 看情况需要,可支持
Object.entries(options.headers || {}).forEach(item => {
const [k, v] = item;
xmlResquest.setRequestHeader(k, v);
})
// 设置返回方法
xmlResquest.onload = (oEvent) => {
// 处理下载的文件
const content = xmlResquest.response;
const blob = new Blob([content]);
// 请求失败
if (xmlResquest.status != 200) {
message.error('请求失败');
return;
}
// 从这个字段获取 filename
const contentDisposition = xmlResquest.getResponseHeader('content-disposition');
if (!name && contentDisposition) {
const matched = contentDisposition.match(/filename*=(.*)/) || contentDisposition.match(/filename=(.*)/);
// 获取filename的值
const filename = matched && matched[1];
name = filename ? decodeURIComponent(filename) : '';
}
// 如果是IE10及以上,不支持download属性,采用msSaveOrOpenBlob方法,但是IE10以下也不支持msSaveOrOpenBlob
if ('msSaveOrOpenBlob' in navigator) {
navigator.msSaveOrOpenBlob(blob, name);
return;
}
// 下面是支持ie10以下版本
const reader = new FileReader();
reader.onload = (event) => {
// json成功表示服务器报错,将错误信息提示出来
try {
const res = JSON.parse(reader.result);
message.error(res.errorMsg);
reject(res);
} catch (e) {
// json化失败,表示是一个文件流,将文件流下载下来
// 组装a标签
const elink = document.createElement('a');
// 设置下载文件名
elink.download = name || `${timestamp}.xlsx`;
elink.style.display = 'none';
const blobUrl = URL.createObjectURL(blob);
elink.href = blobUrl;
document.body.appendChild(elink);
elink.click();
document.body.removeChild(elink);
URL.revokeObjectURL(blobUrl);
resolve(true);
}
};
reader.readAsText(content);
};
// 发送请求
if (method === 'POST') xmlResquest.send(JSON.stringify(param));
if (method === 'GET') xmlResquest.send();
}));
}
写到这里整个导出的方法就结束了。
这里在讲解下URL.createObjectURL和URL.revokeObjectURL
URL.createObjectURL:静态方法会创建一个DOMString、,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的document、 绑定。这个新的URL 对象表示指定的File、 对象或Blob、 对象。
URL.revokeObjectURL: 在每次调用 createObjectURL方法时,都会创建一个新的 URL 对象,即使你已经用相同的对象作为参数创建过。当不再需要这些 URL 对象时,每个对象必须通过调用 URL.revokeObjectURL() 方法来释放。
若有不对的地方,欢迎大家一起探讨深入了解~

浙公网安备 33010602011771号