zoukankan      html  css  js  c++  java
  • SpringBoot图片上传(四) 一个input上传N张图,支持各种类型

     简单介绍:需求上让实现,图片上传,并且可以一次上传9张图,图片格式还有要求,网上找了一个测试了下,好用,不过也得改,仅仅是实现了功能,其他不尽合理的地方,还需自己打磨。

    代码:

    //html
    <div class="col-md-12">
    <label class="control-label flex" style="margin-top: 10px;">
    上传附件<span class="star align-items">*</span>
    </label>
      <form id="imgForm">
    <div class="">
    <img th:src="@{/assets-new/apps/img/shangchuan.png}" id="imgIcon"
    width="35px" height="35px"/>
    <input type="file" id="seledIcon" style="display:none"
    multiple="multiple" accept="image/gif,image/jpg,image/png,image/JPEG"/>
    </div>
      </form>
    <input type="hidden" name="contractIcon" id="contractIcon"/>
    </div>
    <div id="imgBox"></div>
    <button id="btn">上传</button> 
    //这里的form 是专门用来做上传用的(言外之意是还有别的form)。专门 专门 专门 因为新增或者编辑的时候我们上传图片,最后肯定要保存的,点击保存,触发表单form提交,就会冲突
    //说明一下,accept可以直接设置"image/*"是所有类型的图片格式 输入accept= idea会给出提示的,可以自己看看
    //js代码 
    $("#imgIcon").on("click", function () {
    $("#seledIcon").trigger("click");
    });

    //这段代码建议放到初始化里边 另外 url要加上 根路径 rootPath,否则上传不了不怪我哦
    <script type="text/javascript" th:inline="javascript" xmlns:th="http://www.w3.org/1999/xhtml">
    <![CDATA[
    imgUpload({
    inputId:'seledIcon', //input框id
    imgBox:'imgBox', //图片容器id
    buttonId:'btn', //提交按钮id
    upUrl: rootPath +'/oper/contract/uploadImg', //提交地址
    data:'file', //参数名
    num:"9"//最多上传图片个数,可以设置很多,看你服务器大小以及性能了
    });
    ]]>
    </script> 

    //js代码
    var imgSrc = []; //存放图片路径
    var imgFile = []; //存放文件流
    var imgName = []; //存放图片名字
    //选择图片的操作
    function imgUpload(obj) {
    debugger;
    var oInput = '#' + obj.inputId;
    var imgBox = '#' + obj.imgBox;
    var btn = '#' + obj.buttonId;
    //用on是因为它可以动态的绑定事件
    $(oInput).on("change", function() {
         imgFile = [];//保证二次点击上传的时候第一次的file不会被再次上传
    //获取type=file的input
    var fileImg = $(oInput)[0];
    //得到所有的图片列表
    var fileList = fileImg.files;
    for(var i = 0; i < fileList.length; i++) {
          if(fileList[i].size<1021*1024){
    //得到每个图片的路径
    var imgSrcI = getObjectURL(fileList[i]);
    //向文件名的数组末尾添加此文件名
    imgName.push(fileList[i].name);
    //向路径的数组末尾添加路径
    imgSrc.push(imgSrcI);
    //在文件流数组的末尾添加文件
    imgFile.push(fileList[i]);
     }
         }
    //将图片展示出去
    addNewContent(imgBox);
    });

    $(btn).on('click', function() {
    if(!limitNum(obj.num)){
    layer.msg("最多只能上传"+obj.num+"张照片!");
    return false;
    }

    //用FormData对象上传
    var fd = new FormData($('#imgForm')[0]);
    //由于fd对象中已经包含<input type='file'>的input标签,如果不删除,就会造成重复上传
    fd.delete("file");
    //将文件流循环添加到FormData对象中
    for(var i=0;i<imgFile.length;i++){
    fd.append(obj.data,imgFile[i]);
    }
    //上传所有的图片
    submitPicture(obj.upUrl, fd);
    })
    }
    //图片展示
    function addNewContent(obj) {
    $(imgBox).html("");
    for(var a = 0; a < imgSrc.length; a++) {
    var oldBox = $(obj).html();
    $(obj).html(oldBox + '<div class="imgContainer"><img title=' + imgName[a] + ' alt=' + imgName[a] + ' src=' + imgSrc[a] + ' onclick="imgDisplay(this)"><p onclick="removeImg(this,' + a + ')" class="imgDelete">删除</p></div>');
    }
    }
    //删除
    function removeImg(obj, index) {
    //向数组中删除元素
    imgSrc.splice(index, 1);
    imgFile.splice(index, 1);
    imgName.splice(index, 1);
    var boxId = "#" + $(obj).parent('.imgContainer').parent().attr("id");
    addNewContent(boxId);
    }
    //限制图片个数
    function limitNum(num){
    if(!num){
    return true;
    }else if(imgFile.length>num){
    return false;
    }else{
    return true;
    }
    }

    //上传(将文件流数组传到后台)
    function submitPicture(url,data) {
    debugger;
    for (var p of data) {
    console.log(p);
    }
    if(url&&data){
    $.ajax({
    url: url,
    type: "post",
    data: data,
    async: true,
    //下面这两个要写成false,要不然上传不了。
    processData: false,
    contentType: false,
    success: function(dat) {
    debugger;
    layer.msg("上传成功");
    },
    error:function(xhr,emsg,e) {
    //打印ajax发生的错误
    console.log(e);
    //答应出ajax请求返回的文本信息
    console.log(xhr.responseText());
    }
    });
    }else{
    layer.msg('数据格式不正确!');
    }
    }
    //当鼠标移到图片上时,显示x删除
    function imgDisplay(obj) {
    var src = $(obj).attr("src");
    var imgHtml = '<div style=" 100%;height: 100vh;overflow: auto;background: rgba(0,0,0,0.5);text-align: center;position: fixed;top: 0;left: 0;z-index: 1000;"><img src=' + src + ' style="margin-top: 100px; 70%;margin-bottom: 100px;"/><p style="font-size: 50px;position: fixed;top: 30px;right: 30px;color: white;cursor: pointer;" onclick="closePicture(this)">×</p></div>'
    $('body').append(imgHtml);
    }
    //关闭
    function closePicture(obj) {
    $(obj).parent("div").remove();
    }
    //图片预览路径
    function getObjectURL(file) {
    var url = null;
    if(window.createObjectURL != undefined) { // basic
    url = window.createObjectURL(file);
    } else if(window.URL != undefined) { // mozilla(firefox)
    url = window.URL.createObjectURL(file);
    } else if(window.webkitURL != undefined) { // webkit or chrome
    url = window.webkitURL.createObjectURL(file);
    }
    return url;
    } 

    //后台java代码
    //获取配置里的路径 写在Controller里
    @Value("${constant.image_path}")
    private String imagePath;

    @Value("${constant.image_temp_path}")
    private String imageTempPath;

    @RequestMapping("/uploadImg")
    @ResponseBody
    public String uploadImg(MultipartFile file[]) throws Exception {
    List<String> list = new ArrayList<>();
    for (MultipartFile f : file) {
    // 图片的名字用毫秒数+图片原来的名字拼接
    String imgName = System.currentTimeMillis() + f.getOriginalFilename();
    //上传文件
    uploadFileUtil(f.getBytes(), imageTempPath, imgName);
    list.add(imgName);
    }
    String str = StringUtils.join(list,",");
    return str;
    }

    private void uploadFileUtil(byte[] file, String imgPath, String imgName) throws Exception {
    File targetFile = new File(imgPath);
    if (!targetFile.exists()) {
    targetFile.mkdirs();
    }
    FileOutputStream out = new FileOutputStream(imgPath + File.separator + imgName);
    out.write(file);
    out.flush();
    out.close();
    } 

     主要的改动是在uploadFileUtil方法中,原博文的上传图片,上传后的图片名字前面还多了一个上级文件夹的名字,经过我修改后的就没有了,

    另外 springboot内置tomact的的文件传输默认为1MB,所以我在js里边添加了一个if条件限定文件大小小于1M也就是1024*1024

    随笔到这里就完了,下边是一些注意事项和小问题。

    ————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

     首先一个很重要的内容,因为这里使用的是表单提交请求,所以存在一个问题,如果我们在做新增或者编辑的时候,最后肯定是要提交form表单来把数据传递到后台的,因为有id是imgForm图片提交的form存在,所以写在imgForm之外,addForm之内的一些表单信息后台就获取不到,也就是下边的 备注notes 和 别名alias 就不能够被addForm传递到后台,后台是null,要解决这个问题,只要把notes 和 alias这两个表单放到 imgForm上边就OK。

    //html  
    <form action="" class="horizontal-form" method="post" id="addForm" autocomplete="off">
    <div class="col-md-6">
    <label class="control-label flex" style="margin-top: 10px;" >
    编号<span class="star align-items">*</span>
    </label>
    <input type="text" id="number" name="number"
    class="form-control" maxlength="50" placeholder="编号"/>
    </div>
    <div class="col-md-6">
    <label class="control-label flex" style="margin-top: 10px;">
    类型<span class="star align-items">*</span>
    </label>
    <select id="s_type" name="s_ype" class="form-control js-example-basic-single">
    <option th:each="status : ${typeList}" th:value="${status.dictCode}"
    th:text="${status.dictName}"
    xmlns:th="http://www.w3.org/1999/xhtml"></option>
    </select>
    </div>
    <div class="col-md-6">
    <label class="control-label flex" style="margin-top: 10px;">
    生效时间<span class="star align-items">*</span>
    </label>
    <div class="input-group-control date-picker">
    <input class="form-control" type="text" name="startTime" id="startTime" maxlength="50" placeholder="请输入生效时间"/>
    </div>
    </div>
    <div class="col-md-6">
    <label class="control-label flex" style="margin-top: 10px;">
    失效时间<span class="star align-items">*</span>
    </label>
    <div class="input-group-control date-picker">
    <input class="form-control" type="text" name="endTime" id="endTime" maxlength="50" placeholder="请输入失效时间"/>
    </div>
    </div>
    <br /><br />

    <div class="col-md-12">
    <label class="control-label flex" style="margin-top: 10px;">
    上传附件<span class="star align-items">*</span>
    </label>
    <form id="imgForm">
    <div class="" id="imgDiv">
    <img th:src="@{/assets-new/apps/img/shangchuan.png}" id="imgIcon"
    width="35px" height="35px"/>
    <input type="file" id="seledIcon" style="display:none"
    multiple="multiple" accept="image/gif,image/jpg,image/png,image/JPEG"/>
    </div></form>
    <input type="hidden" name="contractIcon" id="contractIcon"/>
    </div>
      <div class="col-md-12">
    <label class="control-label flex" style="margin-top: 10px;">
    备注
    </label>
    </div>
    <div class="col-md-12">
    <textarea id="notes" name="notes" class="form-control" placeholder="请填写备注信息" maxlength="200"></textarea>
    </div>
      <div class="col-md-12">
        <input type="text" id="alias" name="alias" class="form-control" placeholder="别名"/>
      </div>
    <br />
    <br />
    </form> 

    在说一点:springboot 内置tomact的的文件传输默认为1MB,超过这个会报错哦,要注意,限制大小;要么就是修改文件传输的大小限制,这个我没改,因为老大不让动配置,emmm,不过呢,给你们个链接,我觉得这个应该会好使https://blog.csdn.net/duangecho/article/details/80383720

    还有的就是一些,很细节方面的问题了,比如说,原文的imgbox真的不太美观,我改了,文章没体现,下一篇(五)会说的,还有就是删除样式也不太好看=3=!(^o^)/

    总结:好用是好用,但是对于图片大小样式什么的没有具体的限定,另外展示图片仅仅是吧图片放在了html中,体验感不太好,嗯,反正得改。。。。有一点,原来的博主js写的挺全面的,什么 删除啦,点击放大预览啦都有的,值得借鉴,当然也得修改修改

    原文链接:https://blog.csdn.net/jtshongke/article/details/78516559

  • 相关阅读:
    WPF窗口和用户控件事件相互触发
    C#排序算法总结
    C#.NET操作数据库通用类
    在C#的WPF程序使用XAML实现画线
    centos7 用户介绍
    Linux系列2
    nginx的使用
    TCP协议、三次握手以及滑动窗口等的介绍(计算机网络基础知识)
    mysql的
    jQuery的东西
  • 原文地址:https://www.cnblogs.com/xuchao0506/p/9935988.html
Copyright © 2011-2022 走看看