JSZip 使用详解

发布于:2025-07-12 ⋅ 阅读:(21) ⋅ 点赞:(0)

JSZip 使用详解

JSZip 是一个用于创建、读取和编辑 ZIP 文件的 JavaScript 库,完全在浏览器中运行,也支持 Node.js 环境。

安装

浏览器环境

<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>

Node.js 环境

npm install jszip
# 或
yarn add jszip

基本使用

1. 创建一个 ZIP 文件

const JSZip = require("jszip"); // Node.js 中需要
const zip = new JSZip();

// 添加文本文件
zip.file("hello.txt", "Hello World\n");

// 添加文件夹
const img = zip.folder("images");

// 在文件夹中添加文件
img.file("smile.gif", base64Data, {base64: true});

// 生成 ZIP 文件
zip.generateAsync({type:"blob"})
  .then(function(content) {
    // 下载 ZIP 文件
    saveAs(content, "example.zip");
  });

2. 读取 ZIP 文件

// 假设 file 是用户通过 input[type=file] 选择的 ZIP 文件
function readZip(file) {
  JSZip.loadAsync(file)
    .then(function(zip) {
      // 获取所有文件和文件夹
      Object.keys(zip.files).forEach(function(filename) {
        const file = zip.files[filename];
        if (!file.dir) {
          // 如果是文件而不是文件夹
          file.async("text").then(function(fileData) {
            console.log(filename, fileData);
          });
        }
      });
    })
    .catch(function(err) {
      console.error(err);
    });
}

核心 API

创建和添加内容

  • new JSZip() - 创建一个新的 JSZip 实例
  • .file(name, data[, options]) - 添加一个文件
  • .folder(name) - 创建一个文件夹
  • .remove(name) - 删除文件或文件夹

读取内容

  • .file(name) - 获取文件
  • .files - 获取所有文件
  • .forEach(callback) - 遍历所有文件
  • .filter(callback) - 过滤文件

生成 ZIP

  • .generateAsync(options) - 异步生成 ZIP 文件
  • .generateNodeStream(options) - Node.js 流式生成

进阶功能

1. 添加二进制数据

// 添加 ArrayBuffer
fetch('image.png')
  .then(res => res.arrayBuffer())
  .then(data => {
    zip.file("image.png", data);
  });

// 添加 Blob
zip.file("image.jpg", blobData);

2. 设置文件属性

zip.file("readme.txt", "This is a readme", {
  date: new Date(2020, 0, 1), // 设置日期
  unixPermissions: "644",      // UNIX 权限
  dosPermissions: null,        // DOS 权限
  comment: "First comment",    // 注释
  createFolders: true          // 自动创建文件夹
});

3. 处理大型文件

// 使用流式处理大型文件 (Node.js)
const fs = require('fs');
const stream = fs.createReadStream('large-file.bin');

zip.file("large-file.bin", stream);

// 生成时使用流式输出
const zipStream = zip.generateNodeStream({type:'nodebuffer', streamFiles:true});
zipStream.pipe(fs.createWriteStream('output.zip'))
  .on('finish', function () {
    console.log("output.zip written.");
  });

4. 密码保护 (需要 JSZip 第三方插件)

// 注意:这不是 JSZip 核心功能,需要额外插件
const password = "secret";
zip.generateAsync({
  type: "blob",
  encryption: "AES-256", // 加密类型
  password: password      // 密码
}).then(function(content) {
  saveAs(content, "protected.zip");
});

实际应用示例

1. 打包多个文件下载

async function downloadFilesAsZip(files) {
  const zip = new JSZip();
  const promises = [];
  
  files.forEach(file => {
    promises.push(
      fetch(file.url)
        .then(res => res.blob())
        .then(blob => {
          zip.file(file.name, blob);
        })
    );
  });
  
  await Promise.all(promises);
  
  const content = await zip.generateAsync({type: "blob"});
  saveAs(content, "download.zip");
}

2. 在浏览器中预览 ZIP 内容

document.getElementById('zip-input').addEventListener('change', function(e) {
  const file = e.target.files[0];
  const zip = new JSZip();
  
  zip.loadAsync(file)
    .then(function() {
      const preview = document.getElementById('preview');
      preview.innerHTML = '';
      
      zip.forEach(function(relativePath, file) {
        const div = document.createElement('div');
        div.textContent = relativePath;
        preview.appendChild(div);
      });
    });
});

3. 从 ZIP 中提取特定文件

async function extractFileFromZip(zipFile, targetFileName) {
  const zip = await JSZip.loadAsync(zipFile);
  const file = zip.file(targetFileName);
  
  if (!file) {
    throw new Error('File not found in zip');
  }
  
  return file.async('text'); // 或 'arraybuffer', 'blob' 等
}

注意事项

  1. 浏览器兼容性:JSZip 支持大多数现代浏览器,包括 IE10+
  2. 性能考虑:处理大型 ZIP 文件可能会占用大量内存
  3. Node.js 特定功能:如流式处理仅在 Node.js 中可用
  4. ZIP 规范支持:JSZip 支持大多数常见的 ZIP 功能,但不支持所有 ZIP 特性

JSZip 是一个功能强大且灵活的库,非常适合在 Web 应用中处理 ZIP 文件,无论是创建、读取还是修改 ZIP 存档。


网站公告

今日签到

点亮在社区的每一天
去签到