EasyUI实现图片的上传后与其他文本框的提交以及DataGrid中图片的展示

  图片即文件,在jsp中文件上传很简单,一个type为file的input,一个form指定enctype为multipart/form-data,通过post提交到后台利用apache的commons-fileupload.XXjar即可实现。EasyUI的filebox组件也是用来进行文件上传的,但我这里的业务需求不仅仅是图片上传,还有其他文本框的提交,所以需要文件上传后再点击保存。界面展示图片是在数据列表中,因此需要小图,点击图片后再展示大图。

  因为这里支付截图上传后需跟另一个支付流水的文本框一起在form里提交,因此需要多加一个文件上传按钮来先进行图片的上传:

  选好图片后点击图片上传:

  传好后点击保存,支付流水和截图将一起入库。再看数据列表的展示:

  鼠标点击小图展示大图:

  这里上传和展示就一起说明了:

  先看html,首先datagrid中我们设置列头时执行支付截图需要通过imgFormatter方法进行格式化:

<th field="payFlow" width="3%">支付流水</th>
<th field="photoUrl" width="3%" data-options="formatter:imgFormatter">支付截图</th>

  再看点击编辑时弹出的form:

<div id="dlg" class="easyui-dialog" style="560px;height:300px;padding:10px 20px"
     closed="true" buttons="#dlg-buttons">
    <div class="ftitle">支付信息</div>
    <form id="fm" method="post" novalidate>
        <div class="fitem">
            <label>支付流水:</label>
            <input name="payFlow" class="easyui-numberbox">
        </div>
        <div class="fitem">
            <label>支付截图:</label>
            <input id="photoUrl" name="photoUrl">
        </div>
    </form>
</div>
<div id="dlg-buttons">
    <a href="javascript:void(0)" class="easyui-linkbutton c6" iconCls="icon-save" onclick="saveFile()"
       style="90px">图片上传</a>
    <a href="javascript:void(0)" class="easyui-linkbutton c6" iconCls="icon-ok" onclick="saveFlow()"
       style="90px">保存</a>
    <a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-cancel"
       onclick="javascript:$('#dlg').dialog('close')" style="90px">取消</a>
</div>

  再看下js,展示图片、上传图片和保存信息都在这里:

    var url;
    var uploadPath;
    
    $(function () {
        $('#photoUrl').filebox({
            prompt: '请选择一张图片...',
             '280px',
            buttonText: '点击选择图片'
        })
        $('#photoUrl').filebox({
            onChange: function () {
                var fileObj = $("input[name='photoUrl']")[0];
                var allowExtention = ".jpg,.bmp,.gif,.png,.jpeg";
                var extention = fileObj.value.substring(fileObj.value.lastIndexOf(".") + 1).toLowerCase();
                if (allowExtention.indexOf(extention) == -1) {
                    $.messager.show({    // show error message
                        title: '错误',
                        msg: "只支持以下格式图片:" + allowExtention + "."
                    });
                    $('#photoUrl').filebox('reset');
                    $('#photoUrl').filebox('setValue', "");
                    $('#photoUrl').filebox('disableValidation');
                }
            }
        })
    });

    function imgFormatter(value, row, index) {
        if ('' != value && null != value) {
            var imgResult = "<img onclick=download("" + value + "") style='30px; height:30px;margin-left:3px;' src='" + value
                + "' title='点击查看全图'/>";
            return imgResult;
        }
    }

    function download(img) {
        var imgTemp = "http://localhost:8888" + img;
        $('#dlgImg').dialog({
            title: '展示全图',
             600,
            height: 500,
            resizable: true,
            closed: false,
            cache: false,
            modal: true
        });
        $('#imgTemp').attr("src", imgTemp);
    }

    function editFlow() {
        var row = $('#dg').datagrid('getSelected');
        if (row) {
            $('#dlg').dialog('open').dialog('setTitle', '编辑');
            $('#fm').form('load', row);
            url = 'update_pay?id=' + row.id;
        }
    }

    function saveFile() {
        // 异步提交文件
        $.ajaxFileUpload({
            url: 'uploadFile',
            secureuri: false,
            fileElementId: $("input[name='photoUrl']").attr("id"),
            type: 'post',
            success: function (data) {
                var reg = /<pre.+?>(.+)</pre>/g;
                var temp = data.match(reg);
                temp = RegExp.$1;
                var data = eval('(' + temp + ')');
                if (data.resultPath) {
                    uploadPath = data.resultPath;
                    $.messager.show({    // show error message
                        title: '成功',
                        msg: '图片上传成功.'
                    });
                }
            },
            error: function () {
                $.messager.show({    // show error message
                    title: '错误',
                    msg: "图片上传失败."
                });
            }
        });

        $('#photoUrl').filebox('reset');
        $('#photoUrl').filebox('setValue', "");
        $('#photoUrl').filebox('disableValidation');
    }

    function saveFlow() {
        if (uploadPath) {
            url = url + '&photoUrl=' + uploadPath;
        }
        $('#fm').form('submit', {
            url: url,
            onSubmit: function () {
                return $(this).form('validate');
            },
            success: function (result) {
                var result = eval('(' + result + ')');
                if (result.errorMsg) {
                    $.messager.show({
                        title: '错误',
                        msg: "保存失败."
                    });
                } else {
                    $('#dlg').dialog('close');        // close the dialog
                    $('#dg').datagrid('reload');    // reload the user data
                }
            }
        });
    }

  头文件里引入ajaxfileupload.js

