前端资源下载——JSZip和FileSaver 使用

引入JSZip 和 FileSaver 资源包

npm install JSZip FileSaver

使用方式

使用了ant Design 里面的 messagenotification 组件,需要的话可以自行替换;

实现思路,通过将获取到的 Url 资源转换为Blob对象,拿到文件的数据流,然后通过 JSZip 进行资源压缩,最后通过 FileSaver 进行资源下载;

获取 Url 资源的时候使用了 fetch 请求,这里可以根据自己的需求修改为其他请求方式;

import JSZip from "jszip";
import FileSaver from "file-saver";
import { message, notification } from "antd";

/**
 * 批量下载图片,Zip压缩包
 * @filesList
 * @type
 * @callback
 */
export function batchDownLoadZip(filesList: any, type: string, callback: any) {
  const zip = new JSZip();
  const promises: any = [];
  const cache = {};
  const title: string = `${
    type == "picture" ? "图片" : type == "video" ? "视频" : "文件"
  }`;
  if (filesList.length > 1) {
    filesList.forEach((item: any, idx: number) => {
      const fileList = getFile(item.url, type).then((data: any) => {
        // 下载文件, 并存成ArrayBuffer对象
        // 逐个添加文件,视频后缀-.mp4 图片后缀-.png
        zip.file(
          type == "video"
            ? `【${Number(idx) + 1}】${item.name}.mp4`
            : `${Number(item.rowIndex) + 1}_picture_${Number(idx) + 1}.png`,
          data,
          { binary: true }
        );
        cache[item.url] = data;
      });
      promises.push(fileList);
    });
    notification.success({
      message: `${title}下载中`,
      description: `${title}资源准备中,请稍等...`,
      duration: 5,
      onClose: () => {
        Promise.all(promises)
          .then(() => {
            // 生成二进制流
            zip.generateAsync({ type: "blob" }).then((content) => {
              // 利用file-saver保存文件  自定义文件名
              FileSaver.saveAs(content, `${title}`);
              message.success(`${title}下载完成`);
              callback();
            });
          })
          .catch((res) => {
            message.warning(`${title}下载失败!`);
            callback();
          });
      },
    });
  } else {
    if (filesList.length == 0) {
      return false;
    }
    notification.success({
      message: `${title}下载中`,
      description: `${title}资源准备中,请稍等...`,
      duration: 2,
      onClose: () => {
        getFile(filesList[0].url, type).then((data: any) => {
          FileSaver.saveAs(
            data,
            filesList[0].name ||
              `${Number(filesList[0].rowIndex) + 1}_picture.png`
          );
        });
        callback();
      },
    });
  }
}
/**
 *
 * @param url
 * @returns
 */
//批量
export function getFile(url: string, type: string) {
  return new Promise((resolve, reject) => {
    if (type != "video") {
      fileUrlToBlob(url, (event: any) => {
        resolve(event);
      });
    } else {
      urlToBlob(url, (event: any) => {
        resolve(event);
      });
    }
  });
}

/**
 * URL转为Blob格式
 * 图片地址需要允许跨域
 * @param url
 * @param callback
 */
function urlToBlob(url: any, callback: any) {
  // 隐藏referrer属性
  const meta = document.createElement("meta");
  meta.setAttribute("name", "referrer");
  meta.setAttribute("content", "never");
  meta.setAttribute("id", "remove");
  document.getElementsByTagName("head")[0].appendChild(meta);

  const xhr = new XMLHttpRequest();
  xhr.open("get", url, true);
  // ""|"text"-字符串 "blob"-Blob对象 "arraybuffer"-ArrayBuffer对象
  xhr.responseType = "blob";

  xhr.onload = function () {
    if (this.status == 200) {
      const blob: any = this.response;
      // const path: any = URL.createObjectURL(xhr.response);
      callback(blob);
    }
  };
  xhr.send();
}

/**
 *
 * @param url
 * @param callback
 */
function fileUrlToBlob(url: any, callback: any) {
  fetch(url)
    .then((res) => res.blob())
    .then((res) => {
      callback(res);
    });
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值