springboot layui实现带进度条的多文件上传tag
1.tag代码
<script type="text/javascript" data-th-inline="javascript">
var xhrOnProgress=function(fun) {
xhrOnProgress.onprogress = fun; //绑定监听
//使用闭包实现监听绑
return function() {
//通过$.ajaxSettings.xhr();获得XMLHttpRequest对象
var xhr = $.ajaxSettings.xhr();
//判断监听函数是否为函数
if (typeof xhrOnProgress.onprogress !== 'function')
return xhr;
//如果有监听函数并且xhr对象支持绑定时就把监听函数绑定上去
if (xhrOnProgress.onprogress && xhr.upload) {
xhr.upload.onprogress = xhrOnProgress.onprogress;
}
return xhr;
}
}
$(document).ready(function() {
layui.use(['upload','element','layer'], function(){
var $ = layui.jquery;
var upload = layui.upload,element = layui.element,layer = layui.layer;
//多文件列表示例
var count=0;
var context=$("[name=context]").val();
var demoListView = $('#${id}fList')
,uploadListIns = upload.render({
elem: '#${id}upList'
,url: '${url}'
,accept: 'file'
,size:'${filesize}'
,multiple:${isMultiple}
,xhr:xhrOnProgress
,progress:function(value,obj){//上传进度回调 value进度值
$("#${id}fList").find('.layui-progress ').each(function () {
if( $(this).attr("file")==obj.name){
var progressBarName= $(this).attr("lay-filter");
var percent=Math.floor((value.loaded / value.total)*100);//计算百分比
element.progress(progressBarName, percent+'%')//设置页面进度条
}
})
}
,auto: false
,bindAction: '#${id}upListAction'
,choose: function(obj){
var files = this.files = obj.pushFile(); //将每次选择的文件追加到文件队列
//读取本地文件
obj.preview(function(index, file, result){
count++;
var tr = $(['<tr id="${id}upload-'+ index +'">'
,'<td>'+ file.name +'</td>'
,'<td>'+ (file.size/1014).toFixed(1) +'kb</td>'
,'<td>'
+'<div file="'+file.name+'" class="layui-progress layui-progress-big" lay-showpercent="true" lay-filter="progressBar'+count+'">'
+'<div class="layui-progress-bar layui-bg-red" lay-percent="0%"></div>'
+'</div>'
, '</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>'
,'</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.code == 1){ //上传成功
if($("#${id}fList").val() == ""){
$("#${id}fList").val(res.url);
}else{
$("#${id}fList").val($("#${id}fList").val()+"@@[email protected]@"+res.url);
}
var tr = demoListView.find('tr#${id}upload-'+ index)
,tds = tr.children();
tds.eq(3).html('<span style="color: #5FB878;">上传成功</span>');
tds.eq(4).html(''); //清空操作
return delete this.files[index]; //删除文件队列已经上传成功的文件
}
this.error(res,index, upload);
}
,error: function(res,index, upload){
//element.progress('progressBar', '0%');
var tr = demoListView.find('tr#${id}upload-'+ index)
,tds = tr.children();
tds.eq(3).html('<span style="color: #FF5722;">上传失败,'+res.msg+'</span>');
tds.eq(4).find('.demo-reload').removeClass('layui-hide'); //显示重传
}
});
})
});
</script>
<div class="layui-input-block layui-btn-container">
<button type="button" class="btn btn-white btn-sm" id="${id}upList">${labelname}</button>
<button type="button" class="btn btn-white btn-sm" id="${id}upListAction">开始上传</button>
</div>
<div class="layui-input-block">
<div class="layui-upload">
<div class="layui-upload-list">
<table class="layui-table">
<thead>
<tr><th>文件名</th>
<th>大小</th>
<th>上传进度</th>
<th>状态</th>
<th>操作</th>
</tr></thead>
<tbody id="${id}fList" value="${value}"></tbody>
</table>
</div>
</div>
</div>
目录:
2.前端tag调用示例:
<!DOCTYPE html>
<html xmlns:th="http://www.w3.org/1999/xhtml">
<head>
<#inc:head/>
<script type="text/javascript">
$(document).ready(function() {
$("#btnImport").click(function(){
//验证选择文件后必须上传完成才能提交
var flag = false;
$("#testfList").find('.layui-progress ').each(function () {
if($(this).children().attr("style") != "width: 100%;") {
flag = true;
return;
}
})
if(flag){
top.layer.alert('请先上传选择的文件!', {icon: 0, title: '提示'});
return;
}
alert("文件路径:"+$("#testfList").val())
});
});
</script>
</head>
<body class="layui-layout-body" style="overflow: auto;">
<div class="layui-form-item">
<label class="layui-form-label">输入框</label>
<div class="layui-input-block">
<input type="text" id="fileTitle" name="fileTitle" required lay-verify="required" placeholder="请输入标题" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item layui-form-text">
<label class="layui-form-label">文本域</label>
<div class="layui-input-block">
<textarea id="remarks" name="remarks" placeholder="请输入" class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-form-item">
<#fileImport:multifile
id="test"
filesize="2048"
isMultiple="true"
labelname="上传文件"
value=""
url="${ctx}/filetest/uploadmulti3/"
/>
</div>
<div class="layui-input-block layui-btn-container">
<button type="button" class="btn btn-white btn-sm" id="btnImport">模拟提交</button>
</div>
</body>
</body>
</html>
3、后端controller实现
@Controller
@RequestMapping(value = "${adminPath}/filetest")
public class FilesTestController extends BaseController {
@PostMapping("uploadmulti3")
@ResponseBody
public Map<String, Object> noticeFile(HttpServletRequest request, @RequestParam(name = "file") MultipartFile files) {
Map<String, Object> resMap = FileUtils.uploadFile2(files,"");
return resMap;
}
@RequestMapping("home9")
public ModelAndView home9(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("modules/file/uploadMulti3.html");
return modelAndView;
}
}
4、上传代码实现
public static Map<String, Object> uploadFile2(MultipartFile fileList,String filePath) {
try {
filePath ="D:\\files\\"+filePath;
//String timeMillis = Long.toString(System.currentTimeMillis());// 时间戳
String filename = fileList.getOriginalFilename();
File dir = new File(filePath);
if (!dir.exists()) {
dir.mkdirs();
}
String endpath = filePath + filename;
File serverFile = new File(endpath);
fileList.transferTo(serverFile);
Map<String, Object> map = new HashMap<String, Object>();
map.put("code", "1");
map.put("url", endpath);
return map;
} catch (Exception e) {
e.printStackTrace();
Map<String, Object> map = new HashMap<String, Object>();
map.put("code", "0");
return map;
}
}
5、layui upload.js修改,放置工程目录覆盖原有的
layui.each(a, function (e, a) {
var r = new FormData;
r.append(l.field, a), layui.each(l.data, function (e, i) {
i = "function" == typeof i ? i() : i, r.append(e, i)
}), i.ajax({
url: l.url,
type: "post",
data: r,
contentType: !1,
processData: !1,
dataType: "json",
xhr:l.xhr(function(e){//此处为新添加功能
var percent=Math.floor((e.loaded / e.total)*100);//计算百分比
l.progress(e,a);//回调将数值返回
//console.log(e,"e2")
}),
headers: l.headers || {},
success: function (i) {
t++, d(e, i), u()
},
error: function () {
n++, o.msg("请求上传接口出现异常"), m(e), u()
}
})
})
6、实现效果
备注:多文件路径的拼接可以通过 组件value获得,用于和其他数据一起表单提交