JSZip和FileSaver.js
本节会简单的介绍一下JSZip和FileSaver.js的API和用法。
安装
1 | npm install jszip file-saver |
JSZip
JSZip是一个用于创建、读取和编辑.zip文件的javascript库,并且拥有有友好而简单的API。
一个简单的例子
首先我们来实现一个简单的例子,来感受一下这个十分好用的工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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 |
1 2 3 4 5 6 7 8 9 10 11 12 13 | download() { const zip = new JSZip(); // 实例化zip const img = zip.folder( "qrCode" ); // zip包内的文件夹名字 this .listOfData.forEach((item) => { // listOfData是含有图片的数据数组 const basePic = item.url.replace(/^data:image\/(png|jpg);base64,/, "" ); // 生成base64图片数据 img.file(item.name + '的二维码.png' , basePic, { base64: true }); // 将图片文件加入到zip包内 }) zip.generateAsync({ type: "blob" }) // zip下载 .then(function (content) { // see FileSaver.js saveAs(content, "二维码.zip" ); // zip下载后的名字 }); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | import JSZip from 'jszip' import FileSaver from 'file-saver' getFile = (url) => { return new Promise(resolve => { const xhr = new XMLHttpRequest(); // 避免 200 from disk cache url = url + `?r=${Math.random()}`; xhr.open( 'GET' , url, true ); xhr.responseType = 'blob' ; xhr.onload = () => { if (xhr.status === 200) { resolve(xhr.response); } else { resolve(); // 避免图片下载失败,导致批量导出失败 } }; xhr.send(); }); } // 批量下载 handleBatchDownload = async (selectImgList, idArray) => { const data = selectImgList; const zip = new JSZip(); const cache = {}; const promises = []; await data.forEach((item, index) => { const promise = this .getFile(item).then((fileData) => { // 下载文件 const arrName = item.split( '/' ); let fileName = arrName[arrName.length - 1]; // 获取文件名 // 转码文件名, 上传的文件用decodeURIComponent转汉字 const endIndex = fileName.lastIndexOf( '.' ); const format = fileName.slice(endIndex); const startName = fileName.slice(0, endIndex); const newFileName = decodeURIComponent(startName) + format; zip.file(newFileName, fileData as any, { binary: true }); // 逐个添加文件 cache[newFileName] = fileData; }); promises.push(promise); }); Promise.all(promises).then(() => { zip .generateAsync({ type: 'blob' }) .then(async (content) => { // 生成二进制流;利用file-saver保存文件 FileSaver.saveAs( content, `压缩文件.zip` ); }); }); }; |
点击下载按钮,我们就可以得到一个名为example.zip
的压缩文件,打开压缩文件,里面也会有一个名为Hello.txt
的文件.
API
简单介绍一下几个API。
创建JSZip实例:
1 | const zip = new JSZip(); |
创建文件:
1 | zip.file( "hello.txt" , "Hello World\n" ); |
创建文件夹:
1 | zip.folder( "file" ) |
同时创建文件夹和文件:
1 2 3 | zip.file( "file/hello.txt" , "Hello World\n" ); // 等同于 zip.folder( "file" ).file( "hello.txt" , "Hello World\n" ); |
生成一个压缩文件:
我们可以通过.generateAsync(options)
或者 .generateNodeStream(options)
来生成一个压缩文件:
1 2 3 4 5 6 | 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
文件保存了下来。
语法
1 | FileSaver saveAs(Blob/File/Url, optional DOMString filename, optional Object { autoBom }) |
例子
1 2 3 4 | import FileSaver from 'file-saver' ; const blob = new Blob([ "Hello, world!" ], {type: "text/plain;charset=utf-8" }); FileSaver.saveAs(blob, "hello world.txt" ); |
更多用法点击官方文档
批量获取文件并打包下载
这两个库我们已经有所了解接下来就是实现我们的需求。这里分两步进行,第一步是获取文件;第二步是打包压缩。
需要操作的源文件地址
这里的文件地址只是一个简单的示例,实际开发的时候视情况而定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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: '文件四' }, ]; |
获取文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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) }) }) } |
打包压缩下载
这里主要是通过遍历地址数组,然后通过地址从后端获取文件,再进行一个批量压缩打包文件的操作,最后把压缩好的文件保存下来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | /** * 打包压缩下载 * @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; |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
· 不到万不得已,千万不要去外包
· C# WebAPI 插件热插拔(持续更新中)
· 会议真的有必要吗?我们产品开发9年了,但从来没开过会
· 【译】我们最喜欢的2024年的 Visual Studio 新功能
· 如何打造一个高并发系统?
2020-06-08 jetbrains产品(WebStorm、idea、pycharm) 最新激活码
2020-06-08 ts使用装饰器
2020-06-08 Object.seal()与Object.freeze()
2020-06-08 zuul网关集成swagger
2020-06-08 Spring Cloud Gateway整合Swagger聚合微服务系统API文档(非Zuul)