导出时损坏的Excel xlsx

时间:2019-03-21 21:13:56

标签: java angular spring-boot

在过去的几个小时中,我经历了不同的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;
   }

任何帮助都会很棒!我目前没有主意。谢谢!

1 个答案:

答案 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类型。