vue通过el-upload 实现单、多文件上传

目录

1.代码实现

2.常见问题:


话不多说,直接上代码,文章最后附上实现过程中可能出现的问题。

1.代码实现

前台: 

<template>
    <el-form ref="form" :model="form" label-width="150px">
        <el-form-item label="申请人" prop="applyName">
            <el-input v-model="applyName"></el-input>
        </el-form-item>
       
        <el-form-item label="导入文件" prop="uploadFile">
            <el-upload v-model="form.uploadFile"
                    class="upload-demo" 
                    action="#"
                    ref="upload"
                    :auto-upload="false"
                    :file-list="uploadFile"
                    :on-change="changeFile"
                    :headers="headers" //配置头
                    :multiple= true  //实现多文件上传,不写的话默认是单个文件上传
                    >
                    <el-button class="btn"><i class="el-icon-paperclip">                            </i>上传附件</el-button>
             </el-upload>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="submitForm">确定</el-button>
        </el-form-item>
    </el-form>
</template>
<script>
export default {
    name:'UploadUi',
    data(){
        return{
            form: {},
            uploadFile: [],
            fileList:[],
            headers: { "Content-Type": "multipart/form-data" }, //必须加这个
        }
    },
    methods:{
     
      //通过onchanne触发方法获得文件列表
      changeFile(file, fileList) {
        this.fileList = fileList;
      },
      submitForm() {
         // 启动流程并将表单数据加入流程变量
         let fd = new FormData();
         this.fileList.forEach(element => {
           fd.append("uploadFile", element.raw)  //这里是raw,不是row 仔细仔细!
         });

         addFileLoad(fd).then((response)=>{  //addFileLoad是调后台的方法
           if(response.code == 200){
             this.$modal.msgSuccess(res.msg);
           }
         });
      }, 
       
    }
}
</script>

 

  如果是单个文件上传 可以将changeFile方法改成如下

  changeFile(file, fileList) {	
    this.fileList = fileList[0].raw
  },

   提交里直接这样写即可:  

 let fd = new FormData();
 fd.append("uploadFile", this.fileList);
 addFileLoad(fd).then((response)=>{  //addFileLoad是调后台的方法
    if(response.code == 200){
        this.$modal.msgSuccess(res.msg);
    }
 });

 --------------------------------------------------------------------------------------------------------------------------------

后台:

Controller:

@PostMapping("/fileLoad/fileLoad") 
public R<Void> add(@RequestParam(value = "uploadFile",required = false) MultipartFile[] uploadFile) {

        if(ifileLoadService.uploadFile(uploadFile).getCode()==200){ //uploadFile将上传文件写入硬盘
            for (MultipartFile file: uploadFile) {
                fileLoadBo fileLoadBo = new fileLoadBo();
                fileLoadBo.setFileName(file.getOriginalFilename());//获取上传文件名
                fileLoadBo.setTest("测试");
                ifileLoadService.insertByBo(fileLoadBo); //插入到业务表中
            }
            return toAjax(true);
        }else {
            return toAjax(false);
        }
    }

  这里如果需要将上传的文件存入到业务表当中,就可以加入自己的逻辑在里面,本例子展示的是上传多个文件后,将文件名落入到数据表中,前台如果需要将其他的表单信息同样传到后台,那么只需要将要传递的信息在fd中追加即可。如:fd.append("key值","要传递的信息")

Service:

 public interface IfileLoadService {
   /**
    * 新增文件上传
    */
   Boolean insertByBo(fileLoadBo bo);
   /**
    * 文件存入硬盘
    */
   R<Void> uploadFile(MultipartFile[] files);
 } 

实现类:

@Service
public class fileLoadServiceImpl implements IfileLoadService {
    /**
     * 新增文件上传
     */
    @Override
    public Boolean insertByBo(fileLoadBo bo) {
        fileLoad add = BeanUtil.toBean(bo, fileLoad.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;

        if (flag) {
            bo.setFileId(add.getFileId());
        }
        return flag;
    }
    @Override
    public R<Void> uploadFile(MultipartFile[] files){
        if (files != null){
            for(MultipartFile file : files) {
                String fileName  = file.getOriginalFilename();
                System.out.println(fileName);
                try{
                    File mkdir = new File("e:\\MyTest\\file");
                    if(!mkdir.exists()) {
                        mkdir.mkdirs();
                    }
                    //定义输出流,将文件写入硬盘
                    FileOutputStream os = new FileOutputStream(mkdir.getPath()+"\\"+fileName);
                    InputStream in = file.getInputStream();
                    int b = 0;
                    while((b=in.read())!=-1){ //读取文件
                        os.write(b);
                    }
                    os.flush(); //关闭流
                    in.close();
                    os.close();

                }catch(Exception  e) {
                    e.printStackTrace();
                    return R.fail();
                }
            }
            return R.ok();
        }else {
            return R.fail("文件找不到");
        }
    }


}

2.常见问题:

问题1. Uncaught (in promise) Error: Content type 'multipart/form-data;boundary=---WebKitFormBoundary4g1AmOlvw9Ew13ih;charset=UTF-8' not supported
   at _default (request.js:95:1)

解决方法:因为后端读取的是MultipartFile 类型数据,通过对请求头的类型进行判断,仅识别 multipart 开头的 Content-Type。所以我们需要修改headers 的 Content-Type。

前台:加请求头 headers: { "Content-Type": "multipart/form-data" },

后台:在Controller里去掉@RequestBody,并加上如下一句话:

@RequestParam(value = "uploadFile",required = false) MultipartFile[] uploadFile

问题2:Field error in object '*****Vo' on field 'files': rejected value [[object Object]]

  解决方法:在前台取值的时候直接取raw,我们通过打印formData这个对象,本例子中为fd,可以看到这个files是个[object Object] ,它传入后台是个String类型,而后台是通过MultipartFile[]来接收这个String类型的 “[object Object]” ,必然会报错。

 问题3:数据前台打印都正常,但是传到后台就变成了null,查看请求体变成了undefined

  解决办法:看看是不是把raw错写成了row。 哈哈哈哈因为我就是。

  有其他问题欢迎各位评论下面留言

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿土不土

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值