<点击/a>标签下的下载;或者通过后端接口返回文件流,然后我们再对流进行一系列的操作等等。下载单个文件的解决方案有很多种,但是当我们需要批量下载文件时,该怎么办呢?解决方案面对这样的需求,我们提出了以下解决方案:方案一:直接获取后端返回的文件地址数组,然后一个一个下载。但是这样每下载一个文件,浏览器就会显示更多的下载任务;方案二:后端先打包压缩文件,然后前端只需要下载一个压缩文件即可,但是对服务器性能影响很大方案三:或者直接获取返回的文件地址数组后端,一个一个下载,然后打包压缩前端。说实话,说到前端打包压缩的时候,心里有一些小伙伴的感觉,前端怎么打包压缩呢?下面两个优秀的库可以很好的解决我们的问题。在这里提一下,下面是在React环境下的例子,其实在其他环境下的思路和用法都是类似的,可以参考下面的内容。JSZip和FileSaver.js本节将简要介绍JSZip和FileSaver.js的API和用法。安装npminstalljszipfile-saverJSZipJSZip是一个用于创建、读取和编辑.zip文件的javascript库,具有友好而简单的API。一个简单的例子首先我们来实现一个简单的例子来感受一下这个非常有用的工具importReact,{useState}from'react';从“jszip”导入JSZip;从“文件保护程序”导入FileSaver;constMyButton=()=>{constdownloadFile=()=>{constzip=newJSZip();zip.file("Hello.txt","HelloWorld\n");zip.generateAsync({type:"blob"}).then((content)=>{FileSaver(content,"example.zip");});}return({downloadFile()}}>Download
)}exportdefaultMyButton点击??下载按钮,我们可以得到一个名为example的压缩文件。zip,打开压缩文件,里面还会有一个名为Hello.txt的文件。API简介这里介绍几个API。创建一个JSZip实例:constzip=newJSZip();创建文件:zip.file("hello.txt","HelloWorld\n");创建文件夹:zip.folder("file")创建文件夹和文件:zip.file("file/hello.txt","HelloWorld\n");//等同于zip.folder("file").file("hello.txt","HelloWorld\n");生成压缩文件:我们可以通过.generateAsync(options)或者.generateNodeStream(options)来生成压缩文件:letpromise=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文件。语法FileSaversaveAs(Blob/File/Url,optionalDOMStringfilename,optionalObject{autoBom})示例importFileSaverfrom'file-saver';constblob=newBlob(["Hello,world!"],{type:"text/plain;charset=utf-8"});FileSaver.saveAs(blob,"helloworld.txt");更多用法,点击官方文档批量获取文件,打包下载这两个库。我们已经了解了下一步满足我们的需求。这里有两步,第一步是获取文件;第二步是打包压缩。需要操作的源文件地址这里的文件地址只是一个简单的例子,具体要根据实际开发而定。constdata=[{fileUrl:'https://www.xxx.com/data/data_service/20210429/144b4b1e4e457485c10fed54b8bc8d48.docx',fileName:'文件一'},{fileUrl:'https://www.xxx.com/data/data_service/20210429/144b4b1e4e457485c10fed54b8bc8d48.docx',fileName:'文件2'},{fileUrl:'https://www.xxx.com/data/data_service/20210429/144b4b1e4e457485c10fed54httpr'doccU},8d'://www.xxx.com/data/data_service/20210429/144b4b1e4e457485c10fed54b8bc8d48.docx',fileName:'文件四'},];从“jszip”获取文件导入JSZip;从“文件保护程序”导入FileSaver;从“./requestFile”导入请求文件;//这里是封装的request函数,可以自己封装或者axiosconstgetFile=(url:string)=>{returnnewPromise((resolve,reject)=>{requestFile(url,{method:'GET',responseType:'blob'}).then((res:any)=>{resolve(res)}).catch((error:any)=>{reject(error)})})}打包压缩下载主要是通过遍历地址数组,然后通过地址从后台获取文件,然后进行批量压缩打包操作,最后保存压缩文件/***打包压缩下载*@param数据源文件数组*@paramfileName压缩文件名*/constcompressAndDownload=(data:any[],fileName?:string)=>{constzip=newJSZip();const承诺:any[]=[];//用于存储多个承诺data.forEach((item:any)=>{constpromise=getFile(item.fileUrl).then((res:any)=>{constfileName=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~91是最快的压缩方式,9是最好的压缩方式}}).then((res:any)=>{FileSaver.saveAs(res,fileName?fileName:"compressedpackage.zip")//使用文件保护程序保存文件})})}exportdefaultcompressAndDownload;参考https://stuk.github.io/jszip/https://github.com/eligrey/Fi...最后,通过使用JSZip和FileSaver.js,我们可以在后端进行整合包压缩批处理文件,这样在一定程度上减轻了服务器的压力,另一方面给人一种文件下载完成的感觉。不会一次性弹出很多下载任务,也在一定程度上提升了体验