Angular 5从Spring Boot保存损坏的Excel文件

时间:2018-09-26 16:12:42

标签: excel angular spring-boot xlsx filesaver.js

我真的被困在这里。我已经阅读了许多有关此问题的文章,但此示例无用。我尝试使用不同的contentType作为Blob,bufferArray ...,但没有结果。

我有这个简单的Spring Boot控制器

@RequestMapping(value = "/square/export-excel", method = RequestMethod.POST)
public void exportExcel(@RequestBody List<SquaredEmissions> dto, HttpServletResponse response) {

  try {
    Workbook book = new XSSFWorkbook();
    byte[] output = excelHelper.exportExcel(book);
    filesHelper.serveXlsxBrowser(response, output, "excel.xlsx");

  } catch (Exception e) {
    LOGGER.error(e.getMessage(), e);
  }
}

和帮助程序代码:

public byte[] exportExcel(Workbook book) throws IOException {

  if (book == null) {
    return new byte[0];
  }

  ByteArrayOutputStream output = new ByteArrayOutputStream();
  book.write(output);
  output.close();

  return output.toByteArray();
}

public void serveXlsxBrowser(HttpServletResponse response, byte[] file, String fileName)
    throws IOException {

  response.setContentType(
    "Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=UTF-8");
  response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
  response.getOutputStream().write(file);
  response.getOutputStream().flush(); 
}

然后在Angular服务中,我正在执行以下呼叫

export () {

const headers = new Headers();
headers.append('Accept', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=UTF-8');

this.http
  .post(this.PATHS.export, this.squareService.getEmissions(), { headers: headers } )
  .toPromise()
  .then(response => {
    console.log(response);
    this.fileService.saveExcelToFileSystem(response);
  });  }


saveExcelToFileSystem (response) {

const contentDispositionHeader: string = response.headers.get('Content-Disposition');
const blob = new Blob([response._body], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; ; charset=UTF-8' });

if (contentDispositionHeader != null) {
  const parts: string[] = contentDispositionHeader.split(';');
  let filename = parts[1].split('=')[1];
  filename = filename.substring(1, filename.length - 1);

  saveAs(blob, filename);

} else {
  saveAs(blob);
}

}

之后,我要下载一个excel文件(.xlsx),但该文件已损坏且无法读取。 响应的_body看起来像 PK��:M_rels /.rels���J1���Pr��� “�u/”�Md}��ff�L��F���E] w @�c���H��9L�r。 ��E�������nu�F�G2v7�g��P�N| *Bb10��k��(i8Q���s@�e�uB;bOzӶ�:e�1U흁�wkP�=��yү��'汩�:xK��X�:o��s�('ҏ^�^��|�8����.���:4EGn�je�T��.N8Y��7����@�?�?����P;�PK�A���UPK��:M[Content_Types].xml���N�0��H�C�+�]8 �=�s�J�X�Mc����}{6i��PT��X3��x�܍W�UK���ЈK9� �F�O��Q�。Q�����

我不知道为什么。

1 个答案:

答案 0 :(得分:0)

似乎Angular与该问题无关。尽管我不确定这是否正确,但至少它能起作用

在我的示例中,我试图导出一个空的Excel文件

new XSSFWorkbook();

现在我要向该Excel文件的第一个单元格添加一些虚拟值,并且导出工作正常。

Workbook book = new XSSFWorkbook();
Sheet sheet = book.createSheet();
Row row = sheet.createRow(0);
row.createCell(0).setCellValue("hello");

这样,无论Content-type是否正确定义,或者excel版本是.xls或.xlsx。

现在我对Apache POI库有疑问,也许写一些内容对于正确导出是必须的。