<script src="ajaxfileupload.js" type="text/javascript"></script>

  ajaxfileupload.js直接放在静态文件目录下即可,当然你也可以自己找地方,上面的引入路径能匹配到即可:

jQuery.extend({
    createUploadIframe: function (d, b) {
        var a = "jUploadFrame" + d;
        var c = '<iframe id="' + a + '" name="' + a + '" style="position:absolute; top:-9999px; left:-9999px"';
        if (window.ActiveXObject) {
            if (typeof b == "boolean") {
                c += ' src="' + "javascript:false" + '"'
            } else {
                if (typeof b == "string") {
                    c += ' src="' + b + '"'
                }
            }
        }
        c += " />";
        jQuery(c).appendTo(document.body);
        return jQuery("#" + a).get(0)
    }, createUploadForm: function (a, j, d) {
        var h = "jUploadForm" + a;
        var c = "jUploadFile" + a;
        var b = jQuery('<form  action="" method="POST" name="' + h + '" id="' + h + '" enctype="multipart/form-data"></form>');
        if (d) {
            for (var e in d) {
                if (d[e].name != null && d[e].value != null) {
                    jQuery('<input type="hidden" name="' + d[e].name + '" value="' + d[e].value + '" />').appendTo(b)
                } else {
                    jQuery('<input type="hidden" name="' + e + '" value="' + d[e] + '" />').appendTo(b)
                }
            }
        }
        var f = jQuery("#" + j);
        var g = jQuery(f).clone();
        jQuery(f).attr("id", c);
        jQuery(f).before(g);
        jQuery(f).appendTo(b);
        jQuery(b).css("position", "absolute");
        jQuery(b).css("top", "-1200px");
        jQuery(b).css("left", "-1200px");
        jQuery(b).appendTo("body");
        return b
    }, ajaxFileUpload: function (k) {
        k = jQuery.extend({}, jQuery.ajaxSettings, k);
        var a = new Date().getTime();
        var b = jQuery.createUploadForm(a, k.fileElementId, (typeof (k.data) == "undefined" ? false : k.data));
        var i = jQuery.createUploadIframe(a, k.secureuri);
        var h = "jUploadFrame" + a;
        var j = "jUploadForm" + a;
        if (k.global && !jQuery.active++) {
            jQuery.event.trigger("ajaxStart")
        }
        var c = false;
        var f = {};
        if (k.global) {
            jQuery.event.trigger("ajaxSend", [f, k])
        }
        var d = function (l) {
            var p = document.getElementById(h);
            try {
                if (p.contentWindow) {
                    f.responseText = p.contentWindow.document.body ? p.contentWindow.document.body.innerHTML : null;
                    f.responseXML = p.contentWindow.document.XMLDocument ? p.contentWindow.document.XMLDocument : p.contentWindow.document
                } else {
                    if (p.contentDocument) {
                        f.responseText = p.contentDocument.document.body ? p.contentDocument.document.body.innerHTML : null;
                        f.responseXML = p.contentDocument.document.XMLDocument ? p.contentDocument.document.XMLDocument : p.contentDocument.document
                    }
                }
            } catch (o) {
                jQuery.handleError(k, f, null, o)
            }
            if (f || l == "timeout") {
                c = true;
                var m;
                try {
                    m = l != "timeout" ? "success" : "error";
                    if (m != "error") {
                        var n = jQuery.uploadHttpData(f, k.dataType);
                        if (k.success) {
                            k.success(n, m)
                        }
                        if (k.global) {
                            jQuery.event.trigger("ajaxSuccess", [f, k])
                        }
                    } else {
                        jQuery.handleError(k, f, m)
                    }
                } catch (o) {
                    m = "error";
                    jQuery.handleError(k, f, m, o)
                }
                if (k.global) {
                    jQuery.event.trigger("ajaxComplete", [f, k])
                }
                if (k.global && !--jQuery.active) {
                    jQuery.event.trigger("ajaxStop")
                }
                if (k.complete) {
                    k.complete(f, m)
                }
                jQuery(p).unbind();
                setTimeout(function () {
                    try {
                        jQuery(p).remove();
                        jQuery(b).remove()
                    } catch (q) {
                        jQuery.handleError(k, f, null, q)
                    }
                }, 100);
                f = null
            }
        };
        if (k.timeout > 0) {
            setTimeout(function () {
                if (!c) {
                    d("timeout")
                }
            }, k.timeout)
        }
        try {
            var b = jQuery("#" + j);
            jQuery(b).attr("action", k.url);
            jQuery(b).attr("method", "POST");
            jQuery(b).attr("target", h);
            if (b.encoding) {
                jQuery(b).attr("encoding", "multipart/form-data")
            } else {
                jQuery(b).attr("enctype", "multipart/form-data")
            }
            jQuery(b).submit()
        } catch (g) {
            jQuery.handleError(k, f, null, g)
        }
        jQuery("#" + h).load(d);
        return {
            abort: function () {
            }
        }
    }, uploadHttpData: function (r, type) {
        var data = !type;
        if (!type) {
            data = r.responseText
        }
        if (type == "xml") {
            data = r.responseXML
        }
        if (type == "script") {
            jQuery.globalEval(data)
        }
        if (type == "json") {
            data = r.responseText;
            var start = data.indexOf(">");
            if (start != -1) {
                var end = data.indexOf("<", start + 1);
                if (end != -1) {
                    data = data.substring(start + 1, end)
                }
            }
            eval("data = " + data)
        }
        if (type == "html") {
            jQuery("<div>").html(data).evalScripts()
        }
        return data
    }, handleError: function (b, d, a, c) {
        if (b.error) {
            b.error.call(b.context || b, d, a, c)
        }
        if (b.global) {
            (b.context ? jQuery(b.context) : jQuery.event).trigger("ajaxError", [d, b, c])
        }
    }
});

  通过ajaxfileupload.js进行异步调用获取到的json响应会多一些文本(其实就是一个<pre>标签),所以上面在点击保存时saveFile()通过正则过滤才能真正拿到图片路径。

  最后看下后台,文件上传Controller:

    @ResponseBody
    @RequestMapping(value = "uploadFile", method = RequestMethod.POST)
    public Object uploadFile(@RequestParam(value = "photoUrl") MultipartFile file,
                             HttpServletRequest request) {
        Map<String, Object> resultMap = new HashMap<>();
        String error = null;

        // 获取文件名
        String fileName = file.getOriginalFilename();

        // 根据文件后缀生成新的文件名
        String type = fileName.substring(fileName.lastIndexOf(".") + 1);

        String newFileName = Utils.createFileName(type);

        fileName = newFileName != null ? newFileName : fileName;

        // 上传文件并返回相对路径
        String resultPath = null;
        try {
            resultPath = flowService.uploadFile(file.getBytes(), filePath, fileName);
        } catch (Exception e) {
            LOGGER.error("--uploadFile-- error: {}", e);
            error = e.getMessage();
        }
        if (error != null) {
            resultMap.put("errorMsg", error);
        } else {
            resultMap.put("resultPath", resultPath);
        }

        return resultMap;
    }

  这里MultipartFile是spring自带的,在spring boot中我们无需引入额外的jar包,看下导入的包路径即可明了:

