微信小程序 - 创建 ZIP 压缩包

场景

微信小程序只提供了解压ZIP的API,并没有提供创建ZIP的方法。
当我们想把自己处理好的保存,打包ZIP保存下来时就需要自己实现了。

分享代码片段

不想听废话的,直接看代码
https://developers.weixin.qq.com/s/ChblKjmo7ZNd

在这里插入图片描述

导入 JSZip

首先需要 jszip

const JSZip = require('../lib/jszip.min');
const fs = wx.getFileSystemManager();

jszip 在微信小程序无法直接跑。要处理一下。把 setImmediate 全部替换为 setTimeout
在这里插入图片描述

创建ZIP文件

/**
 * 文件打包为 zip
 * @param {*} fileList 文件列表 [{ name: '文件名', path: '文件路径'}]
 * @param {*} zipPath  保存压缩包的路径
 * @param {*} progress 处理进度更新时:回调
 */
async function zip(fileList, zipPath, progress=res=>console.log){
  try {
    // 实例化 jszip
    var jszip = new JSZip();
    // 遍历文件列表,添加到 zip 文件列表中
    let total = fileList.length;
    fileList.forEach((file, index) => {
      jszip.file(file.name, new Uint8Array(fs.readFileSync(file.path)));
      progress({ percent: Math.round((index+1)/total) * 100, msg: `读取资源 ${index+1}/${total}` });
    });
    // 生成压缩包对象(uint8array)
    let content = await jszip.generateAsync(
      { type : JSZip.support.uint8array ? "uint8array" : "string" },
      meta => progress({ percent: Math.floor(meta.percent), msg: `创建 ZIP...` }) // { currentFile: '', percent: 100 }
    );
    // 将 arrayBuffer 形式压的缩包数据写入二进制文件,生成 zip
    progress({ percent: 0, msg: `保存 ZIP...` }); // 开始
    // 分块写入
    await appendFile({ 
      filePath: zipPath, 
      data: content.buffer, 
      encoding: 'binary', 
      progress: percent => progress({ percent: Math.floor(percent), msg: `保存 ZIP...` })
    }).then(() => {
      progress({ percent: 100, msg: `ZIP 保存完成` });
    }).catch(err => {
      console.error('写入文件失败:', err);  
    });
  } catch (err) {
    console.log(err);
  }
}

追加写入文件

/**
 * 追加写入文件
 * @param {string} filePath     文件路径
 * @param {string} data         写入数据
 * @param {string} encoding     编码类型:默认 utf8
 * @param {number} chunkSize    写入块大小:默认 1048576 字节
 * @param {function} progress   更新进度回调
 */
function appendFile(options) { 
  let { filePath, data, encoding, chunkSize, progress } = Object.assign({
    encoding: 'utf8',     // 编码类型,默认 utf8。想写二进制用 'binary'
    chunkSize: 1048576,   // 每块大小默认 1M
    progress: console.log // 更新进度
  }, options);

  // 文件总长度
  const fileLength = data instanceof ArrayBuffer ? data.byteLength : data.length;  

  // 文件小于 chunkSize 直接写
  if(fileLength <= chunkSize){
    return new Promise((resolve, reject) => {
      try {
        resolve(fs.writeFileSync( filePath, data, encoding ));
      } catch (error) {
        reject(error);
      }      
    });
  }else{
    // 否则分块写入,并调用进度更新 callback
    return new Promise((resolve, reject) => {
      // 先写入一个空文件。(作用:有则清空,无则创建)
      fs.writeFileSync(filePath, new ArrayBuffer(0), encoding);
      // 已写入长度
      let writtenLength = 0;
      // 写入数据块
      const writeChunk = () => {
        const chunkData = data.slice(writtenLength, writtenLength + chunkSize); // 切段
        fs.appendFile({  
          filePath,         // 文件路径
          data: chunkData,  // 数据块
          encoding,         // 编码类型
          success: () => {  
            writtenLength += chunkSize; // 更新已写入长度
            progress( Math.floor((writtenLength / fileLength) * 100)); // call回调函数更新进度  
            if (writtenLength < fileLength) {  
              writeChunk();  // 继续写入下一块数据  
            } else {  
              resolve(writtenLength);  // 文件写入完成:返回写入长度
            }  
          },  
          fail: err => reject(err) 
        });  
      };
      // 继续调用写入数据块
      writeChunk();  
    });
  }
}

测试方法

