飞道的博客

springboot+layui实现表格数据和文件一起上传

610人阅读  评论(0)

前言

  • 通过这篇文章一定能解决你的问题,让你不用看其他博客浪费时间。

逻辑

  • 前台form表格里有很多条数据,还有文件上传的操作,当用户点击提交按钮就把文件和数据一起提交到后台。
  • 我想使用layui的方法来提交文件,因为layui确实是比较方便的,但是很多地方具体怎么操作找不到官方教程,中间也是边百度边试探,终究找到了方法,特此记录一下。

方法一

前台

  • 前台的代码比较好用,很有参考价值:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8">
    <title>Layui</title>
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="stylesheet" href="/layui/css/layui.css"  media="all">
    <!-- 注意:如果你直接复制所有代码到本地,上述css路径需要改成你本地的 -->
</head>
<body>

<blockquote class="layui-elem-quote layui-text">
    请各位老师发布毕业设计题目
</blockquote>

<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
    <legend>毕业设计题目发布信息表格</legend>
</fieldset>

<form class="layui-form"  method="post">
    <div class="layui-form-item">
        <label class="layui-form-label">毕设题目</label>
        <div class="layui-input-block">
            <input type="text" name="subjname" lay-verify="required" autocomplete="off" placeholder="请输入毕设题目" class="layui-input">
        </div>
    </div>
    <div class="layui-form-item">
        <div class="layui-inline">
            <label class="layui-form-label">老师工号</label>
            <div class="layui-input-inline">
                <input type="text" name="teachertno" autocomplete="off" th:value="${userId}" disabled="disabled" class="layui-input">
            </div>
        </div>
        <div class="layui-inline">
            <label class="layui-form-label">老师姓名</label>
            <div class="layui-input-inline">
                <input type="text" name="teachername" autocomplete="off" th:value="${userName}" disabled="disabled" class="layui-input">
            </div>
        </div>
    </div>

    <fieldset class="layui-elem-field layui-field-title" style="margin-top: 30px;">
        <legend>指定允许上传的文件类型</legend>
    </fieldset>
    <div class="layui-form-item">
        <button type="button" style="margin-left: 30px;" class="layui-btn" id="test3"><i class="layui-icon"></i>上传文件</button>
    </div>
    <div style="width:300px;">
        <div class="layui-progress layui-progress-big" lay-showpercent="yes" lay-filter="demo">
            <div class="layui-progress-bar" lay-percent=""></div>
        </div>
    </div>
    <div class="layui-form-item" style="margin-top: 20px;">
        <div class="layui-input-block">
            <button type="submit" class="layui-btn" lay-submit="" lay-filter="demo1" id="put" onclick="return false">立即提交</button>
            <button type="reset" class="layui-btn layui-btn-primary">重置</button>
        </div>
    </div>
</form>

<script src="/layui/layui.js" charset="utf-8"></script>
<!-- 注意:如果你直接复制所有代码到本地,上述 JS 路径需要改成你本地的 -->
<script>

    layui.use(['upload', 'element', 'layer'], function(){
    
        var $ = layui.jquery
            ,upload = layui.upload
            ,element = layui.element
            ,layer = layui.layer;
        var form = layui.form


        //指定允许上传的文件类型
        upload.render({
    
            elem: '#test3'
            ,url: 'fileUpload1' //改成您自己的上传接口https://httpbin.org/post
            ,accept: 'file' //普通文件
            ,size: 5120 //限制文件大小,单位 KB
            ,exts: 'pdf' //只允许上传压缩文件
            ,auto: false //选完文件后自动上传
            ,bindAction: '#put'//点击该按钮就上传文件
            ,before: function(obj){
    
                element.progress('demo', '0%'); //进度条复位
                this.data = {
    
                    subjname: $('input[name="subjname"]').val(),
                    teachertno: $('input[name="teachertno"]').val(),
                    teachername: $('input[name="teachername"]').val(),
                }
            }
            ,done: function(res){
    
                layer.msg('上传成功');
                console.log(res);
            }
            ,error: function(){
    
                //演示失败状态,并实现重传
                //alert("文件上传失败");
                console.log("文件上传失败");
            }
            //进度条
            ,progress: function(n, index, e){
    
                element.progress('demo', n + '%'); //可配合 layui 进度条元素使用
                if(n == 100){
    
                    //layer.msg('上传完毕', {icon: 1});
                }
            }
        });


    });
</script>


</body>
</html>

这里需要注意的点如下:

上面分别是设置不自动上传,和绑定点击哪个控件的时候上传文件,自然是绑定为提交按钮,然后before是设置在上传文件前(即点击控件后,上传文件前)的操作,即把咱们要传到后台的数据写在这个before里。
还有,这里一定要去掉form标签里的action以及设置按钮点击事件为false:

因为点击控件之后会同时触发form表单的提交操作和文件数据上传的ajax操作(layui内部采用的应该是ajax传文件),这样会导致后台报错:
org.apache.catalina.connector.ClientAbortException: java.io.IOException: 您的主机中的软件中止了一个已建立的连接。

当然我们可以把form用div代替,但是我不想遇到困难就妥协,用form也可以,将最后的提交按钮的click事件设置为false就可以了,千万不要让表格的点击事件设置为false哈!

