关于前端:前端批量获取文件并打包压缩解决方案

75次阅读

共计 3609 个字符,预计需要花费 10 分钟才能阅读完成。

前言

前端文件下载我置信很多小伙伴并不生疏,下载文件的模式也有很多,例如,后端返回一个文件地址,咱们把地址放在 <a></a> 标签外面点击下载;或者是通过后端接口返回文件流,咱们再对流进行一系列的操作等等。

单个件下载的解决办法有很多,然而当咱们须要批量下载文件的时候,咱们该怎么去做呢?

计划

面对这样的需要,咱们提出了以下几个计划:

计划一:间接获取后端返回文件地址数组,而后一个一个的去下载。然而这样每次下载一个文件,浏览器会显示比拟多的下载工作;

计划二:后端对先对文件进行打包压缩解决,而后前端只须要下载一个压缩文件,然而这样会对服务器性能造成很大的影响;

计划三:还是间接获取后端返回的文件地址数组,一个一个的去下载,而后前端来进行打包压缩的解决。

说实话,过后提到前端来打包压缩时,我心中就和一部分小伙伴一样,前端怎么打包压缩?上面这两个优良的库就能够很好的解决咱们的问题。

这里提一下,上面是以 React 环境下为例,然而在其余环境的思路和用法其实都是大同小异,都能够以上面的内容为参考。

JSZip 和 FileSaver.js

本节会简略的介绍一下 JSZip 和 FileSaver.js 的 API 和用法。

装置

npm install jszip file-saver

JSZip

JSZip 是一个用于创立、读取和编辑.zip 文件的 javascript 库,并且领有有敌对而简略的 API。

一个简略的例子

首先咱们来实现一个简略的例子,来感受一下这个非常好用的工具

import React , {useState} from 'react';
import JSZip from 'jszip';
import FileSaver from 'file-saver'; 


const MyButton = () => {const downloadFile = () => {const zip = new JSZip();
        zip.file("Hello.txt", "Hello World\n");
        zip.generateAsync({type:"blob"})
        .then((content) => {FileSaver(content, "example.zip");
        });
    }

    return (
        <div>
            <button onClick={() => {downloadFile()
            }}> 下载 </button>
        </div>
    )
} 

export default MyButton

点击下载按钮,咱们就能够失去一个名为 example.zip 的压缩文件,关上压缩文件,外面也会有一个名为 Hello.txt 的文件.

API

简略介绍一下几个 API。

创立 JSZip 实例:

const zip = new JSZip();

创立文件:

zip.file("hello.txt", "Hello World\n");

创立文件夹:

zip.folder("file")

同时创立文件夹和文件:

zip.file("file/hello.txt", "Hello World\n");
// 等同于
zip.folder("file").file("hello.txt", "Hello World\n");

生成一个压缩文件:

咱们能够通过.generateAsync(options) 或者 .generateNodeStream(options) 来生成一个压缩文件:

let promise = null;
if (JSZip.support.uint8array) {promise = zip.generateAsync({type : "uint8array"});
} else {promise = zip.generateAsync({type : "string"});
}

具体 API 点击官网文档

FileSaver.js

在后面的这个例子中咱们使用了 JSZip 外还应用了 FileSaver.js 这个库。FileSaver.js 是在客户端保留文件的解决方案,非常适合在客户端生成文件。

在上一节的例子中,咱们就是通过 FileSaver.js 把咱们生成的 .zip 文件保留了下来。

语法

FileSaver saveAs(Blob/File/Url, optional DOMString filename, optional Object { autoBom})

例子

import FileSaver from 'file-saver';

const blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
FileSaver.saveAs(blob, "hello world.txt");

更多用法点击官网文档

批量获取文件并打包下载

这两个库咱们曾经有所理解接下来就是实现咱们的需要。这里分两步进行,第一步是获取文件;第二步是打包压缩。

须要操作的源文件地址

这里的文件地址只是一个简略的示例,理论开发的时候视状况而定。

const data = [
    {
        fileUrl: 'https://www.xxx.com/data/data_service/20210429/144b4b1e4e457485c10fed54b8bc8d48.docx',
        fileName: '文件一'
    },
    {
        fileUrl: 'https://www.xxx.com/data/data_service/20210429/144b4b1e4e457485c10fed54b8bc8d48.docx',
        fileName: '文件二'
    },
    {
        fileUrl: 'https://www.xxx.com/data/data_service/20210429/144b4b1e4e457485c10fed54b8bc8d48.docx',
        fileName: '文件三'
    },
    {
        fileUrl: 'https://www.xxx.com/data/data_service/20210429/144b4b1e4e457485c10fed54b8bc8d48.docx',
        fileName: '文件四'
    },
];  

获取文件

import JSZip from 'jszip';
import FileSaver from 'file-saver';
import requestFile from './requestFile'; // 这里是封装的申请函数,大家用本人封装的或者 Axios 都行

const getFile = (url: string) => {return new Promise((resolve, reject) => {
    requestFile(url, {
      method: 'GET',
      responseType: 'blob'
    }).then((res:any) => {resolve(res)
    }).catch((error: any) => {reject(error)
    })
  })
}

打包压缩下载

这里次要是通过遍历地址数组,而后通过地址从后端获取文件,再进行一个批量压缩打包文件的操作,最初把压缩好的文件保留下来。

/**
 * 打包压缩下载
 * @param data  源文件数组
 * @param fileName  压缩文件的名称
 */
const compressAndDownload = (data: any[], fileName ?: string) => {const zip = new JSZip();
  const promises: any[] = [];  // 用于存储多个 promise
  data.forEach((item: any) => {const promise = getFile(item.fileUrl).then((res: any) => {
      const fileName = item.fileName
      zip.file(fileName, res ,{binary: true});
    })
    promises.push(promise)
  })

  Promise.all(promises).then(() => {
    zip.generateAsync({
      type: "blob",
      compression: "DEFLATE",  // STORE:默认不压缩 DEFLATE:须要压缩
      compressionOptions: {level: 9               // 压缩等级 1~9    1 压缩速度最快,9 最优压缩形式}
    }).then((res: any) => {FileSaver.saveAs(res, fileName ? fileName : "压缩包.zip") // 利用 file-saver 保留文件
    })
  })
}

export default compressAndDownload;

参考

https://stuk.github.io/jszip/

https://github.com/eligrey/Fi…

最初

通过利用 JSZip 和 FileSaver.js,咱们能够对后端的批量文件进行一个整合打包压缩,这样既在肯定水平上缩小了对服务器的压力,在另一方面给人们的感觉就是下载了一个文件,不会一次性弹出很多的下载工作,也在肯定水平上进步了体验。

正文完
 0