Angular多文件上传

不同于传统JSP应用直接可以使用<input type="file"/>进行文件上传,在Angular中表单一般是绑定到后台的一个对象上,然后通过AJAX对服务器发起异步请求,那么如何在Angular中实现文件上传呢?

前端实现

此处我们使用primeNG提供的文件上传组件

1
2
<p-fileUpload #fileUpload name="file" mode="basic" chooseLabel="上传附件"[multiple]="true"
[auto]="true" customUpload="true" (uploadHandler)="myUploader($event)"></p-fileUpload>

但是除了文件本身外,我们还需要提交一些额外的JSON数据给服务器进行处理,所以将customUpload属性设为true,然后自定义自己的上传逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//上传的具体实现方法
myUploader(event){
//new 一个FormData对象来保持我们的提交信息
let formDate: FormData = new FormData();
event.files.forEach(file => {
formDate.append('file', file);
});
//加上其它需要传到后端的信息,采用JSON编码
formDate.append('yourInformation', JSON.stringify(yourInformation));
//调用http服务上传文件
this.yourHttpService.Upload(formDate).subscribe(res => {
console.log(res);
}, error => {
console.log(error)
});
}

此处不要手动指定Content-Type,angular会自动指定类型为multipart/form-data,并且生成随机字符串来分隔不同的文件与json

后端实现

后端采用spring mvc来处理请求,注意前端传过来的JSON信息无法直接解析(可能是我的处理方式不对),所以作为字符串类型接受,文件由于我们采用了多文件上传,所以接受的参数类型是`MultipartFile[]``

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@RequestMapping(value = "", method = RequestMethod.POST)
public ResponseEntity upload(@RequestParam("yourInformation") String yourInformation, HttpServletRequest request, @RequestParam("file") MultipartFile[] files) {
//解析JSON到对象YourObject
YourObject yourObject= (YourObject) JSONObject.toBean(JSONObject.fromObject(yourInformation),YourObject.class);
//获取文件实际存储路径
String path = request.getServletContext().getRealPath("/WEB-INF/InteriorWorkAttachment/");
final boolean[] flag = {true};
Arrays.asList(files).forEach(file -> {
String fullname = file.getOriginalFilename();
if (//你的上传业务逻辑,返回一个布尔类型的值,成功返回true)) {
flag[0] = false;
}
});
if (flag[0]) {
return ResponseEntity.ok("上传成功");
} else {
return ErrorResponseEntity.buildToResponseEntity(400, "上传失败,文件已经存在!");
}
}

下载参考

下载时直接获取文件在服务器的路径然后用byte[]进行返回,在前端使用window.open(url)打开即可。不推荐使用window.location.href=
遇到异常,如文件不存在时,后者会导致angular应用整个跳转到错误页面。而前者是新打开一个错误页。
下载实现代码参考:

1
2
3
4
5
6
public ResponseEntity getExportStandardIndex() throws IOException {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentDispositionFormData("attachment", URLEncoder.encode("你的文件名", "UTF-8") + "." + "xlsx");
return new ResponseEntity<>(standardIndexService.getExportIndexByStandardSn(standardSn), headers, HttpStatus.OK);
}