小工具知识网

当前位置: 首页 > 行业知识 > 前端实现下载文件(包含压缩包下载)方式汇总

行业知识

前端实现下载文件(包含压缩包下载)方式汇总

2026-11-15 23:32:57 来源:互联网转载

默认最简单的下载方式是:window.open(后台接口API路径),但该方法弊端:因是新开窗口方式,前端展示上,每次会闪下。

此外,如果使用window.open(文件URL)方式:

  • pdf、office文档、psd:直接下载。
  • 图片、txt:新开窗口预览,不会下载;且txt预览,有时出现中文乱码问题。

    一、根据文件URL下载

    实现原理:通过a标签实现下载。

    /** * @method 下载单个文件(文件类型可任意:.png、txt、office文档、.psd等) * @param { String } url - 文件的http完整路径, 如:http: //xxx.png * @param { String } fileName - 文件名,注意是要带文件后缀名,如:xxx.png * @doc https://blog.csdn.net/weixin_39547158/article/details/110851570 */export function downloadFile(url: string, fileName: string) {  return new Promise((resolve, reject) => {    const xhr = new XMLHttpRequest();    xhr.open('GET', url, true);    xhr.responseType = 'blob';    xhr.upload.onprogress = (e) => {      if (e.lengthComputable) {        let progress = e.loaded / e.total;        console.log('文件上传进度是', progress);      }    };    xhr.onload = function () {      const url = window.URL.createObjectURL(xhr.response);      const eleLink = document.createElement('a');      eleLink.href = url;      eleLink.download = `${fileName}`;      eleLink.style.display = 'none';      document.body.appendChild(eleLink);      eleLink.click();      document.body.removeChild(eleLink);      resolve('success');    };    xhr.onerror = (e) => {      console.log('请求错误回调', e);      message.warning('下载文件失败')      reject(e);    };    xhr.send();  });}

    二、excel文件:调用后台接口返回文件流,前端下载文件

    实现原理:调用后台接口,返回blob, 前端使用file-saver库实现下载。

    // 下载excel文件import FileSaver from 'file-saver';const downloadTemplate = async () => {  try {    const params = { ... } // 传参    const res = await generateDownStreamReconciliationUsingGET(params);    // res为返回结果    if (res) {      const blob = new Blob([res], { type: 'application/vnd.ms-excel' });      FileSaver.saveAs(blob, '对账单.xlsx');      console.log('对账单下载成功')    }  } catch (e) {    console.log(e);  } finally {    console.log('finally')  }};
    // 生成对账excel模板表格APIexport async function generateDownStreamReconciliationUsingGET(  params: API.generateDownStreamReconciliationUsingGETParams,  options?: { [key: string]: any },) {  return request(    `${process.env.APP_HOST_WAYBILL}/xxx/generateDownStreamReconciliation`,    {      method: 'GET',      responseType: 'blob',  // 必须写该行,否则:后台返回的是string,不是blob且文件下载后,会出现打不开问题。      params: {        ...params,      },      ...(options || {}),    },  );}

    三、多文件URL下载,前端生成压缩包下载

    实现原理:jszip库 + file-saver库

    import { getBlobOfUrl } from '@/services/common';import { saveAs } from 'file-saver';import JSZip from 'jszip';import { message } from 'antd';/** * @method 同时下载多文件,并生成一个压缩包 * @param { Object[] } fileInfoList - 文件列表 * @param { String } urlField - 文件URL的字段名 * @param { String } fileNameField - 文件名的字段名 * @param { String } folderName - 压缩包 & 文件夹名称 */export function downloadAsZip(  fileInfoList: any[],  folderName = '文件压缩包',  urlField = 'filePath',  fileNameField = 'name',) {  return new Promise((resolve, reject) => {    const zip = new JSZip();    // const folder = zip.folder(folderName); // 创建文件夹    const promisesList = fileInfoList.map((item) => {      return getBlobOfUrl(item[urlField])        .then((data) => {          // console.log(data); // Blob          // folder.file(item[fileNameField], data, { binary: true }); // 往文件夹中存放文件          zip.file(item[fileNameField], data, { binary: true }); // 不创建文件夹        })        .catch((e) => {          console.log(e);          message.warning(e?.message || '获取文件流失败')        });    });    Promise.all(promisesList)      .then(() => {        zip          .generateAsync({ type: 'blob' })          .then((content) => {            saveAs(content, folderName);            resolve('success');          })          .catch((e) => {            message.warning(e?.message || '生成压缩包失败')            reject(e);          });      })      .catch((e) => {        message.warning(e?.message || '批量获取文件流失败')        reject(e);      });  });}
    import { request } from 'umi';/** * @method 根据文件URL获取blob数据流的API * @param { String } fileUrl - 文件完整路径,如:http://xxx.png */export function getBlobOfUrl(fileUrl: string) {  return request(fileUrl, {    method: 'GET',    responseType: 'blob', // 设置后台返回的内容类型为blob    params: {      notAuthorization: true,    },  });}

上一篇:图论基础(一)

下一篇:人人商城拼团分销攻略,轻松掌握分销技巧,助力你的拼团销售火爆!