1.单个下载(开始是导出按钮 下载显示进度条)

html
- <el-button @click.stop="exportReport(scope.row, scope.index)"
- v-if="!scope.row.schedule" icon="el-icon-download"
- size="small" type="text"style="color: #409eff">导出报告
- el-button>
- <el-progress style="width: 60px;display:inline-block;margin-left: 20px;"
- v-else :text-inside="true" :stroke-width="20"
- :percentage="scope.row.scheduleNumber" status="success" />
因为接口没有返回schedule和scheduleNumber数据只是前端需要 用来判断显示 按钮还是进度条的所以就手动给数组添加响应式数据
- this.data.map((item, index) => {
- this.$set(item, 'schedule', false);
- this.$set(item, 'scheduleNumber', 0);
- return item;
- });
js部分
- exportReport(row) {
- let data=this.visible?this.selectionList:this.data
- // 自己封装的方法
- downloadGet('/api/blade-robot/siteInfo/export-template','巡检报告', this.schedule, row).then(() => {
- data.forEach((x) => {
- if (x.id === row.id) {
- x.schedule = false
- }
- })
- })
- },
- schedule(progressEvent, row) {
- // 回调的progressEvent参数里有一个progressEvent.loaded和progressEvent.total两个参数,分别意思为已下载的文件大小和总文件大小
- // 因为total一直为0,经研究发现需要后端传给我ContentLength到response里这个值才会有值
- // 然而又发现后端使用的是minio这个文件服务器,所以这个文件大小太难获取了,所以我决定不改后端,直接写死了文件大小
- setTimeout(() => {
- let data=this.visible?this.selectionList:this.data
- data.forEach((x) => {
- if (x.id === row.id) {
- x.schedule = true
- x.scheduleNumber = Math.round(progressEvent.loaded / 3715 * 100)
- if( x.schedule == true){
- setTimeout(() => {
- x.schedule = false
- }, 2000);
- }
- }
- })
- }, 2000);
- },
downloadGet方法
- export const downloadGet = (url, filename, callback, callbackParameter)=> {
- return request({
- url:url,
- method: 'get',
- responseType: 'blob',
- timeout: 120000,
- // 下载的实时回调,axios里的
- onDownloadProgress: (a) => {
- if (callback) {
- callback(a, callbackParameter)
- }
- }
- }).then((r) => {
- // 下面的代码就是拿到字节流后转为文件的方法,想研究的可以自行百度
- const content = r.data
- const blob = new Blob([content],{type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'})
- if ('download' in document.createElement('a')) {
- const elink = document.createElement('a')
- elink.download = filename
- elink.style.display = 'none'
- elink.href = URL.createObjectURL(blob)
- document.body.appendChild(elink)
- elink.click()
- URL.revokeObjectURL(elink.href)
- document.body.removeChild(elink)
- }else if (typeof window.navigator.msSaveBlob !== 'undefined'){
- // IE
- let blob = new Blob([content], {type: 'application/force-download'});
- navigator.msSaveBlob(blob, filename)
- }else {
- // Firefox
- var file = new File([content], filename, {type: 'application/force-download'});
- window.open(URL.createObjectURL(file));
- }
- }).catch((r) => {
- console.error(r)
- })
- }
以上就可以实现每行下载时候去显示进度条了
2.批量下载弹框
弹框html
- <el-dialog title="批量导出巡检报告" @close="toClose"
- :close-on-click-modal="false" :visible="visible" lock-scroll append-to-body
- width="600px" :modal-append-to-body="false">
- <el-table :data="selectionList" border style="width: 100%">
- <el-table-column type="index"label="序号" width="50">el-table-column>
- <el-table-column prop="id" label="文件名称">
- <template slot-scope="scope">
- <span>{{scope.row.id}}巡检报告span>
- template>
- el-table-column>
- <el-table-column prop="scheduleNumber" label="下载进度">
- <template slot-scope="scope">
- <el-progress :percentage="scope.row.scheduleNumber" :text-inside="true" :stroke-
- width="20" status="success">el-progress>
- template>
- el-table-column>
- el-table>
- el-dialog>
js
- import { deepClone } from "@/util/util";//引入深拷贝方法
- //表格选中多个
- selectionChange(list) {
- this.selectionList = deepClone(list);
- },
- //点击批量下载方法
- handleDelete() {
- if (this.selectionList.length === 0) {
- this.$message.warning("请选择至少一条数据");
- return;
- }
- this.$confirm("确定将选择数据批量导出巡检报告?", {
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- type: "warning"
- })
- .then(() => {
- this.$nextTick(() => {
- this.visible=true
- this.selectionList.forEach(item=>{
- this.exportReport(item)
- })
- });
- })
- .catch(() => {});
- },
- //关闭弹框清空选中状态
- toClose(){
- this.visible=false
- this.onLoad(this.page);
- this.$refs.crud.toggleSelection();
- },
深拷贝方法(不使用深拷贝的话弹框和表格进度条会冲突!!!!!)
- /**
- * 对象深拷贝
- */
- export const deepClone = data => {
- var type = getObjType(data)
- var obj
- if (type === 'array') {
- obj = []
- } else if (type === 'object') {
- obj = {}
- } else {
- //不再具有下一层次
- return data
- }
- if (type === 'array') {
- for (var i = 0, len = data.length; i < len; i++) {
- obj.push(deepClone(data[i]))
- }
- } else if (type === 'object') {
- for (var key in data) {
- obj[key] = deepClone(data[key])
- }
- }
- return obj
- }
最后就是设置导出文件的类型在上文封装下载方法中 type设置的
const blob = new Blob([content],{type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'})
关于 Blob 的 content-type 的部分媒体类型 可以参照下面!!!!!
- ".*"="application/octet-stream"
- ".001"="application/x-001"
- ".301"="application/x-301"
- ".323"="text/h323"
- ".906"="application/x-906"
- ".907"="drawing/907"
- ".a11"="application/x-a11"
- ".acp"="audio/x-mei-aac"
- ".ai"="application/postscript"
- ".aif"="audio/aiff"
- ".aifc"="audio/aiff"
- ".aiff"="audio/aiff"
- ".anv"="application/x-anv"
- ".asa"="text/asa"
- ".asf"="video/x-ms-asf"
- ".asp"="text/asp"
- ".asx"="video/x-ms-asf"
- ".au"="audio/basic"
- ".avi"="video/avi"
- ".awf"="application/vnd.adobe.workflow"
- ".biz"="text/xml"
- ".bmp"="application/x-bmp"
- ".bot"="application/x-bot"
- ".c4t"="application/x-c4t"
- ".c90"="application/x-c90"
- ".cal"="application/x-cals"
- ".cat"="application/vnd.ms-pki.seccat"
- ".cdf"="application/x-netcdf"
- ".cdr"="application/x-cdr"
- ".cel"="application/x-cel"
- ".cer"="application/x-x509-ca-cert"
- ".cg4"="application/x-g4"
- ".cgm"="application/x-cgm"
- ".cit"="application/x-cit"
-
- ".doc"="application/msword"
- ".docx"="application/vnd.openxmlformats-officedocument.wordprocessingml.document"
- ".rtf"="application/rtf"
- ".xls"="application/vnd.ms-excel application/x-excel"
- ".xlsx"="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
- ".ppt"="application/vnd.ms-powerpoint"
- ".pptx"="application/vnd.openxmlformats-officedocument.presentationml.presentation"
- ".pps"="application/vnd.ms-powerpoint"
- ".ppsx"="application/vnd.openxmlformats-officedocument.presentationml.slideshow"
- ".pdf"="application/pdf"
- ".swf"="application/x-shockwave-flash"
- ".dll"="application/x-msdownload"
- ".exe"="application/octet-stream"
- ".msi"="application/octet-stream"
- ".chm"="application/octet-stream"
- ".cab"="application/octet-stream"
- ".ocx"="application/octet-stream"
- ".rar"="application/octet-stream"
- ".tar"="application/x-tar"
- ".tgz"="application/x-compressed"
- ".zip"="application/x-zip-compressed"
- ".z"="application/x-compress"
- ".wav"="audio/wav"
- ".wma"="audio/x-ms-wma"
- ".wmv"="video/x-ms-wmv"
- ".mp3, .mp2, .mpe, .mpeg, .mpg"="audio/mpeg"
- ".rm"="application/vnd.rn-realmedia"
- ".mid, .midi, .rmi"="audio/mid"
- ".bmp"="image/bmp"
- ".gif"="image/gif"
- ".png"="image/png"
- ".tif, .tiff"="image/tiff"
- ".jpe, .jpeg, .jpg"="image/jpeg"
- ".txt"="text/plain"
- ".xml"="text/xml"
- ".html"="text/html"
- ".css"="text/css"
- ".js"="text/javascript"
- ".mht, .mhtml"="message/rfc822"
大概率就OK了!!!!!等待大文件联调看效果!!!!!!(其中的延时器是因为我现在测试的文件只有4kb没有进度条效果 所以出此下策 请辨别哦~~~~)