vue - 实现文件的上传-文档流下载详细过程

这篇具有很好参考价值的文章主要介绍了vue - 实现文件的上传-文档流下载详细过程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

  • 这个需求一般是在有合同的地方用,首先不止一个地方用我们应该把他封装成一个简易的全局组件,

  • 上传的时候封装成全局组件,传2个值,一个合同id,一个开关,下载的时候调用接口获取文档流下载

  • 注意看下面的文件上传下载-细节有详细的过程和遇到的问题和解决方案

效果图

接口配置

import request from '@/utils/request'
​
// 上传合同附件
export function uploadPDF (data) {
  return request({
    url: '/contractMsg/updatePDF',
    method: 'put',
    headers: { 'Content-Type': 'multipart/form-data' },
    data
  })
}
​
// 下载合同附件
export function download (id) {
  return request({
    url: `/contractMsg/getPDF/${id}`,
    method: 'get',
    //参数序列化 可加可不加
    paramsSerializer: params => {
      return qs.stringify(params)
    },
    //将二进制流转换成blob对象
    reponseType: 'blob',
    // 可加可不加
    headers: {
      'Content-Type': 'application/json;charset=UTF-8;'
    }
  })
}

文件上传下载-细节

文件上传时

1.全局注册组件-主页文章有

2.单向数据流的问题,要把开关值通知父组件关闭使用.sync语法糖,不然会报错。

3.跟Excel文件上传是一样道理,传递formdata类型给后端,记得在api二次封装时候设置formdata类型

4.最好在formdata传2个值,一个上传文件,一个文件id。方便下载。记得回显数据到父组件输入框

5.formdatad对象直接打印是空的,要这样打印 console.log("formdata", formdata.get("file"));

文件下载时

在网上看来很多文章一头雾水,自己试一下,在 这里记录一下。

首先第一点这个文件下载主要是后端写,我们只要传入id即可。但是我们要排查问题。

如果后端把这个接口写好了,在测试工具测试可以直接下载,并且返回结果返回文档流。那剩下就是前端问题。

代码是不能直接下载我们需要blob对象转一下,通过a标签来下载。

网上很多文章是说使用windows.URL就可以实现下载,但是会报undefined,查阅资料好像是说api废弃了,我们可以使用webkitURL是一样效果

还有就是如果我们有全局响应拦截的话,可能会过不去。因为后端可能没有放回状态码,只有文档流。那我们就要在request 响应拦截加上res != ' '(我们是判断code通过),axios会默认加一层data

如下例子

service.interceptors.response.use(
  res => {
    // axios默认加了一层data
    // 这个res包括这个请求响应回来的所有信息
    // 所有的接口请求都会回到这里
    // 获取到本次请求得到的数据
    const data = res.data
    // 会帮所有的请求打印
    // console.log(data);
    // 判断本次请求是否成功
    if (data.code === 200 || data != '') {
      // 如果响应成功,则正常给他返回数据
      return data
    } else {
      // 证明失败,我们需要让外面的catch被调用
      // 要让catch被调用,就要手动抛出一个错误,并把服务器返回的消息抛回去
      // Message.warning(data.message)
      return Promise.reject(data.message)
    }
  },
}

全局上传组件-全局components下

我的命名UploadAnnex/index.vue

<template>
  <el-dialog
    title="合同附件上传"
    :visible.sync="dialogVisible"
    width="40%"
    :before-close="handleClose"
  >
    <el-form ref="form" :model="form" size="small" label-width="80px">
      <el-form-item label="文件名称:">
        <el-input v-model="form.contitle"></el-input>
      </el-form-item>
      <el-form-item label="文件上传:">
        <div class="uppicture">
          <input type="file" class="upinput" ref="file" @change="showimg" />
          <i class="el-icon-plus" id="changes" @click="changeimg"></i>
          <p>上传合同文件附件</p>
          <el-button type="primary" class="uploadbutton" @click="addupload"
            >上传附件{{ id }}</el-button
          >
        </div>
      </el-form-item>
    </el-form>
​
    <span slot="footer" class="dialog-footer">
      <el-button @click="handleClose" style="background: #f7f7f7" size="small"
        >取 消</el-button
      >
      <!-- <el-button type="primary" @click="upload">确 定</el-button> -->
    </span>
  </el-dialog>
