使用el-upload多图片上传,通过后端保存到本地

注意!!!!!!!!该方法在多图的情况下并不实用!!!更方便的方法请转移至该链接☞https://blog.csdn.net/DRNB666/article/details/120362318?spm=1001.2014.3001.5501

需求:前端需要上传多张图片文件,所以用的是el-upload的上传组件,稍微改了一下组件。
思路:前端使用FormData,将每个file存到一个数组里面,然后以文件数组的形式一次性请求到服务,后端使用MultipartFile[]数组类型进行接收,然后保存到本地。
效果:
在这里插入图片描述

以下是前端代码:

<template>
  <!-- 图片上传(支持多图) -->
  <div>
    <main-head> </main-head>
    <main-content>
      <el-row :gutter="20">
        <el-col :span="4">
          <span style="font-size: 10px">宝贝卡片背景图</span>
          <el-image :src="src" />
        </el-col>
        <el-col :span="12">
          <el-upload
            class="upload-demo"
            ref="upload"
            action="string"
            accept="image/jpeg,image/png,image/jpg"
            list-type="picture-card"
            :before-upload="onBeforeUploadImage"
            :on-change="fileChange"
            :on-remove="removeFile"
            :file-list="fileList"
            :auto-upload="false"
          >
            <el-button size="small" type="primary">点击上传</el-button>
            <div slot="tip" class="el-upload__tip">
              只能上传jpg/jpeg/png文件,且不超过500kb
            </div>
          </el-upload>

          <el-button type="primary" plain @click="sumbit()">上传</el-button>
        </el-col>
      </el-row>
    </main-content>
  </div>
</template>

<script>
export default {
  data() {
    return {
      //文件数组
      fileArr: [],
      //页面显示的图片文件数组
      fileList: [],
      src: "https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg",
    };
  },
  methods: {
    //上传之前的钩子,自定义上传后,该钩子失效
    onBeforeUploadImage(file) {},
    //文件改变钩子
    fileChange(file, fileList) {
      if (this.fileArr.length > 0) {
      //写的是多图上传,但是这个模块只用到了单图,所以加个判断,多图的可以留着后面用
        this.$message.error("当前背景图只支持单张上传");
        fileList = fileList.pop();
        return;
      }
      const isIMAGE = file.type === "image/jpeg" || "image/jpg" || "image/png";
      const isLt1M = file.size / 1024 / 1024 < 1;
      if (!isIMAGE) {
        this.$message.error("上传文件只能是图片格式!");
      }
      if (!isLt1M) {
        this.$message.error("上传文件大小不能超过 1MB!");
      }
      //将文件存到数组中
      this.fileArr.push(file.raw);
    },
    //提交事件
    sumbit() {
      const formData = new FormData();
      //这一步要特别注意!!!如果直接formData.append("files",this.fileArr),那么后端将会收不到参数,一定一定要遍历这个数组然后一个个重新append formdata中
      for (var i = 0; i < this.fileArr.length; i++) {            
            formData.append("files",this.fileArr[i]);
        }         
      this.$request.post({
        url: "system/params/bannerUpdate",
        params: formData,
        success: (result) => {},
        finally: () => {},
      });
    },
    //移除文件的钩子
    removeFile(file, fileList) {
      for (var i = 0; i < this.fileArr.length; i++) {
        //如果传入的文件uid和即将提交的图片数组中的某个uid一致,那么移除此图片
        if (file.raw.uid == this.fileArr[i].uid) {
          this.fileArr.splice(this.fileArr[i], 1);
        }
      }
    },
  },
};
</script>
<style>
</style>

后端代码:
controller层

@ApiOperation("背景图片更换")
    @PostMapping("bannerUpdate")
    @ApiImplicitParams({
             @ApiImplicitParam(paramType = "query", dataTypeClass = Long.class, name = "id", value = "id", required = false),
     })
    public String bannerUpdate(MultipartFile[] files) throws IOException {
        //保存图片文件到本地并返回相对路径
        List<String> image = FileUtil.uploads("/planCat_file/", files, "image");
        //拿着图片路径存储到数据库或者做其他处理,这里就先不多写了,自行发挥
        
        return ReturnBody.success();
    }

工具类方法

