zoukankan      html  css  js  c++  java
  • 前端打包压缩下载

    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
    ");
            zip.generateAsync({type:"blob"})
            .then((content) => { 
                FileSaver(content, "example.zip");
            });
        }
    
        return (
            <div>
                <button onClick={() => {
                    downloadFile()
                }}>下载</button>
            </div>
        )
    } 
    
    export default MyButton
    

     

    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下载后的名字
          });
    }
    

      

    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实例:

    const zip = new JSZip();
    

      

     

    创建文件:

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

     

    创建文件夹:

    zip.folder("file")
    

      

    同时创建文件夹和文件:

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

     

    生成一个压缩文件:

    我们可以通过.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;
    

     

     

  • 相关阅读:
    UI设计细分为哪些具体职位?国内提供了哪些?
    C4D四视图切换及基本操作
    PS 小技巧让你好用到哭
    在设计中如何运用颜色
    创意海报设计的几大要素
    PS马卡龙渐变海报制作教程
    探索性思维——How to Solve It
    The Go Programming Language. Notes.
    浅析前缀树
    TIJ——Chapter Eleven:Holding Your Objects
  • 原文地址:https://www.cnblogs.com/ygunoil/p/14864001.html
Copyright © 2011-2022 走看看