</template>
​
<script>
import { uploadPDF } from "@/api/client/administrator";
export default {
  name: "UploadAnnex",
  data() {
    return {
      form: {
        // 合同名称
        contitle: "",
      },
      formdata: {},
    };
  },
  props: {
    // 显示隐藏
    dialogVisible: {
      type: Boolean,
      //   必传
      required: true,
    },
    // 合同id
    id: {
      type: Number,
      //   必传
      required: true,
    },
  },
  methods: {
    // 关闭之前
    handleClose() {
      console.log("关闭之前");
      // .sync语法糖,单向数据流问题,
      // 父组件传递给子组件的数据,子组件直接修改会报错,需要传递给父组件修改
      this.$emit("update:dialogVisible", false);
    },
    // 输入款获取事件
    showimg() {
      const that = this;
      console.log(that.$refs.file);
      console.log(that.$refs.file.files[0]);
      // 文件名称复制
      that.form.contitle = that.$refs.file.files[0].name;
      // 声明一个formdata对象
      this.formdata = new FormData();
      // 赋值需要传递的文件-添加到formdata对象中
      this.formdata.append("file", that.$refs.file.files[0]);
      // 赋值需要传递文件id
      this.formdata.append("id", this.id);
      // 打印formdata对象
       console.log("formdata", formdata.get("file"));
    },
    // 图标触发输入框事件
    changeimg() {
      // 点击图标时候,触发input选择文件按钮
      this.$refs.file.dispatchEvent(new MouseEvent("click"));
    },
    // 上传附件
    async addupload() {
      // 上传文文件提示,未选择文件提示用户
      if (!this.form.contitle) {
        return this.$message.warning("请先在左侧上传文件");
      }
      const res = await uploadPDF(this.formdata);
      console.log("合同上传", res);
      // 回显文件名称给父组件的form表单
      this.$emit("updata", this.form.contitle);
      //  清空表单
      this.form.contitle = "";
      this.formdata = {};
      // 关闭弹框
      this.handleClose();
    },
  },
};
</script>
​
<style lang="scss" scoped>
::v-deep .el-dialog {
  border-radius: 10px;
  .el-dialog__header {
    border-radius: 9px 9px 0 0;
    background-color: #1488c6;
    padding: 8px 20px;
    .el-dialog__title {
      color: white;
      font-size: 16px;
    }
​
    .el-dialog__headerbtn {
      top: 12px;
      i {
        color: white;
      }
    }
  }
  .el-dialog__footer {
    text-align: center;
  }
  .el-dialog__body {
    padding: 12px;
  }
  .uppicture {
    width: 120px;
    height: 120px;
    border: 1px solid #717376;
    position: relative;
    cursor: pointer;
    input {
      width: 100%;
      height: 100%;
      vertical-align: middle;
      opacity: 0;
    }
    i {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      font-size: 30px;
      // background-color: skyblue;
    }
    p {
      position: absolute;
      bottom: -2px;
      left: 50%;
      word-break: keep-all;
      transform: translate(-50%);
    }
    .uploadbutton {
      position: absolute;
      bottom: 0;
      margin-left: 20px;
    }
    &:hover {
      color: #2da9fa;
      border: 1px solid #2da9fa;
      p {
        color: #2da9fa;
      }
    }
  }
}
</style>

使用组件-父组件

 <!-- 上传组件使用 -->
    <UploadAnnex
      :dialogVisible.sync="dialogannex"
      :id="uploadid"
      @updata="updata = $event"
    ></UploadAnnex>

父组件数据

// 上传组件开关
      dialogannex: false,
      // 合同id
      uploadid: 2,
      updata: "",

父组件回显文件名称和使用结构

<el-form-item label="合同扫描件:" >
              <el-input
                v-model="updata"
                style="width: 350px; margin-right: 10px"
              ></el-input>
              <el-button @click="download">下载</el-button>
              <el-button @click="addupload">上载</el-button>
            </el-form-item>

父组件事件

link.download 是下载文件的名字,可能会因为编码格式原因中文名字会乱码。所以可以在这条数据文件上传时把名字在数据库存一次,查单条的时候放回来,下载时候重新赋值名字

import { download } from "@/api/client/administrator";
 
 // 上传组件按钮
    addupload() {
      this.dialogannex = true;
    },
    // 下载文件
    async download() {
      await download(this.uploadid)
        .then((res) => {
          console.log("res", res);
          let blob = new Blob([res.data], {
            type: "application/pdf;",
          });
          console.log("blob", blob);
          let filename = "css.doc";
          if (window.navigator.msSaveOrOpenBlob) {
            navigator.msSaveBlob(blob, filename);
          } else {
            var link = document.createElement("a");
            link.href = webkitURL.createObjectURL(blob);
            link.download = filename;
            link.click();
            webkitURL.revokeObjectURL(link.href);
          }
        })
        .catch((err) => {
          console.log("错误信息", err);
        });
    },

总结:

经过这一趟流程下来相信你也对 vue - 实现文件的上传-文档流下载详细过程 有了初步的深刻印象,但在实际开发中我 们遇到的情况肯定是不一样的,所以我们要理解它的原理,万变不离其宗。加油,打工人!

