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);
相关推荐
竹林81812 小时前
Web3表单签名验证:我用 wagmi 和 ethers 给 DApp 加了一个“免密登录”,踩坑记录全在这了
javascript
用户69903048487512 小时前
try catch使用场景 处理同步代码错误兼容用的
javascript·uni-app
LDR00612 小时前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术12 小时前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript
码云数智-园园12 小时前
C++20 Modules 模块详解
java·开发语言·spring
VidDown12 小时前
VidDown 工具站:免费、本地优先的开发者工具箱
javascript·编辑器·音视频·视频编解码·视频
swordbob13 小时前
NIO的channel中什么是 fd(File Descriptor,文件描述符)
java·开发语言·nio
源分享13 小时前
Java线程同步的多种实现方法(非常详细)
java·开发语言·jvm
Luminous.13 小时前
C语言--day30
c语言·开发语言
何以解忧,唯有..14 小时前
Go语言循环语句详解:for、range与循环控制
开发语言·算法·golang