在过去的几个小时中,我经历了不同的Stack Overflow线程,讨论了如何下载Excel文件以及如何将ByteArrayOutputStreams传递到前端。我有一个Spring Boot后端,它创建一个自定义Excel工作簿和适当的工作表。但是,似乎二进制文件从后端返回到有角度的6前端可能格式错误。我已经包括了不同的服务和控制器以及可能格式错误的数据。
响应正文(截断值):
"PK]�uN_rels/.rels���j�0��}
�{㴃1F�^Ơ�2��l%1I,c�[��3�l
l�����H��4�R�l��·����q}*�2������;�*��
t"�^�l;1W)�N�iD)ejuD�cKz[:}g����@:�
�3����4�7N�s_ni�G�M*7�����2R�+� �2�/�����b��mC�Pp�ֱ$POyQ�抒�DsZ��IС�'un���~�PK����OPK]�uN[Content_Types].xml�SMO1��+6��m��1���G%��β...."
ExcelWriterService.java
private XSSFWorkbook workbook = new XSSFWorkbook();
public byte[] excelExporter(QueryResultsDataset<DataExportTable> data) {
List<DataExportTable> tableList = data.getTables();
List<Map<String, String>> dataRows = tableList.get(0).getRows();
OutputStream outputStream = new ByteArrayOutputStream();
... Create Excel workbook
workbook.write(outputStream);
outputStream.close();
workbook.close();
} catch (IOException ex) {
// Doing nothing
}
return ((ByteArrayOutputStream) outputStream).toByteArray();
Spring Controller
@RequestMapping(value = "<path>", method = RequestMethod.POST)
public @ResponseBody ResponseEntity<byte[]> export(@RequestBody SavedQuery request, Principal principal) {
//Run the job
QueryResultsDataset dataset = dataExportJob.getQueryResultsDataset();
ExcelWriterService ews = new ExcelWriterService();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
StringBuilder filename = new StringBuilder("hello").append(".xlsx");
headers.add("content-disposition", "inline;filename=" + filename.toString());
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
QueryResultsDataset<DataExportTable> fixResults = (QueryResultsDataset<DataExportTable>) fixMultiplier(dataset, request);
byte [] bytes = ews.excelExporter(fixResults);
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
return response;
}
}
Downloader.service.ts(Angular 6服务)
public exportExcel(search: any) {
const opts = [];
const tables = [];
this.api.download(environment._downloadDataEndPoint, search, {})
.subscribe(response => {
console.log(response);
var contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
let blob = new Blob([response], {type: contentType});
let link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = "dataweb.xlsx";
link.click();
}
...
}
Api服务(Angular 6服务)
download(url: string, body: any, header: any) {
header = JSON.parse(this._auth.getToken());
const headers = new Headers(header);
headers.append('responseType', ResponseContentType.Blob.toString());
const options = new RequestOptions({headers: headers});
const response = this.http.post(url, body, options)
.pipe(catchError((error: any) => observableThrowError(error)));
return response;
}
任何帮助都会很棒!我目前没有主意。谢谢!
答案 0 :(得分:0)
您将响应类型设置在错误的位置。 代替
const headers = new Headers(header);
headers.append('responseType', ResponseContentType.Blob.toString());
const options = new RequestOptions({headers: headers});
尝试
const headers = new Headers(header);
const options = new RequestOptions({
headers: headers,
responseType: ResponseContentType.Blob
});
请参见documentation了解RequestOptions类型。