package com.mmx.baseservice.common.utils;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class FileUtil {
    private static JSONObject typeObj;

    private static String BASE_PATH = "/files";

	/**
	 * 上传单个文件
	 * @param relativePath 相对路径
	 * @param file 文件
	 * @param fileType 文件类型
	 * @return 文件路径
	 */
    public static String upload(String relativePath, MultipartFile file, String fileType, HttpServletRequest request) {
        relativePath = BASE_PATH + relativePath;
        String basePath = PathUtil.getFullRealPath(request) + relativePath;
        File dir = new File(basePath);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        String fileName;
        if (!file.isEmpty()) {
            try {
                String name = file.getOriginalFilename();
                fileName = checkFile(name, fileType);
                //判断文件类型并返回文件名
                if (fileName != null) {
                    File realFile = new File(basePath + fileName);
                    file.transferTo(realFile);
                } else {
                    return null;
                }
            } catch (IllegalStateException | IOException e) {
                e.printStackTrace();
                return null;
            }
            return relativePath + fileName;
        } else {
            return null;
        }
    }

    /**
     * 上传多个文件
     *
     * @param relativePath 相对路径
     * @param files        文件
     * @return 完整路径名列表
     */
    public static List<String> uploads(String relativePath, MultipartFile[] files, String fileType) {
        String basePath = PathUtil.getFullRealPath() + relativePath;
        List<String> list = new ArrayList<>();
        for (int i = 0; i < files.length; i++) {
            if (!files[i].isEmpty()) {
                try {
                    String name = files[i].getOriginalFilename(); //获取原文件名
                    String fileName = checkFile(name, fileType); //获取新文件名
                    //判断文件类型并返回文件名
                    if (fileName != null) {
                        File realFile = new File(basePath + fileName);
                        files[i].transferTo(realFile);
                        list.add(relativePath + fileName);
                    } else {
                        return null;
                    }
                } catch (IllegalStateException | IOException e) {
                    e.printStackTrace();
                }
            } else {
                return null;
            }
        }
        return list;
    }

    /**
     * 单文件删除
     * @param fileName 文件名
     * @return 返回boolean 删除成功或失败
     */
    public static boolean delete(String fileName) {
        String basePath = PathUtil.getFullRealPath() + fileName;
        LogUtil.info("删除单个文件,路径:{}", basePath);
        File file = new File(basePath);
        // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                LogUtil.info("删除单个文件" + fileName + "成功!");
                return true;
            } else {
                LogUtil.info("删除单个文件" + fileName + "失败!");
                return false;
            }
        } else {
            LogUtil.info("删除单个文件失败:" + fileName + "不存在!");
            return false;
        }
    }

    /**
     * 判断是否为允许的上传文件类型
     *
     * @return null或文件名
     */
    public static String checkFile(String fileName, String type) {
        if (typeObj == null) {
            typeObj = new JSONObject();
            typeObj.put("image", "jpg,gif,png,ico,bmp,jpeg");
            typeObj.put("file", "txt,doc,docx,xlsx,xls,pdf,jpg,gif,png,ico,bmp,jpeg");
        }
        String suffixList = (String) typeObj.get(type);
        // 获取文件后缀
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        if (suffixList.contains(suffix.trim().toLowerCase())) {
            return UUIDUtil.getCode() + "." + suffix.trim().toLowerCase();
        }
        return null;
    }


    /**
     * 下载
     *
     * @param request 文件名(相对路径)
     * @param response
     * @return
     */
    public static boolean downloadFile(HttpServletRequest request, HttpServletResponse response) {
        String fileName = request.getParameter("fileName");
        if (fileName != null) {
            File file = new File(PathUtil.getFullRealPath(), fileName);
            if (file.exists()) {
                response.setContentType("application/force-download");// 设置强制下载不打开
                response.addHeader("Content-Disposition", "attachment;fileName=" + fileName);// 设置文件名
                byte[] buffer = new byte[1024];
                FileInputStream fis = null;
                BufferedInputStream bis = null;
                try {
                    fis = new FileInputStream(file);
                    bis = new BufferedInputStream(fis);
                    OutputStream os = response.getOutputStream();
                    int i = bis.read(buffer);
                    while (i != -1) {
                        os.write(buffer, 0, i);
                        i = bis.read(buffer);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                } finally {
                    if (bis != null) {
                        try {
                            bis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (fis != null) {
                        try {
                            fis.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
        return true;
    }


    /**
     * FileWriter类文件写入
     *
     * @throws IOException
     */
    public static void writeFile(String fileName, List<String> fileContent) throws IOException {
        FileWriter fileWriter = null;
        try {
            //使用这个构造函数时,如果存在fileName文件,
            //则先把这个文件给删除掉,然后创建新的fileName
            fileWriter = new FileWriter(fileName);
            for (int i = 0; i < fileContent.size(); i++) {
                fileWriter.write(fileContent.get(i) + "\n");
            }
        } finally {
            try {
                if (fileWriter != null) {
                    fileWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *File转MultipartFile
     */
    public static MultipartFile  createFileItem(File file) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem("textField", "text/plain", true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new CommonsMultipartFile(item);
    }
}

总结:
1、前端方面需要注意每次图片删除的时候,记得把对应的需要上传到后台的file数组中的图片元素也删除掉,因为前端图片上的删除只是删除fileList这个显示在页面的数组图片
2、上传formdata的时候,文件数组不能直接append到表单里面,需要遍历后一个一个append到一个属性里面,不然后端会报空指针

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
el-upload标签是elementUI中的上传控件,用于将文件上传后端。在前端代码中,可以看到el-upload标签的属性中有一个action属性,该属性指定了文件上传后端路径。在\[1\]中,action属性的值为后端上传路径,而在\[2\]中,action属性的值为"#",表示上传的请求将发送到当前页面。在\[3\]中,action属性的值为"https://jsonplaceholder.typicode.com/posts/",表示上传的请求将发送到该URL。因此,el-upload标签的action属性可以根据具体的需求设置为相应的后端上传路径。 #### 引用[.reference_title] - *1* [使用el-upload上传单文件多文件前后端实现](https://blog.csdn.net/qq_43780761/article/details/126564877)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [前端文件上传后端接收(el-upload标签的使用)](https://blog.csdn.net/Hsssc/article/details/109067378)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [vue el-upload实现上传文件到后台的功能](https://blog.csdn.net/qq_42345108/article/details/102824501)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值