Угловая и весенняя загрузка — Сохранение файла Excel / Ошибка «Ответ не является большим двоичным объектом» во второй раз

#angular #excel #spring-boot #apache-poi #blob

Вопрос:

У меня следующая проблема: я пытаюсь загрузить файл Excel (.xlsx) из REST-API.

Краткое описание приложения: Существуют проекты, которые можно загрузить в виде файла Excel со всеми их данными.

Все работает при первой загрузке файла. Но если я попытаюсь загрузить файл во второй раз, произойдет ошибка «Ответ не является большим двоичным объектом». Я использую Angular 11 и Spring Boot с POI Apache.

Я установил некоторые точки останова и заметил, что точка останова в моем Бэкэнд-контроллере dosent срабатывает во второй раз, поэтому я предполагаю, что это ошибка интерфейса (также нет ошибки в Spring-Консоли).

Вот мой код:

 // Component (the selected projects ids are emitted to the service)
      exportProjects() {
       const exportIds = this.selection.selected.map(x => x.id);
       this.projectService.downloadSelectedProjects(exportIds);
      }
 
 // Service
  downloadSelectedProjects(selectedProjectIds) {
    let params = new HttpParams();
    params = params.append('selectedProjectIds', selectedProjectIds);
    return this.http.get(this.PROJECT_API_URL   Config.services.projects.exportSelectedProjectListExcel, {
      params: params,
      responseType: 'blob' as 'json' })
      .subscribe(res => {
        let binaryData = [];
        binaryData.push(res);
        let downloadLink = document.createElement('a');
        downloadLink.href = window.URL.createObjectURL(new Blob(binaryData, {type: 'application/octet-stream'}));
        const filename = "test.xlsx";
        downloadLink.setAttribute('download', filename);
        document.body.appendChild(downloadLink);
        downloadLink.click();
    });
  }
 
 // Backend-Controller
    @GetMapping(value = "/exportSelectedProjectListExcel")
    @ResponseBody
    public void exportSelectedProjectListExcel(@RequestParam("selectedProjectIds") List<Long> selectedProjectIds,
                                               HttpServletResponse response) throws IOException {
        try (SXSSFWorkbook xlsx = projectService.getSelectedProjectListExcel(selectedProjectIds)) {
            xlsx.write(response.getOutputStream());
        }
    }
 

Ответ №1:

Чтобы использовать данные Excel в виде большого двоичного объекта в угловой службе , ваш тип ответа должен быть ByteArray ResponseEntity<byte[]> или

     @GetMapping(value = "/exportSelectedProjectListExcel")
        @ResponseEntity<OutputStream> exportSelectedProjectListExcel(@RequestParam("selectedProjectIds") List<Long> selectedProjectIds,
                                                   HttpServletResponse response) throws IOException {
    
            try {
    SXSSFWorkbook xlsx = projectService.getSelectedProjectListExcel(selectedProjectIds)
    response.setContentType("application/octet-stream");
                response.setHeader("Content-Disposition", "attachment; filename=File.xlsx");

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

xlsx.write(response.getOutputStream());

ByteArrayInputStream stream = new ByteArrayInputStream(outputStream.toByteArray());

IOUtils.copy(stream, response.getOutputStream());
return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=File.xlsx")
            .contentType(new MediaType("application", "octet-stream"))
            .body(outputStream);
      }catch(Exception ex){

        }