图片即文件,在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="width: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="width:90px">图片上传</a>
<a href="javascript:void(0)" class="easyui-linkbutton c6" iconCls="icon-ok" onclick="saveFlow()"
style="width:90px">保存</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-cancel"
onclick="javascript:$('#dlg').dialog('close')" style="width:90px">取消</a>
</div>

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

    var url;
var uploadPath; $(function () {
$('#photoUrl').filebox({
prompt: '请选择一张图片...',
width: '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='width:30px; height:30px;margin-left:3px;' src='" + value
+ "' title='点击查看全图'/>";
return imgResult;
}
} function download(img) {
var imgTemp = "http://localhost:8888" + img;
$('#dlgImg').dialog({
title: '展示全图',
width: 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访问到并展示出来了。

  

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

  1. iOS图片上传后被旋转的问题

    最近用PHP做了一个图片合成程序,前端是通过HTML的file input选取自定图片,POST到php后台调整尺寸后与事先准备好的背景图进行合成. 通过测试发现,上传后的自定图片有的被旋转了,有的是 ...

  2. 三款不错的图片压缩上传插件(webuploader+localResizeIMG4+LUploader)

    涉及到网页图片的交互,少不了图片的压缩上传,相关的插件有很多,相信大家都有用过,这里我就推荐三款,至于好处就仁者见仁喽: 1.名气最高的WebUploader,由Baidu FEX 团队开发,以H5为 ...

  3. 分离与继承的思想实现图片上传后的预览功能:ImageUploadView

    本文要介绍的是网页中常见的图片上传后直接在页面生成小图预览的实现思路,考虑到该功能有一定的适用性,于是把相关的逻辑封装成了一个ImageUploadView组件,实际使用效果可查看下一段的git效果图 ...

  4. asp.net mvc4 easyui datagrid 增删改查分页 导出 先上传后导入 NPOI批量导入 导出EXCEL

    效果图 数据库代码 create database CardManage use CardManage create table CardManage ( ID ,) primary key, use ...

  5. magento 1.9 上传后图片前后台无法正常显示

    1.上传后图片不显示,设置 允许 flash 2.保证php 执行是内存大小至少为为128M,多种方式设置,这里以init_set为例子,在index.php 加入下面一行代码,根据情况而定 ini_ ...

  6. ueditor百度编辑器中,多图上传后,图片顺序乱掉的处理方法

    上传后,图片的顺序和预期的不一致,需要修改ueditor的源码. 一.找到editor/dialogs/attachment/attachment.js文件 1.将_this.fileList.pus ...

  7. 改变wordpress图片上传后的压缩质量

    WordPress 在图片上传后会默认压缩图片质量为原来的 90%,这样做的好处可以极大的加快页面的载入速度与缩小图片大小所占服务器空间. 如果希望 100% 原质量怎么办呢?如何禁止 WordPre ...

  8. django实现图片上传后自动修改尺寸并保存修改后的图到数据库和本地文件系统

    图片上传首先要是设置settings.py文件(与静态文件设置类似) MEDIA_ROOT = os.path.join(BASE_DIR,'media')MEDIA_URL = '/media/' ...

  9. js实现图片上传后即时预览

    //关于FileReader对象 http://blog.csdn.net/zk437092645/article/details/8745647 <!DOCTYPE html> < ...

随机推荐

  1. 2019-ACM-ICPC-南京区网络赛-E. K Sum-杜教筛+欧拉定理

    2019-ACM-ICPC-南京区网络赛-E. K Sum-杜教筛+欧拉定理 [Problem Description] 令\(f_n(k)=\sum_{l_1=1}^n\sum_{l_2=1}^n\ ...

  2. Luogu P3243 菜肴制作

    Luogu P3243 菜肴制作 神神奇奇的拓扑排序,也就是借这道题学习一下大名鼎鼎的Toposort了-- #include<bits/stdc++.h> #define N 10001 ...

  3. 利其器:无法在 ".vscode" 文件夹()内创建 "launch.json" 文件。

    无法在 ".vscode" 文件夹()内创建 "launch.json" 文件. https://www.cnblogs.com/lidabo/p/588899 ...

  4. php守护进程创建和简要分析

    守护进程可 由系统启动脚本 /etc/rc.local crontab任务, 用户shell 方式运行 具体概念可参考c的 进程守护化基本步骤 1.创建子进程,终止父进程 (pcntl_fork,ex ...

  5. MySQL 空间数据 简单操作

    在做的项目中需要,自己绘制区域图形,并存储起来,后面还有更新的需要,存文件不方面,想到现在数据库都支持空间数据库. 现在用的就是 MySQL ,就继续用 MySQL 来存储.管理空间数据.下面就做一些 ...

  6. css全局定位内容图片自动居中

    最近在做一个资讯站点时候,因为采集的数据,图片不居中,导致界面很不美观,所以需要全局定义下图片输出时候进行居中. .content img { max-width:800px;_width:expre ...

  7. java中的switch

    switch 语句由一个控制表达式和多个case标签组成. switch 控制表达式支持的类型有byte.short.char.int.enum(Java 5).String(Java 7). swi ...

  8. Spring如何给静态变量注入值

    Common.java是一个工具类. Spring无法直接给静态变量注入值,因为静态变量不属于对象,只属于类,也就是说在类被加载字节码的时候变量已经初始化了,也就是给该变量分配内存了,导致spring ...

  9. P3588 [POI2015]PUS

    好题 思路:线段树优化建图+拓扑DP or 差分约束(都差不多): 提交:3次 错因:眼瞎没看题,Inf写的0x3f3f3f3f 题解: 类似差分约束的模型,\(a<b\rightarrow a ...

  10. 洛谷 P2038 无线网络发射器选址 题解

    每日一题 day9 打卡 Analysis 这道题是个模拟,两个0~128( 注意不是1~128 )的循环枚举正方形中心点,判断正方形的边界,再用循环枚举公共场所的数量就好了. 时间复杂度 < ...