文件导出方法的思路

这里主要讲解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;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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');<br>
// 设置header, options.headers 看情况需要,可支持
Object.entries(options.headers || {}).forEach(item => {
    const [k, v] = item;
    xmlResquest.setRequestHeader(k, v);
});

3. 设置返回方法 onload,然后发送请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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以下浏览器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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';<br>      const blobUrl = URL.createObjectURL(blob);<br>      elink.href = blobUrl;
      document.body.appendChild(elink);
      elink.click();
      document.body.removeChild(elink);
      URL.revokeObjectURL(blobUrl);
      resolve(true);
    }
  };
  reader.readAsText(content);
};

5. 总代码合并起来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
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() 方法来释放。

若有不对的地方,欢迎大家一起探讨深入了解~

 

posted @   君临天下之徐少  阅读(38)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示