我需要在客户端使用angular下载文件,该文件可以具有pdf或excel或image或txt的任何格式…我的方法仅适用于txt文件,但给我excel和image的失败格式,对于pdf,它会给出一个空的pdf。
所以在我的控制器中,这里是调用service方法的函数:
vm.downloadFile = downloadFile; function downloadFile(file){ var urlDir = "C://STCI//"+idpeticion; return VerDocServices.downloadFile(file,urlDir) .then(function(response) { var data = response.data; var filename = file; var contentType = 'application/octet-stream';//octet-stream var linkElement = document.createElement('a'); try { var blob = new Blob([ data ], { type : contentType }); var url = window.URL.createObjectURL(blob); linkElement.setAttribute('href', url); linkElement.setAttribute("download", filename); var clickEvent = new MouseEvent("click", { "view" : window, "bubbles" : true, "cancelable" : false }); linkElement.dispatchEvent(clickEvent); } catch (ex) { console.log(ex); throw ex; } }).catch(function(response) { alert('Se ha producido un error al exportar del documento'); console.log(response.status); throw response; }); }
而我的service.js具有:
angular.module('mecenzApp').service('VerDocServices',['$http',function($http) { this.downloadFile = function(file,urlDir) { return $http.get('api/downloadFile', { params : { file : file, urlDir : urlDir } }); }} ]);
我的服务方法是这样的:
@GetMapping("/downloadFile") @Timed public ResponseEntity<byte[]> downloadFile(@RequestParam(value = "file") String file, @RequestParam(value = "urlDir") String urlDir) { log.debug("GET ---------------- DOWNLOAD FILE : {}", file); log.debug("GET ---------------- From the DIRECTORY: {}",urlDir); InputStream fileStream; String filepath = urlDir+File.separator+file; try { File f = new File(filepath); log.debug("GET ---------------- FILE: {}",f.getPath()); fileStream = new FileInputStream(f); byte[] contents = IOUtils.toByteArray(fileStream); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.parseMediaType("application/octet-stream")); String filename = file; headers.setContentDispositionFormData(filename, filename); ResponseEntity<byte[]> response2 = new ResponseEntity<byte[]>(contents, headers, HttpStatus.OK); fileStream.close(); return response2; } catch (FileNotFoundException e) { System.err.println(e); } catch (IOException e) { System.err.println(e); } return null; }
你能看看我告诉我我错过了什么吗?
谢谢你:)
下载二进制文件时,重要的是设置responseType:
responseType
app.service('VerDocServices',['$http',function($http) { this.downloadFile = function(url, file, urlDir) { var config = { //SET responseType responseType: 'blob', params : { file : file, urlDir : urlDir } }; return $http.get(url, config) .then(function(response) { return response.data; }).catch(function(response) { console.log("ERROR: ", response.status); throw response; }); }; }]);
如果responseType省略,则XHR API默认将UTF-8编码的文本转换为DOMString(UTF-16),这将损坏PDF,图像和其他二进制文件。
有关更多信息,请参见MDN Web API参考-XHR ResponseType