当前位置: 首页 > news >正文

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

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

  • 场景
  • 分享代码片段
  • 导入 JSZip
  • 创建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 {// 实例化 jszipvar 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 形式压的缩包数据写入二进制文件,生成 zipprogress({ 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,   // 每块大小默认 1Mprogress: 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{// 否则分块写入,并调用进度更新 callbackreturn 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);}// 打包 zipfileUtil.zip(fileList, zipPath, console.log);// 保存 zipwx.saveFileToDisk({ filePath: zipPath, success: console.log, fail: console.error });} catch(e) {console.error(e)}}

参考资料

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

相关文章:

  • json转yolo格式
  • RabbitMQ 消息中间件 消息队列
  • flask之文件上传
  • 双目光波导AR眼镜_AR智能眼镜主板PCB定制开发
  • P5743 【深基7.习8】猴子吃桃
  • 什么是https加密协议?
  • 基于个微机器人的开发
  • 注意力机制的快速学习
  • 新华三数字大赛复赛知识点 VLAN基本技术
  • 使用 HPA 和 TopologySpreadConstraints 实现可用区间等比扩容
  • http与apache
  • Linus:我休假的时候也会带着电脑,否则会感觉很无聊
  • 什么是ElasticSearch中的过滤器?
  • 搭配君正主控芯片测评:创想三维物有所值,让你玩3D打印,而不是玩3D打印机
  • 解决 Element-ui中 表格(Table)使用 v-if 条件切换后,表格的列的筛选不显示了
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【MySQL经典案例分析】 Waiting for table metadata lock
  • angular2 简述
  • Golang-长连接-状态推送
  • JAVA 学习IO流
  • laravel5.5 视图共享数据
  • TiDB 源码阅读系列文章(十)Chunk 和执行框架简介
  • use Google search engine
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 从零开始在ubuntu上搭建node开发环境
  • 前端相关框架总和
  • 如何设计一个比特币钱包服务
  • 试着探索高并发下的系统架构面貌
  • 微信支付JSAPI,实测!终极方案
  • 想写好前端,先练好内功
  • 怎么把视频里的音乐提取出来
  • ​io --- 处理流的核心工具​
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​你们这样子,耽误我的工作进度怎么办?
  • ​软考-高级-系统架构设计师教程(清华第2版)【第9章 软件可靠性基础知识(P320~344)-思维导图】​
  • ​一、什么是射频识别?二、射频识别系统组成及工作原理三、射频识别系统分类四、RFID与物联网​
  • #Lua:Lua调用C++生成的DLL库
  • (AngularJS)Angular 控制器之间通信初探
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (三)uboot源码分析
  • (一)Java算法:二分查找
  • (转载)深入super,看Python如何解决钻石继承难题
  • . Flume面试题
  • .aanva
  • .form文件_SSM框架文件上传篇
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET 使用 XPath 来读写 XML 文件
  • .NET 中让 Task 支持带超时的异步等待
  • .NET处理HTTP请求
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • @RequestParam,@RequestBody和@PathVariable 区别
  • [2016.7 test.5] T1
  • [AutoSAR 存储] 汽车智能座舱的存储需求
  • [bzoj 3534][Sdoi2014] 重建