SpringBoot生成Excel部署AWS EC2后无法打开问题求助
Excel导出接口本地正常,部署AWS EC2后下载文件无法打开
问题描述
SpringBoot开发的Excel导出接口在本地Windows环境运行正常,但部署到AWS EC2服务器后,Angular前端调用API下载的Excel文件无法打开,提示文件格式或扩展名无效。
后端Controller代码
@GetMapping(value = "/export", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<Resource> export(HttpServletResponse httpResponse) { try { List<MyOutPut> data = mydata(); List<String> fieldsToInclude = List.of("id", "Name"); ExportRequest<MyOutPut, ExcelDesignOption> request = new ExportRequest<>( ExportRequest.ExportFormat.EXCELSX, data, fieldsToInclude, MyOutPut.class, "export_data", new ExcelDesignOption() ); System.out.println("Data received now"); ExportUseCase<MyOutPut, ExcelDesignOption> exportUseCase = new ExportUseCase<>(); ExportResponse response = exportUseCase.execute(request); HttpHeaders headers = new HttpHeaders(); headers.setContentDispositionFormData("attachment", response.getFileName()); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); // httpResponse.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); System.out.println("Data received now about to render from vendor"); // Return the file as a byte array response entity // org.apache.commons.io.IOUtils.copy(response.getInputStream(), httpResponse.getOutputStream()); // httpResponse.flushBuffer(); InputStreamResource file = new InputStreamResource(response.getInputStream()); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + "export_data.xlsx") .header(HttpHeaders.CONTENT_TYPE, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") .contentType(MediaType.parseMediaType("application/vnd.ms-excel")).body(file); } catch (Exception e) { log.error("search operation failed ", e); throw new RuntimeException("Error exporting Excel file", e); } }
前端Angular代码
// 调用下载方法 this.downloadExcel(this.id).subscribe({ next: ({ blob, filename }) => this.myService.handleFileDownload(blob, filename), error: (err) => console.error('File download failed', err) }); // HTTP请求方法 return this.http.get(url, { observe: 'response', responseType: 'blob' }).pipe( map(response => { const contentDisposition = response.headers.get('Content-Disposition'); const filename = contentDisposition ? contentDisposition.split('filename=')[1].replace(/"/g, '') : 'Registered Vendor List.xlsx'; return { blob: response.body as Blob, filename }; }) );
文件结构

报错信息
Excel无法打开文件'export_data.xlsx',因为文件格式或文件扩展名无效。请确定文件未损坏,并且文件扩展名与文件的格式匹配。

问题分析与解决方案
后端代码问题修正
修正接口Produces类型
原接口produces设置为APPLICATION_JSON_VALUE,与导出Excel的MIME类型冲突,改为对应xlsx的标准类型:@GetMapping(value = "/export", produces = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")统一Content-Type配置
原代码重复设置Content-Type且类型不一致,统一为xlsx标准类型,并对文件名进行UTF-8编码避免特殊字符问题:return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + URLEncoder.encode("export_data.xlsx", StandardCharsets.UTF_8) + "\"") .contentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) .body(resource);替换InputStreamResource为ByteArrayResource
InputStreamResource在部分服务器环境下可能存在流提前关闭的问题,改用ByteArrayResource确保文件字节完整:// 引入org.apache.commons.io.IOUtils工具类 byte[] fileBytes = IOUtils.toByteArray(response.getInputStream()); ByteArrayResource resource = new ByteArrayResource(fileBytes);
前端代码优化
- 明确指定Blob类型
在文件下载方法中手动指定Blob的MIME类型,避免浏览器自动识别错误:handleFileDownload(blob: Blob, filename: string) { const blobWithType = new Blob([blob], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); const url = window.URL.createObjectURL(blobWithType); const a = document.createElement('a'); a.href = url; a.download = filename; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); }
AWS环境排查
- 检查EC2实例的防火墙/安全组规则,确保响应数据未被截断
- 若使用AWS负载均衡或API Gateway,确认响应头(如Content-Disposition、Content-Type)未被过滤或修改
内容的提问来源于stack exchange,提问作者Dnyaneshwar Jadhav
相关产品推荐
相关产品推荐