后台

  • 代码:
//实验
    @RequestMapping("fileUpload1")
    @ResponseBody
    public JSONObject fileUpload1(@RequestParam(value="subjname",defaultValue ="")String subjname,
                                  @RequestParam(value="teachertno",defaultValue ="")String teachertno,
                                  @RequestParam(value="teachername",defaultValue ="")String teachername,
                                  MultipartFile file) {
   
        System.out.println(subjname);
        System.out.println(teachertno);
        System.out.println(teachername);
        System.out.println(file.getSize());

        //这里写对数据和文件的操作。

        JSONObject json = new JSONObject();
        json.put("sdf","sdf");
        return json;
    }

方法二

前台

 <div class="layui-upload">
                    <button type="button" class="layui-btn layui-btn-normal" id="testList">选择图片</button>
                    <div class="layui-upload-list">
                        <table class="layui-table">
                            <thead>
                            <tr>
                                <th>文件名</th>
                                <th>大小</th>
                                <th>状态</th>
                                <th>操作</th>
                            </tr>
                            </thead>
                            <tbody id="demoList"></tbody>
                        </table>
                    </div>
                </div>
                <div class="modal-footer">
                    <button type="button" class="layui-btn" id="testListAction" onclick="hint()"
                            style="margin-left: 40%">立即提交
                    </button>
                    <button type="button" class="btn btn-primary" id="testListAction1" style="display:none">
                        提交图片
                    </button>
                </div>

### 注释也写的差不多了,不懂的小伙伴留言区一起讨论呀。
//提示提交
    var BCODE;    
    function hint() {
        $.ajax({
            url: "/inputBill/add",
            type: 'POST',
            data: $("#formid").serialize(),
            // 告诉jQuery不要去处理发送的数据
            processData: false,
            // 告诉jQuery不要去设置Content-Type请求头
            contentType: false,
            async: true,
            success: function (data) {
                BCODE = data;
                var imgVal = $("#demoList").html();
                if (imgVal == '') {
                    location.href = "/inputBill/index";
                    layer.msg('提交成功');
                } else {
                    $("#testListAction1").trigger("click");  //触发上传文件
                }
            }
        });
    }

    //多图片上传

    layui.use('upload', function () {
        var $ = layui.jquery
            , upload = layui.upload;
        var demoListView = $('#demoList')
        console.log(demoListView)
            , uploadListIns = upload.render({
            elem: '#testList'
            , url: '/inputBill/Uploadattachment'
            , acceptMime: 'image/*'
            , multiple: true
            , auto: false
            , bindAction: '#testListAction1'
            , before: function (obj) { //obj参数包含的信息,跟 choose回调完全一致。其中输入向后台传输的参数
                this.data = {
                    'BCODE': BCODE
                };
            }
            , choose: function (obj) {
                var files = this.files = obj.pushFile(); //将每次选择的文件追加到文件队列

                obj.preview(function (index, file, result) {
                    var tr = $(['<tr id="upload-' + index + '">'
                        , '<td>' + file.name + '</td>'
                        , '<td>' + (file.size / 1014).toFixed(1) + 'kb</td>'
                        , '<td>等待上传</td>'
                        , '<td>'
                        , '<button class="layui-btn layui-btn-xs demo-reload layui-hide">' +
                        '重传</button>'
                        , '<button class="layui-btn layui-btn-xs layui-btn-danger demo-delete">删除</button>'
                        /*    ,'<button class="layui-btn layui-btn-xs layui-btn-danger demo-delete">预览</button>'*/
                        , '</td>'
                        , '</tr>'].join(''));

                    //单个重传
                    tr.find('.demo-reload').on('click', function () {
                        obj.upload(index, file);
                    });

                    //删除
                    tr.find('.demo-delete').on('click', function () {
                        delete files[index]; //删除对应的文件
                        tr.remove();
                        uploadListIns.config.elem.next()[0].value = ''; //清空 input file 值,以免删除后出现同名文件不可选
                    });
                    //预览
                    demoListView.append(tr);
                });
            }
            , done: function (res, index, upload) {
                if (res.return_code == 1) { //上传成功
                    var tr = demoListView.find('tr#upload-' + index)
                        , tds = tr.children();
                    tds.eq(1).html('<span style="color: #5FB878;">上传成功</span>');
                    tds.eq(2).html(''); //清空操作
                    return delete this.files[index]; //删除文件队列已经上传成功的文件
                }
                this.error(index, upload);
            }
            , allDone: function (obj) { //当文件全部被提交后,才触发
                layer.msg('保存成功!', {
                    time: 2000, //2s后自动关闭
                    btn: ['确定']
                });
                location.href = "/inputBill/index";
            }
            , error: function (index, upload) {
                var tr = demoListView.find('tr#upload-' + index)
                    , tds = tr.children();
                tds.eq(1).html('<span style="color: #FF5722;">上传失败</span>');
                tds.eq(2).find('.demo-reload').removeClass('layui-hide'); //显示重传
            }
        });
    });

总结

  • 总体来说,第一种方法是最正规直接的方法,第二种方法是曲线救国,后台需要用两个函数,先接受数据,再接受文件,不太优雅。

转载:https://blog.csdn.net/qq_41076797/article/details/116304057
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场