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

作者 | xmanlin
链接 | https://juejin.cn/post/6970866355977486349
前言
方案
jsZip和FileSaver.js
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"});}
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[] = []; //用于存储多个promisedata.forEach((item: any) => {const promise = getFile(item.fileUrl).then((res: any) => {const fileName = item.fileNamezip.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;
最后
通过利用JSZip和FileSaver.js,我们可以对后端的批量文件进行一个整合打包压缩,这样既在一定程度上减少了对服务器的压力,在另一方面给人们的感觉就是下载了一个文件,不会一次性弹出很多的下载任务,也在一定程度上提高了体验。
学习更多技能
请点击下方公众号
![]()

评论