org.springframework.web.multipart.MultipartFile

  再看调用的service:

    /**
     * 上传文件
     *
     * @param file
     * @param filePath
     * @param fileName
     * @return
     * @throws Exception
     */
    public String uploadFile(byte[] file, String filePath, String fileName) throws Exception {

        // 判断文件目录是否存在,不存在则新建
        File targetFile = new File(filePath);
        if (!targetFile.exists()) {
            targetFile.mkdir();
        }

        // 新文件路径
        String fullPath = filePath + "/" + fileName;
        FileOutputStream out = new FileOutputStream(fullPath);
        out.write(file);
        out.flush();
        out.close();

        // 入库路径
        return fullPath.substring(fullPath.indexOf("/"));
    }

  上传是不是很简单?但有两点需要注意:一个是文件上传大小限制,一个是文件存储目录必须要跟js中的展示url建立映射,这两点都需要在application.properties中配置:

#图片保存路径
imgUpload.file.savePath=D:/imgUpload
#上传文件大小设置10M,默认是1M
spring.servlet.multipart.maxFileSize=10485760

  文件路径在上面的Controller里通过定义全局变量filePath,而filePath则是通过注解从application.properties获取

@Value("${imgUpload.file.savePath}")
private String filePath;

  通过新增java配置来映射物理文件地址和web访问url:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfigurer implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/imgUpload/**").addResourceLocations("file:D:/imgUpload/");
    }
}

  我将存放在D盘的imgUpload映射给tomcat下webapps的/imgUpload,这样在dataGrid中展示的/imgUpload/test.jpg(后台入库时存储的图片路径)就能通过本机地址http://localhost:8888/imgUpload/test.jpg访问到并展示出来了。

  

原文地址:https://www.cnblogs.com/wuxun1997/p/10906899.html