jszip
公司最近会用到文件夹的上传下载,但是文件夹是无法直接上传的,只能先压缩为zip包,下载也是只能是zip包。
下面会讲到具体实际项目中的流程操作
安装依赖
公司使用的是angular开发,所以前端代码更多的是原生html的事件触发写法。
安装jszip
npm install jszip
官方示例如上,根据你实际项目中的开发语言选择对应的引入使用方式。
下载
async download() {
// 引入使用jszip
const JSZip = require("jszip");
const zip = new JSZip();
console.log(zip,'zip')
// 此处是我项目中的逻辑,获取文件夹id,通过文件夹id调用接口获取文件流
for (let i = 0; i < selectedList.length; i++) {
const folderResult = await this.api.get(`/download/?folderId=${selectedList[i].id}`);
console.log(folderResult,'folderResult')
if (folderResult.length > 0) {
for (let j = 0; j < folderResult.length; j++) {
// 这里需要注意因为我需要组成自己的zip文件包和选中的文件夹层级相同,所以先获取了文件夹名称,再通过/隔开层级
// 就好比你在找寻某个文件时的路径
// JSON.stringify(folderResult[j].Data) 就是我需要的json文件内容
console.log(`${selectedList[i].title}/${folderResult[j].Title}.json`)
zip.file(`${selectedList[i].title}/${folderResult[j].Title}.json`, JSON.stringify(folderResult[j].Data));
}
}
}
zip.generateAsync({ type: "blob" }).then((content: any) => {
console.log(content,'content')
saveAs(content, "测试.zip");
});
}
下载总结
- 通过接口返回对应文件内容。
- 通过 zip.file() 方法组成自己需要的文件格式内容。
- 通过 zip.generateAsync 方法获取content内容。
- saveAs 进行下载即可。
上传
<input type='file' id='folderUploadInput' accept="application/zip" name="dashupload" class="hide" >
<button id="browse_btn" class="btn gf-form-btn btn-success plugin_btn" ng-click='ctrl.folderBrowseBtn()'>上传</button>
//通过button触发input的change事件获取上传file内容
folderBrowseBtn() {
document.getElementById('folderUploadInput').click();
document.getElementById('folderUploadInput').addEventListener('change', (plugin: any) => {
this.folderUpload(plugin);
});
}
async folderUpload(plugin: any) {
const JSZip = require("jszip");
const iconv = require('iconv-lite');
const zip = new JSZip();
console.log(plugin.target.files,'plugin.target.files')
if (plugin.target.files && plugin.target.files.length > 0) {
const zipData = await zip.loadAsync(plugin.target.files[0], {
decodeFileName: (bytes: any) => {
console.log(bytes,'bytes')
// 这里必须些gbk 否则中文就会是乱码
return iconv.decode(bytes, 'gbk');
}
});
console.log(zipData,'zipData')
zipData.forEach(async (relativePath: any, file: any) => {
console.log(relativePath,file,'file')
//有file.dir为文件夹名称
if (file.dir && file.name) {
this.fromList.push({
text: file.name.split('/')[0],
value: file.name.split('/')[0],
data: []
});
};
//没有file.dir为文件夹的内容
if (!file.dir) {
//此处的string意思为将内容转为string类型呈现
zip.file(file.name).async("string").then((res: any) => {
console.log(res,'res')
let fileName: any;
if (file.name) {
fileName = file.name.split('/');
}
const fromInfo = this.fromList.find((it: any) => it.value === fileName[0]);
if (fromInfo) {
fromInfo.data.push({
name: file.name.split('/')[1],
content: res
});
}
});
}
});
}
//这里就是我最终组合的文件内容与格式
console.log(this.fromList,'fromList')
this.scope.$apply();
}
因为我这里项目逻辑关系,所以最后我只需要获取到对应的文件夹json内容,然后进行字符串解析,调用接口将json文件上传就可以了。
如果需要看每个json文件的同学可以参考这篇,逻辑都是一样只是在最后将创建File对象,将json文件个个上传。
上传总结
- 上传获取zip文件file。
- 通过 zip.loadAsync 获取zip压缩包目录结构和内容。
- 通过 zip.file 传入json路径获取具体的内容。
- 根据项目实际情况,进行不同处理。