Download files according to the file format (file stream) returned by the backend

Hey hey, I'm here again. Today, the topic we are discussing is downloading files. The current requirements are as follows: the front end writes a file upload page, sets an upload button, and after opening, uses the el-upload component to upload the Excel file. After the backend receives the file, it also returns a file stream to the frontend.

I won’t talk about how to do the backend specifically, let’s just talk about what operations the frontend needs to do. We use vue scaffolding, and write the html code in the template as follows:

<template>
	<div class="box">
		<el-card style="width:80%" class="header-card">
			<template #header>
				<h3>上传文件</h3>
			</template>
            <el-button size="mini" @click="openUpload" type="success" icon="el-icon-upload">点击上传</el-button>
		</el-card>
		<el-dialog
			:visible.sync="importDialog"
			width="1200px"
			:close-on-click-modal="false"
			center
            destroy-on-close
		>
			<div style="text-align: left" slot="title">index上传</div>
			<el-upload
				drag
				v-loading="importLoading"
				action
				:before-upload="beforeSampleImportUpload"
				:http-request="handleSampleImportUploading"
			>
				<i class="el-icon-upload"></i>
				<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
				<div class="el-upload__tip" slot="tip">请上传excel文件!</div>
			</el-upload>
		</el-dialog>
	</div>
</template>

And configure the style:

<style lang="scss" scoped>
.box{
    //背景占满全屏
    min-height: 100%;
    background-image: url(../assets/bg0.jpg);
    background-repeat: no-repeat;
    background-size: cover;
    //卡片内容水平垂直居中
    display: flex;
    justify-content: center;
    align-items: center;
}
:deep(.el-upload--text) {
  width: 100% !important;
}
:deep(.el-upload-dragger) {
  width: 100% !important;
}
.el-upload:before {
  content: "";
}
.header-card{
    margin: 0 0.5rem 0;
}
:deep(.el-card__body){
    min-height: 150px;
}
</style>

Now, the resulting web page is as follows:

 Below is the js code:

<script>
//引入axios,也可以通过拦截器interceptors进行封装
import axios from 'axios'
//引入vuex里的数据(这里专门存的baseurl地址,如果封装了axios,就不需要这一步,这里讲最基础的做法)
import { mapState } from 'vuex';
export default {
    data() {
        return {
            //对话框的显示
            importDialog: false,
            //对话框的loading
            importLoading: false
        };
    },
    methods: {
        //在实例文件导入前做的事
        beforeSampleImportUpload(file) {
            //声明变量,判断是否是Excel文件
            const isExcel =
                file.type ===
                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" || "application/vnd.ms-excel";
            //如果不是的话,就不允许上传,并提示信息
            if (!isExcel) {
                this.$message({
                    message: "上传失败,只接受excel文件!",
                    type: "warning",
                    showClose: true,
                });
                return false;
            }
            return true;
        },
        //在实例文件导入的过程中(调接口)
        handleSampleImportUploading(item) {
            let formdata = new FormData();
            //file字段就是后端接收的字段,值为item.file
            formdata.append("file", item.file);
            //开始显示加载中
            this.importLoading = true;
            //调接口
            axios({
                method: 'post',
                url: this.globalBaseUrl + '/xxx', //这里填写url
                headers: {
                    'Content-Type': 'multipart/form-data'
                },
                data: formdata
            }).then(res=>{
                 //(文件流)
                //设置后缀,根据type设置相应的后缀名称(".xls"/".xlsx")
                let suffix;
                if(res.data && res.data.type=="application/vnd.ms-excel"){
                    suffix = ".xls"
                }else if(res.data && res.data.type=="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"){
                    suffix = ".xlsx"
                }
                let url = window.URL.createObjectURL(new Blob([res.data], { type: suffix }));
                //弄出一个a标签,隐藏起来,点击后下载文件并移除这个anchor的html标签
                let a = document.createElement('a');
                a.style.display = 'none';
                a.href = url;
                a.setAttribute('download', `1${suffix}`);
                document.body.appendChild(a);
                a.click();
                url = window.URL.revokeObjectURL(url);  //释放内存
                document.body.removeChild(a)
            }).catch(()=>{
                this.$notify({
                    title:"上传失败",
                    type:"error",
                    duration:3500,
                    showClose:true
                })
            }).finally(()=>{
                //关闭加载和对话框
                this.importLoading = false;
                this.importDialog = false;
            })
        },
        openUpload(){
            //打开对话框
            this.importDialog = true
        }
    },
    computed: {
        ...mapState(["globalBaseUrl"])
    },
};
</script>

If that's the case, it's done. The file will be downloaded directly. Do not copy the code directly from beginning to end, but operate according to the actual application needs.

Guess you like

Origin blog.csdn.net/weixin_68067009/article/details/130198457