Angular实现多份JSON数据生成独立文件后打包为ZIP下载
纯前端导出JSON数据为ZIP包方案
整套方案完全无需服务端支持,所有逻辑均在用户浏览器本地完成,无需使用你之前尝试的export-from-json包,仅依赖两个轻量前端工具库即可实现。
前置依赖安装
执行以下命令安装所需依赖:
npm install jszip file-saver # TypeScript项目额外安装类型定义 npm install @types/file-saver -D
如果不想引入额外依赖,也可以用原生API实现下载触发,后续会给出对应代码。
1. 单条数据生成独立文件
你不需要提前把文件写到用户本地磁盘,只需要在接口返回数据后,把每一条数据转换为内存中的Blob文件对象暂存即可,后续打包直接读取内存中的对象。
首先在组件/页面中声明一个变量暂存生成的文件列表,改造你原有的接口请求逻辑:
import JSZip from 'jszip'; import { saveAs } from 'file-saver'; // 暂存文件列表的变量 fileList: Array<{fileName: string, content: Blob}> = []; // 原有的接口请求逻辑 this.restapi.getData() .subscribe(results => { // 清空上一次请求生成的旧文件 this.fileList = []; for (const each of results) { // 单条JSON数据序列化为字符串,生成Blob对象,如需导出CSV/TXT等其他格式,修改此处内容和MIME类型即可 const blob = new Blob([JSON.stringify(each, null, 2)], { type: 'application/json' }); // 文件名取each.name,拼接对应后缀,注意提前过滤文件名中的非法字符(\/:*?"<>|)避免打包报错 const fileName = `${each.name.replace(/[\\/:*?"<>|]/g, '_')}.json`; this.fileList.push({ fileName, content: blob }); } });
提示:如果需要导出非JSON格式的单文件,只需要调整Blob构造函数的传入内容和type字段即可,比如导出CSV就传入拼接好的CSV字符串,type设为
text/csv;charset=utf-8。
2. 绑定按钮事件打包ZIP并触发下载
首先在页面模板中给下载按钮绑定点击事件,加个禁用状态避免无数据时点击:
<button (click)="handleExportZip()" [disabled]="fileList.length === 0">下载全部为ZIP</button>
然后在逻辑中实现打包下载的方法:
async handleExportZip() { if (this.fileList.length === 0) return; // 初始化ZIP实例 const zip = new JSZip(); // 遍历把所有单文件加入ZIP包 this.fileList.forEach(file => { zip.file(file.fileName, file.content); }); // 生成ZIP文件的Blob对象 const zipBlob = await zip.generateAsync({ type: 'blob', compression: 'DEFLATE', // 开启压缩 compressionOptions: { level: 6 } // 压缩等级1-9,数字越大压缩率越高耗时越长 }); // 方式1:用file-saver触发下载,简单省心 saveAs(zipBlob, `数据导出_${Date.now()}.zip`); // 方式2:原生API触发下载,不需要file-saver依赖,替换上面的saveAs即可 // const downloadUrl = URL.createObjectURL(zipBlob); // const a = document.createElement('a'); // a.href = downloadUrl; // a.download = `数据导出_${Date.now()}.zip`; // document.body.appendChild(a); // a.click(); // document.body.removeChild(a); // URL.revokeObjectURL(downloadUrl); }
补充说明
- 全流程所有数据处理、打包操作都在浏览器内存中完成,不会向服务端上传任何数据,完全可以纯前端部署使用
- 如果导出数据量较大(总大小超过500M/文件数超过1000),打包过程会占用浏览器主线程导致短暂卡顿,可以在打包时加全局loading提示用户
- 如果需要给ZIP内的文件分类建文件夹,只需要调用
zip.folder('文件夹名').file(...)即可把文件加入对应子目录
内容的提问来源于stack exchange,提问作者Chris T
相关产品推荐
相关产品推荐

