Vue项目-后端接口文件上传下载

本文介绍Vue项目中实现文件上传和下载的方法,包括使用二进制文件流下载、直接下载以及文件上传的具体实现步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、二进制文件流下载

1、axios配置
// 文件位置:@/utils/request.js

import axios from "axios"

let url = 'http://localhost:9999/'

const request = axios.create({
    baseURL: url,
    timeout: 5000, // 超时时间
})

// post请求默认数据格式
request.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";

// 请求拦截
request.interceptors.request.use(request => {
    var user = localStorage.getItem("currentUser");
    if (user) {
        user = JSON.parse(user);
        request.headers['Authorization'] = user.token
    }
    return request;
}, error => {
    return error
})

// 响应拦截
request.interceptors.response.use(
    (response) => {
        return response.data;
    },
    (error) => {
        return error;
    }
);

export default request

2、请求接口配置
// 文件位置:@/utils/api.js

import request from '@/utils/request.js'

exportLog(params) {
    return request.get("/api", { params, responseType: "blob" })
},


// 后端返回的是二进制文件流,必须要在请求时传入{{ responseType: "blob" }}参数

3、组件导出方法配置
<template>
    <div>
        <ul>
            <li>
                <span>时间 :</span>
                <el-date-picker
                size="mini"
                v-model="times"
                type="datetimerange"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                value-format="yyyy-MM-dd HH:mm:ss"
                >
                </el-date-picker>
            </li>

            <li>
                <el-button @click="export">导出</el-button>
            </li>
        </ul>
    </div>
</template>

<script>
import api from '@/utils/api.js'

export default {
    data(){
        return {
            times:[],
        }
    },
    methods:{
        export(){
            let params = {
                startTime:times[0],
                endTime:times[1]
            }

            api.exportLog(params).then((res) => {
                // 创建一个a标签
                const link = document.createElement("a");
                // 创建一个blob实例
                let blob = new Blob([res], { type: "application/x-excel" });
                // 隐藏a标签显示
                link.style.display = "none";
                // 生成url并添加到a标签的href属性上
                link.href = URL.createObjectURL(blob);
                // 下载的文件名称
                link.download = "logExport.xls";
                // 将a标签添加到body中
                document.body.appendChild(link);
                // 模拟点击a标签
                link.click();
                // 将a标签从body中移除
                document.body.removeChild(link);
                // 释放blob对象
                URL.revokeObjectURL(link.href);
              }).catch((error) => {
                this.$message({
                  message: error,
                });
              });
        }
    }
}
</script>

二、直接下载

1、组件导出方法配置
// 组件中请求,不过下载时不能重命名文件,只能下载后再修改文件名称

<template>
    <div>
        <ul>
            <li>
                <span>时间 :</span>
                <el-date-picker
                size="mini"
                v-model="times"
                type="datetimerange"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                value-format="yyyy-MM-dd HH:mm:ss"
                >
                </el-date-picker>
            </li>

            <li>
                <el-button @click="export">导出</el-button>
            </li>
        </ul>
    </div>
</template>

<script>
import api from '@/utils/api.js'

export default {
    data(){
        return {
            times:[],
        }
    },
    methods:{
        export(){
            // url拼接
            let url = `http://localhost:9999/api
                       ?startTime=${times[0]}
                       &endTime=${times[1]}`

            // 访问url下载文件
            window.location.href = url
        }
    }
}
</script>

三、文件上传

1、HTML
<template>
  <ModelAssembly
    v-if="show"
    title="文件上传"
    w="500px"
    h="400px"
    @close="closeWin">
    <div slot="content" class="uploadModel">
      <div class="uploadModelContent">
        <el-upload
          class="upload-demo"
          ref="upload"
          drag
          multiple
          action=""
          :limit="1"
          :auto-upload="false"
          :on-exceed="handleExceed"
          :on-change="handleChange">
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
          <!-- <div class="el-upload__tip" slot="tip">
            只能上传jpg/png文件,且不超过500kb
          </div> -->
        </el-upload>
      </div>

      <div class="uploadModelBtn">
        <el-button plain @click="closeWin" icon="el-icon-circle-close"
          >取消</el-button
        >
        <el-button type="primary" icon="el-icon-upload2" @click="confirm"
          >上传</el-button
        >
      </div>
    </div>
  </ModelAssembly>
</template>
2、JS
<script>
export default {
  name: "",
  components: {},
  props: {
    fileType: {
      type: String,
      default: "",
    },
    expId: {
      type: Number,
      default: null,
    },
  },
  data() {
    return {
      show: false,
      files: null,
    };
  },
  computed: {},
  created() {},
  mounted() {},
  methods: {
    // 上传文件
    confirm() {
      // 创建formData对象
      let formData = new FormData();
      formData.append("exp_id", this.expId);
      formData.append("file_type", this.fileType);
      formData.append("file", this.files.raw);

      this.$API
        .fileUploadRequest(formData)
        .then((res) => {
          if (res.code == 200) {
            this.$message.success("文件上传成功");
            this.$emit("callback");
          } else {
            this.$message.error(res.message ? res.message : "文件上传失败");
          }
        })
        .catch((error) => {
          console.log(error);
          this.$message.error("接口访问失败");
        });

      // 关闭窗口
      this.closeWin();
    },

    // 重新选择文件,覆盖已选中的文件
    handleExceed(file, fileList) {
      this.$set(fileList[0], "raw", file[0]); //raw就是指文件
      this.$set(fileList[0], "name", file[0].name); //name就是指文件名

      this.files = fileList[0];
    },

    // upload Change事件
    handleChange(file) {
      this.files = file;
    },

    // 打开窗口
    openWin() {
      this.show = true;
    },

    // 关闭窗口
    closeWin() {
      this.show = false;
    },
  },
};
</script>
3、CSS
<style lang="less" scoped>
.uploadModel {
  width: 100%;
  height: 100%;

  .uploadModelContent {
    width: 100%;
    height: calc(100% - 60px);
    display: flex;
    justify-content: center;
  }

  .uploadModelBtn {
    width: 100%;
    height: 60px;
    display: flex;
    align-items: center;
    justify-content: flex-end;
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值