什么不足的地方请大家指出谢谢 -- 風过无痕文章来源地址https://www.toymoban.com/news/detail-423411.html

到了这里,关于vue - 实现文件的上传-文档流下载详细过程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Vue3 - 超详细 “纯前端“ 将文件上传到阿里云 OSS 对象存储,最新阿里云 SDK 上传音频、视频、图片、文档、office 等(保姆级详细示例源码教程,每行代码都有注释小白一看就懂)

    网上的教程大部分都过时了,各种不规范的写法五花八门(各种文件引入关系贼难改),对于新手来说真的无从下手。 本文站在新手的角度, 在 vue3 项目开发中,超详细 “纯前端(无需后端)” 上传各种图片图像、文档、音视频文件、压缩包到阿里云oss存储,利用 SDK 前端

    2024年02月03日
    浏览(30)
  • 【java】java实现大文件的分片上传与下载(springboot+vue3)

    源码: https://gitee.com/gaode-8/big-file-upload 演示视频 https://www.bilibili.com/video/BV1CA411f7np/?vd_source=1fe29350b37642fa583f709b9ae44b35 对于超大文件上传我们可能遇到以下问题 • 大文件直接上传,占用过多内存,可能导致内存溢出甚至系统崩溃 • 受网络环境影响,可能导致传输中断,只能重

    2024年02月02日
    浏览(42)
  • Vue项目中大文件切片上传实现秒传、断点续传的详细实现教程

    在Vue项目中,大图片和多数据Excel等大文件的上传是一个非常常见的需求。然而,由于文件大小较大,上传速度很慢,传输中断等问题也难以避免。因此,为了提高上传效率和成功率,我们需要使用切片上传的方式,实现文件秒传、断点续传、错误重试、控制并发等功能,并

    2024年02月12日
    浏览(41)
  • antd+Vue 3实现table行内upload文件图片上传【超详细图解】

    目录 一、背景 二、效果图 三、代码 一名被组长逼着干前端的苦逼后端,在一个晴天霹雳的日子,被要求前端订单产品实现上传产品图片并立刻回显图片。

    2024年04月11日
    浏览(28)
  • SpringBoot整合hdfs,实现文件上传下载删除与批量删除,以及vue前端发送请求,实现前后端交互功能;

    部分工具类代码参考文章:https://blog.csdn.net/qq_27242695/article/details/119683823 前端实现效果 HDFSController HDFS FileInterface (文件接口) HDFS FileImplService (文件接口实现类) HDFSConfig(从yaml读取文件) HDFSUTils 前端vue代码:

    2024年02月16日
    浏览(67)
  • SpringBoot+vue文件上传&下载&预览&大文件分片上传&文件上传进度

    SpringBoot+vue 大文件分片下载 Blob File spark-md5根据文件内容生成hash 大文件分片上传(批量并发,手动上传)vue组件封装-form组件 vue上传大文件/视频前后端(java)代码 springboot+vue自定义上传图片及视频 SpringBoot + VUE实现前台上传文件获取实时进度( 使用commons-fileupload设置上传监听

    2024年02月05日
    浏览(63)
  • elementUI自定义上传文件(前端后端超详细过程)

    elementUI自定义上传文件(前端后端超详细过程) 简介 : 自定义 上传文件并与其他参数一同提交到后台( 主要使用axios ) 简单介绍组件( upload)的属性(熟悉参数的直接略过) 总结elmentUI一下它的使用和常用属性的作用。 主要目的自定义上传文件 2.1 组件代码 2.2 data中的属性

    2024年02月02日
    浏览(28)
  • elementUI自定义上传文件 前端后端超详细过程

    下面是使用Element UI自定义上传文件的前后端详细过程: 前端过程: 引入Element UI组件库:在前端项目中引入Element UI库,可以通过CDN引入或者通过npm安装并导入。 创建上传组件:在前端代码中创建一个上传组件,可以使用 el-upload 组件来实现文件上传功能。在组件中设置上传

    2024年02月11日
    浏览(29)
  • 接口自动化测试:文件上传/下载(最详细)

    我们在做接口自动化测试的时候,经常会碰到文件上传接口和文件下载接口。那么,文件接口跟普通接口有什么区别呢?又该如何实现呢? 文件上传/下载接口与普通接口类似,但是有细微的区别。 如果需要发送文件到服务器,例如:上传文档、图片、视频等,就需要发送二

    2024年02月07日
    浏览(34)
  • Vue2-文件上传、下载场景功能

    在项目开发中,上传文件的应用场景非常的多,一般情况下,上传的接口都是由公司内部自己开发一套适用于任何场景都可以使用的接口,但是这意味着该接口所涉及到的工作量与技术点就非常的多,且不稳定。于是大公司选择了前者自己研发,小公司则选择了性价比更高的

    2024年02月07日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包