利用layui+spring boot实现多文件上传并与表单一起提交
实现思路
文件上传和表单提交是分开进行的。以下以论文申报为例
文件上传部分:建立一个文件表如下图所示,将文件信息存入表中(其中state,fatherid两项初始值都是0,表示还没有关联论文信息),将文件的id值返回给前端,前端将id值赋值给一个隐藏的input的value。(layui的多文件上传是一个一个进行上传的),比如我上传了3个文件,依次返回了3个文件的id值分别是1、2、3,那么input的value值通过字符串的拼接可以变为“0,1,2,3”这样一个值(0没有实际意义,只是为了格式整齐好处理)
提交部分:点击提交按钮后,后端获取到了论文信息和隐藏的input的value值两部分,将论文信息存到论文信息的表中并获取该论文信息的id值(fatherid),之后将隐藏的input的value值拆解为一个数组(这个数组其实就是上传的文件在表中的id值了),之后遍历数组对每个id所在行的state和fatherid进行更新操作,这样就实现了文件与论文信息的关联。
实现方法比较蠢,表达也挺混乱,大家将就看吧,如果有更好的方法请告诉我,谢谢。
以下是代码部分:其中文件上传部分的代码基本复制了这篇博客的:https://blog.csdn.net/lehek/article/details/104575496
html
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header">论文成果申报</div>
<div class="layui-card-body" style="padding: 15px;">
<form class="layui-form" action="" lay-filter="component-form-group">
<div class="layui-form-item">
<label class="layui-form-label">论文名称</label>
<div class="layui-input-block">
<input type="text" name="name" required lay-verify="required" placeholder="请输入论文名称" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">第一作者</label>
<div class="layui-input-block">
<input type="text" name="first_author" required lay-verify="required" placeholder="请输入论文第一作者" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">刊物名称</label>
<div class="layui-input-block">
<input type="text" name="periodical" required lay-verify="required" placeholder="请输入刊物名称" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">所有作者</label>
<div class="layui-input-block">
<input type="text" name="all_author" required lay-verify="required" placeholder="请输入所有作者,以/分隔:XXX/XX/XX" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">发表时间</label>
<div class="layui-input-block">
<input type="text" id="date" name="date" required lay-verify="required" placeholder="格式:2000-01-01" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">支持基金</label>
<div class="layui-input-block">
<input type="text" name="fund" required lay-verify="required" placeholder="单位:万元" 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 name="remark" placeholder="请输入内容" class="layui-textarea"></textarea>
</div>
</div>
<input id="files" name="files" value="0" class="layui-input" type="hidden">
<div class="layui-upload">
<p>上传论文</p>
<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>
<button type="button" class="layui-btn" id="testListAction">开始上传</button>
</div>
<div class="layui-form-item layui-layout-admin">
<div class="layui-input-block">
<div class="layui-footer" style="left: 0;">
<button class="layui-btn" lay-submit="" lay-filter="add">立即提交</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
js
<script>
layui.use('laydate', function(){
var laydate = layui.laydate;
//执行一个laydate实例
laydate.render({
elem: '#date' //指定元素
});
});
layui.use(['form','layer'], function(){
$ = layui.jquery;
var form = layui.form,layer = layui.layer;
//监听提交
form.on('submit(add)', function(data){
console.log(data.field.files);
$.ajax({
url:"AddUserPaper",
type:"post",
async:true,//异步加载
data:data.field,
success:function (obj) {
if(obj["msg"]=="success"){
alert("提交成功");
// 获得frame索引
var index = parent.layer.getFrameIndex(window.name);
//关闭当前frame
parent.layer.close(index);
window.parent.location.reload(); //刷新父页面
}
if(obj["msg"]=="error"){
alert("error");
}
}
});
return false;
});
});
//文件上传
layui.use('upload', function(){
var $ = layui.jquery
,upload = layui.upload;
//多文件列表示例
var demoListView = $('#demoList')
,uploadListIns = upload.render({
elem: '#testList'
,url: 'paperupload'
,accept: 'file'
,multiple: true
,auto: false
,bindAction: '#testListAction'
,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>'
,'</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 === 0){ //上传成功
var tr = demoListView.find('tr#upload-'+ index)
,tds = tr.children();
tds.eq(2).html('<span style="color: #5FB878;">上传成功</span>');
tds.eq(3).html(''); //清空操作
var nowvalue=$("input[name='files']").val();
console.log('<'+nowvalue);
nowvalue=nowvalue+','+res.id;
console.log('>'+nowvalue);
document.getElementById("files").value=nowvalue;//这里必须要用ById,如果用ByName会赋值无效,猜测可能是input设置了隐藏的原因
return delete this.files[index]; //删除文件队列已经上传成功的文件
}
this.error(index, upload);
}
,error: function(index, upload){
var tr = demoListView.find('tr#upload-'+ index)
,tds = tr.children();
tds.eq(2).html('<span style="color: #FF5722;">上传失败</span>');
tds.eq(3).find('.demo-reload').removeClass('layui-hide'); //显示重传
}
});
});
</script>
UploadController
package com.example.demo.controller;
import com.example.demo.bean.FileInfoBean;
import com.example.demo.service.FileInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
@Controller
public class UploadController {
@Autowired
FileInfoService fileInfoService;
@RequestMapping("paperupload")
@ResponseBody
public String paperupload(MultipartFile file){
System.out.println(file);
String pathString=null;
String nowid=null;//要返回给前端的上传的文件在文件表中的id
if(file!=null){
//获取上传的文件名称
String filename = file.getOriginalFilename();
//文件上传时,chrome与IE/Edge对于originalFilename处理方式不同
//chrome会获取到该文件的直接文件名称,IE/Edge会获取到文件上传时完整路径/文件名
//Check for Unix-style path
int unixSep = filename.lastIndexOf('/');
//Check for Windows-style path
int winSep = filename.lastIndexOf('\\');
//cut off at latest possible point
int pos = (Math.max(winSep, unixSep));
if (pos != -1)
filename = filename.substring(pos + 1);
String savename=new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + "_" +filename;
pathString = "E:/upload/" + savename;//上传到本地
int a=fileInfoService.addFile(filename,pathString,savename);
System.out.println("文件添加结果:"+a);
FileInfoBean fileInfoBean=fileInfoService.getFileInfoBySavename(savename);
nowid= String.valueOf(fileInfoBean.getId());
System.out.println("nowid:"+nowid);
}
try {
File files=new File(pathString);//在内存中创建File文件映射对象
//打印查看上传路径
System.out.println(pathString);
if(!files.getParentFile().exists()){//判断映射文件的父文件是否真实存在
files.getParentFile().mkdirs();//创建所有父文件夹
}
file.transferTo(files);//采用file.transferTo 来保存上传的文件
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "{\"code\":0, \"msg\":\"success\", \"fileUrl\":\"" + pathString + "\",\"id\":\""+nowid+"\"}";
}
}
表单提交的controller
@RequestMapping("/AddUserPaper")
@ResponseBody
public Object addPaper(PaperBean paperBean,String files,HttpSession session){
Map<String,String> map=new HashMap<>();
paperBean.setAccount((String) session.getAttribute("account"));
paperBean.setSubmiter((String) session.getAttribute("name"));
int a=paperService.addpaper(paperBean);
String[] ids=files.split(",");//分解字符串获取上传文件在文件表中的id
for(int i=1;i<ids.length;i++){//遍历进行对state和fatherid的更新操作,相当于建立所上传文件与论文信息之间的关系
int updateinfo1=fileInfoService.updateFatherid(paperBean.getId(),Integer.parseInt(ids[i]));
int updateinfo2=fileInfoService.updateFileState(1,Integer.parseInt(ids[i]));
}
System.out.println(files);
if(a==1){
map.put("msg","success");
return map;
}else{
map.put("msg","error");
return map;
}
}