JSZip的使用

要在浏览器中使用 ‌JSZip ‌ 压缩一个文件夹(即包含多个文件和子目录的结构),可以借助 HTML5 的 ‌File API ‌ 和 ‌JSZip‌ 库实现。以下是完整操作指南:


✅ 核心步骤

  1. 引入 JSZip 库
  2. 通过 <input type="file" webkitdirectory> 选择文件夹
  3. 遍历选中的文件,添加到 JSZip 实例中
  4. 生成 ZIP 文件并下载

📦 1. 引入 JSZip

推荐使用 CDN 快速引入(无需安装):

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

更多引入方式(如 npm)可参考 JSZip 官方文档


🖱️ 2. HTML:添加文件夹选择器

复制代码
<input type="file" id="folderInput" webkitdirectory directory multiple /> <button onclick="compressFolder()">压缩文件夹</button>
  • webkitdirectory directory:允许选择整个文件夹(支持 Chrome/Firefox 等现代浏览器)。
  • multiple:确保能获取所有文件。

⚙️ 3. JavaScript:压缩逻辑

复制代码
async function compressFolder() {
  const input = document.getElementById('folderInput');
  const files = Array.from(input.files); // 转换为数组

  if (files.length === 0) {
    alert('请先选择一个文件夹');
    return;
  }

  const zip = new JSZip();

  // 遍历每个文件,按原始路径添加到 zip
  for (const file of files) {
    // 读取文件内容为 ArrayBuffer
    const arrayBuffer = await file.arrayBuffer();
    // 使用完整路径(含文件夹结构)作为 key
    zip.file(file.webkitRelativePath, arrayBuffer);
  }

  // 生成 ZIP 并下载
  const blob = await zip.generateAsync({ type: 'blob' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'compressed_folder.zip'; // 设置压缩包名称
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
  URL.revokeObjectURL(url); // 释放内存
}

✅ ‌关键点‌:

  • 使用 file.webkitRelativePath 可保留原始文件夹层级结构。
  • 使用 arrayBuffer() 适配二进制文件(如图片、PDF 等)。

📁 效果示例

假设你选择的文件夹结构为:

复制代码
my-folder/
├── doc.txt
├── image.jpg
└── sub/
    └── note.md

生成的 ZIP 文件将完全保留该结构。


💡 补充建议

  • 大文件优化 ‌:若文件夹很大(>100MB),建议启用流式处理:

    复制代码
    zip.generateAsync({ type: 'blob', streamFiles: true })
  • 中文文件名‌:JSZip 默认支持 UTF-8,一般无需额外处理。

  • 兼容性 ‌:webkitdirectory 在 Safari 和旧版浏览器中可能不支持,可考虑使用 Web Drag and Drop API 作为备选方案。

在 Node.js 环境中使用 ‌JSZip ‌ 压缩整个文件夹,需结合 Node.js 的文件系统(fs)模块递归读取文件夹内容,再通过 JSZip 将其打包为 ZIP 文件。

以下是完整实现步骤:

复制代码
npm install jszip

JSZip 在 Node.js 中支持良好,但需注意:它本身不直接读取文件系统,必须手动读取文件内容并传入。

复制代码
const fs = require('fs');
const path = require('path');
const JSZip = require('jszip');

async function compressFolder(folderPath, zipPath) {
  const zip = new JSZip();

  // 递归读取文件夹并添加到 zip
  function addFolderToZip(currentPath, zipParent) {
    const items = fs.readdirSync(currentPath);
    items.forEach(item => {
      const fullPath = path.join(currentPath, item);
      const stat = fs.statSync(fullPath);

      if (stat.isDirectory()) {
        const folder = zipParent.folder(item);
        addFolderToZip(fullPath, folder); // 递归处理子目录
      } else {
        const content = fs.readFileSync(fullPath); // 读取为 Buffer
        zipParent.file(item, content);
      }
    });
  }

  // 获取文件夹名作为 zip 根目录名
  const folderName = path.basename(folderPath);
  const rootFolder = zip.folder(folderName);

  // 开始递归添加文件
  addFolderToZip(folderPath, rootFolder);

  // 生成 ZIP 文件并保存到磁盘
  const zipContent = await zip.generateAsync({
    type: "nodebuffer",
    compression: "DEFLATE",
    compressionOptions: { level: 9 }
  });

  fs.writeFileSync(zipPath, zipContent);
  console.log(`压缩完成: ${zipPath}`);
}

// 使用示例
const sourceFolder = './your-folder-to-compress'; // 替换为你的文件夹路径
const outputZip = './output.zip'; // 输出 ZIP 文件名

compressFolder(sourceFolder, outputZip);
相关推荐
ambition202423 分钟前
操作系统同步:读者-写者问题与读写公平法详解(附每个 PV 操作含义)
linux·开发语言·数据结构·unix
chuan.bai3 小时前
Java RAG 实战(第 11 篇):RAG 知识工作台网页
java·开发语言·人工智能
离陌在学C#5 小时前
C# 事件(Event)详解:从概念到实战
开发语言·c#
Terra.K6 小时前
Java异常学习[特殊字符]
java·开发语言·学习
mCell6 小时前
Lua 编程入门:从基础语法到元表
javascript·算法·lua
伟大的兔神6 小时前
我做了一个本地优先的 AI 图片工作台:Loomora v1.0.0 正式发布
前端·javascript·vue.js
葡萄城技术团队7 小时前
InfluxDB 2\.x 深度解析:核心架构、Flux 函数与制造业落地指南(三)
java·开发语言·架构
counting money7 小时前
Java IO流详解:从InputStream到文件操作实战
java·开发语言·python
wuyk5557 小时前
98.C语言易混难点:字符数组与字符串指针的底层差异
c语言·开发语言·c++·stm32·嵌入式硬件·算法
峥无8 小时前
从0到1手撕红黑树:封装实现 my_map 与 my_set(SGI-STL 源码级深度解析)
开发语言·c++·笔记·算法·stl