目前在做一个excel导入功能。前端框架用的EasyUI, 而弹出层用的LayUI中独立的Layer 。后端用的SpringCoud ,涉及到两个微服务,第一个微服务是表现层,第二个微服务是业务层。第一个微服务通过RestTemplate请求第二个微服务中的接口方法。
在这样的一个情况下,我最初做文件上传的时候还是遇到了不少的问题,包括前端和后端,也是查阅了很多资料。但是技术博客千篇一律,大都是复制或转发,你懂得。所以呢,我也做了很多的尝试,最终成功解决了问题。我不知道这篇文章对你是否有帮助,就当是给你提供一个思路吧。
HTML
<button type="button" class="btn btn-outline btn-primary" onclick="importGroupUser()">excel导入</button>
点击“excel导入”按钮 , 会调用一个js方法。这个js方法使用layer打开一个弹窗,弹窗中的内容就是下面这段html代码(它的存在就是为了实现文件选择)。
<div class="col-sm-12" id="GroupUserImportingDialog" style="display: none;">
<form id="importFileForm" method="post" enctype="multipart/form-data" >
<div class="col-sm-12" style="padding-top: 10px;">
<input type="file" id="ExcelFile" name="ExcelFile" />
</div>
</form>
</div>
JS
function importGroupUser() {
layer.open({
type: 1, //页面层
title: '导入群组用户',
shade: false,
shadeClose: true,
maxmin: true, //开启最大化最小化按钮
area: ['20%', '20%'],
content: $("#GroupUserImportingDialog"),
zIndex: 100, //用于解决和easyui-combobox的层叠冲突
btn: ['导入', '取消'],
btn1: function (index, layero) {
// var file = $("#ExcelFile").filebox('files'); //filebox的files必须要EasyUI 1.5.4 版本中才可以使用
var file = document.getElementById("ExcelFile").files[0];
var formData = new FormData();
formData.append("ExcelFile",file );
$.ajax({
url: Url + "userGroup/importGroupUser",
type:'POST',
data: formData,
processData: false,
contentType:false,
success : function(data) {
console.log(data);
if (data.result == 1) {
layer.msg(data.msg , {icon: 1});
} else {
layer.msg(data.msg , {icon: 5})
}
layer.close(index);
}
});
},
btn2: function (index, layero) {
layer.close(index);
},
success: function (layero, index) {
}
});
}
通过layer.open() 方法来打开一个弹出框,在弹出框中可以选择上传文件。btn1后面的函数表示在弹框里面 “导入” 按钮按下后需要执行的操作。
最开始我打算使用EasyUI的files方法来获取文件对象,但这需要EasyUI 版本为1.5.4及以上,于是我换成了使用原生js获取(当然你使用jquery也可以)。
拿到文件对象后,你需要new一个FormData对象 (即表单数据对象),并将文件对象添加到FormData对象中。最后使用jquery的ajax方法提交这个FormData对象就可以了。
注意:type(即提交方式)需要设置为POST
processData 设置为false ,告诉jQuery不要对参数进行处理
contentType 告诉jQuery不要对contentType做处理,服务器会做处理
controller
@RequestMapping(value = "/importGroupUser" ,method = RequestMethod.POST )
@ResponseBody
public Result importGroupUser( HttpServletRequest servletRequest,@RequestParam(value="ExcelFile") MultipartFile multipartFile ) throws IOException {
RestTemplate restTemplate = new RestTemplate();
String url = sysurl + "userGroup/importGroupUser";
/** 将MultipartFile对象的字节数据,封装到ByteArrayResource对象中*/
ByteArrayResource fileAsResource = new ByteArrayResource(multipartFile.getBytes()) {
@Override
public String getFilename() {
return multipartFile.getOriginalFilename();
}
@Override
public long contentLength() {
return multipartFile.getSize();
}
};
/** Http请求body部分 */
MultiValueMap<String,Object> body = new LinkedMultiValueMap<>();
body.add("file" ,fileAsResource);
//获取当前登录用户
User loginUser = (User) servletRequest.getSession().getAttribute("user");
body.add("loginUserId" ,loginUser.getId());
body.add("ip" , servletRequest.getRemoteAddr());
/** Http请求header部分 */
HttpHeaders headers = new HttpHeaders();
headers.add("Accept",MediaType.APPLICATION_JSON.toString());
headers.setContentType(MediaType.parseMediaType("multipart/form-data;charset=UTF-8"));
/** 构造HttpEntity对象 */
HttpEntity<MultiValueMap<String,Object>> formEntity = new HttpEntity<>(body,headers);
/** 通过RestTemplate执行POST请求 */
ResponseEntity<Result> responseEntity = restTemplate.postForEntity(url,formEntity, Result.class);
Result result = responseEntity.getBody();
return result;
}
对于前端传递过来的文件对象,后台方法使用MultipartFile对象作为接收参数就可以了。然后其余的地方可以参考代码中的注释部分。
第三方应用controller
@RequestMapping(value = "/importGroupUser", method = RequestMethod.POST)
public Result importGroupUser(@RequestParam(value = "file") MultipartFile multipartFile ,
@RequestParam(value = "loginUserId") String loginUserId ,
@RequestParam(value = "ip") String ip ) {
ImportParams params = new ImportParams();
params.setHeadRows(1);
List<GroupUser> list = null;
try {
list = ExcelImportUtil.importExcel( multipartFile.getInputStream() , GroupUser.class, params);
} catch (Exception e) {
e.printStackTrace();
}
if (list == null || list.isEmpty()){
return Result.failureResult("excel中未读取到数据");
}
userGroupService.importGroupUser(list ,loginUserId ,ip);
return Result.successResult("导入成功");
}
这里的第二方系统controller中也是用MultipartFile对象作为接收参数,除此之外还可以接收额外的参数。我们这里做的excel上传,其实也是文件上传。处理excel数据用的EasyPoi ,这个API非常的好用,如果你没接触过这个的话那么可以了解下。