test(){
    const zipFolder = `${wx.env.USER_DATA_PATH}/test`;
    const zipPath = `${zipFolder}/hello.zip`;
    let fileList = [];
    try {
      // 先创建对应目录
      fileUtil.mkdir(zipFolder);
      // 生成测试文件
      for (let index = 0; index < 10; index++){
        let filePath = `${wx.env.USER_DATA_PATH}/test/hello${index}.txt`;
        fileList.push({ name: `hello${index}.txt`, path: filePath});
        const res = fs.writeFileSync( filePath, `测试数据${index+1}`, 'utf8' );
        console.log(res);
      }
      // 打包 zip
      fileUtil.zip(fileList, zipPath, console.log);
      // 保存 zip
      wx.saveFileToDisk({ filePath: zipPath, success: console.log, fail: console.error });
    } catch(e) {
      console.error(e)
    }
  }

测试效果

在这里插入图片描述
保存 ZIP 懒得开真机调试录动图了。功能是OK的。

开发环境查看生成的 zip

  1. 先打开开发环境的文件系统所指向的目录
    在这里插入图片描述
  2. 找到 ${wx.env.USER_DATA_PATH} 对应的目录
    在这里插入图片描述
  3. 根据我们自定的路径找到生成的测试文件
    在这里插入图片描述

参考资料

jszip:一个使用JavaScript创建、读取和编辑.zip文件的库,带有一个可爱而简单的API。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
### 回答1: 微信小程序模版合集下载包含了160个微信小程序源码.zip和35个行业-微信小程序源码.zip。这些模板可以帮助开发者快速开发小程序,省去不必要的时间和精力。 在160个微信小程序源码.zip中,包含了各种类型的小程序模板,比如美食、酒店、外卖、婚礼、房产、教育等,开发者可以根据自己的需求选择合适的模板进行二次开发。这些模板已经包含了基本的功能和页面,例如登录、注册、商品展示、订单管理等,开发者只需要将自己的数据和逻辑接入即可。 35个行业-微信小程序源码.zip则是更加针对性的模板,专门为某些行业或者特定领域设计的小程序模板。比如医院、汽车、健身、商城等,这些模板已经适配了相应行业的需求和特点,包含了更多的功能和页面,可以直接拿来使用或者进行修改。 总之,微信小程序模版合集下载是非常有用且方便的资源。对于小程序开发者来说,这些模板可以节省很多时间和精力,让开发更加高效和轻松。同时,这些模板也可以作为学习的参考,对初学者有很大的帮助。 ### 回答2: 微信小程序已成为越来越多企业和个人的选择,为这些用户提供方便、实用的微信小程序源码,能大大缩短开发时间,降低开发成本。本次提供的微信小程序模版合集下载包含 160 个微信小程序源码,涵盖多种类型的小程序,包括商城、社交、新闻资讯、工具等等。另外,35 个行业-微信小程序源码.zip 包含各类小程序,针对不同的行业开发,如美食、旅游、教育等等。这些小程序源码具有良好的交互性、个性化定制功能、良好的用户体验,且可快速部署上线,极大地提高了开发效率和部署速度。如果您正在开发微信小程序,那么这些源码就是不可多得的帮手,它将为您尽可能地节省时间和精力。同时,这些源码支持二次开发和定制,您可根据自己的需求进行修改和扩展,并快速上线。如果您有任何问题和需求,可以随时联系我们,我们将为您提供实时帮助和技术支持。 ### 回答3: 微信小程序模版合集下载是一种非常方便的服务,它能够方便用户下载不同种类的微信小程序模版。本次提供的微信小程序模版合集包括160个微信小程序源码和35个行业-微信小程序源码。这些源码涵盖了不同行业的微信小程序,用户可以根据自己的需求选择相应的模版并进行定制。 160个微信小程序源码.zip中包括了各类微信小程序,比如电商、社交、餐饮、教育、医疗等,这些模版的设计风格及功能设置均有所不同,用户可以根据自己的需求选择相应的模版并进行二次开发。 35个行业-微信小程序源码.zip中包含了不同行业的微信小程序,比如旅游、汽车、电子商务、婚庆、美容等,这些模版中所包含的信息、功能及呈现方式都是与其所在行业相关的,可以让用户更好地进行定制和二次开发。 总之,微信小程序模版合集下载为微信小程序的开发提供了便利,开发者可以根据自己的需求选择相应的模版并进行二次开发,从而快速构建微信小程序。同时,这些模版也为其他用户提供了更为丰富的微信小程序,能够更好地满足用户的需求。
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

笑虾

多情黯叹痴情癫。情癫苦笑多情难

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值