步骤:
第一步:
npm install JSZip
npm install FileSaver
然后在组件中引入
import JSZip from "jszip";
import FileSaver from "file-saver";
第二步:
创建一个function绑定点击事件
在浏览器中创建zip
//创建zip实例化对象
const zip = new JSZip();
//调用实例化的原型链function设置自定义解压目录文件名
let imgsss = zip.folder('目录名');
第三步:
编写业务逻辑代码 批量导出一般都会拿到一个urlList处理
1.遍历urllist将url通过js原生对象new XMLHttpRequest() 创建一个请求实例 将url做为请求接口发出请求得到base64 bold格式的文档字符串(就是这个url的所有内容如文件大小 文件格式等数据)
2.截取第一个 , (逗号)之后的所有字符串已参数的形式插入zip.file(‘文件名’,base64参数)
3.在异步 zip.generateAsync中传入({type:blod})方法中.then拿到生成的二进制流,以参数的形式传入 FileSaver.saveAs(二进制流, '自定义压缩包名称'.zip
) 这样批量导出就做好了
4.效果图
5.附上源码 技术栈 vue-element 咳咳:刚写完就来分享了 有强迫症的自己可以多封装几下 我后续自己的优化就不发了
<template>
<el-form ref="formSave" :label-position="labelPosition" label-width="120px">
<el-dialog :title="returnFile().title" :visible.sync="dialogFormVisible">
<el-row class="marBom">
<el-col
:sm="12"
:md="8"
:lg="6"
v-for="(item,index) of fileList"
:key="index"
class="itemMarBom"
>
<el-form-item :label="'是否导出'+returnFile().filterList(item.bookCategory)+':'">
<el-radio-group v-model="item.yesOrNo">
<el-radio :label="'y'">是</el-radio>
<el-radio :label="'n'">否</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item>
<updata :fileUrl="item.fileUrl" :IsShowView="false" />
</el-form-item>
</el-col>
<el-col :lg="6" :sm="12"></el-col>
</el-row>
<el-button type="primary" @click="handleExportFile" >一键下载全部文件</el-button>
</el-dialog>
<el-button type="primary" style="margin-top:40px;" @click="handleFlogt" :disabled="fileList.length==0">一键下载</el-button>
</el-form>
</template>
<script>
import { getToken } from "@/api/axios";
import updata from "@/components/updata/updata";
import { deepClone } from "@/utils/index";
import JSZip from "jszip";
import FileSaver from "file-saver";
export default {
data() {
return {
url: null,
dialogFormVisible: false,
fileList: [],
labelPosition: "left",
};
},
watch: {
bookFileList: {
deep: true,
handler(list, ov) {
this.fileList = deepClone(
list.map(item => {
item.select = "n";
return item;
})
);
}
}
// setbookFileList(list,nl){
// console.log('list======')
// console.log(list)
// // this.fileList=list.map((item)=>{
// // item.select=0
// // return item
// // })
// }
// }
},
props: {
bookFileList: {
type: Array
},
returnFile: {
type: Function
}
},
components: {
updata
},
computed: {
isShowBtn() {
return true;
}
},
methods: {
handleExportFile() {
const zip = new JSZip();
let imgsss = zip.folder(`${this.returnFile().title}`);
let url = this.$store.state.user.setUpdataToken.url;
for (let index = 0; index < this.bookFileList.length; index++) {
if (this.bookFileList[index].yesOrNo == "y") {
const xhr = new XMLHttpRequest();
xhr.open("GET", url + this.bookFileList[index].fileUrl, true);
xhr.responseType = "blob";
xhr.setRequestHeader("Authorization", "Basic a2VybWl0Omtlcm1pdA==");
xhr.onload = () => {
if (xhr.status === 200) {
const reader = new FileReader();
reader.readAsDataURL(xhr.response);
reader.onload = e => {
console.log( e.target.result)
let resultBase64 = e.target.result.substring(e.target.result.indexOf(",") + 1);
console.log(resultBase64)
imgsss.file(this.bookFileList[index].fileUrl,resultBase64 , { base64: true });
};
}
};
xhr.send();
}
}
if (this.isShowBtn) {
setTimeout(() => {
zip.generateAsync({ type: "blob" }).then(content => {
console.log('=====')
console.log(content)
// 生成二进制流
FileSaver.saveAs(content, `${this.returnFile().title}.zip`); // 利用file-saver保存文件 自定义文件名
});
}, 1500);
}
},
handleFlogt() {
this.dialogFormVisible = true;
},
convertBase64UrlToBlob(base64) {
let urlData = base64.dataURL;
let type = base64.type;
let bytes = window.atob(urlData.split(",")[1]); //去掉url的头,并转换为byte
// let bytes = window.atob('33.jpg'); //去掉url的头,并转换为byte
//处理异常,将ascii码小于0的转换为大于0
let ab = new ArrayBuffer(bytes.length);
let ia = new Uint8Array(ab);
for (let i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob([ab], { type: type });
},
}
};
</script>
<style lang="scss" scoped>
.export-box {
border: 1px solid #cccccc;
box-sizing: border-box;
padding: 30px;
}
.marBom {
margin-bottom: 39px;
margin-top: 39px;
}
.itemMarBom {
margin-bottom: 20px;
}
.parent {
width: 100px;
height: 100px;
}
</style>