[Spring] 엑셀파일 깨짐 현상

🤷‍♂️ 문제상황

엑셀 파일의 내용에 문제가 있습니다. 이 통합문서의 내용을 최대한 복구하시겠습니까?


Spring으로 SXSSF로 대용량 엑셀파일을 다운로드하는 API를 만드는중, 이런 오류가 생겼다.

 

💁‍♀️1트

엑셀 Object를 제대로 close 하지 않으면 이런 현상이 발생할 수 있다고 한다.

try (SXSSFWorkbook workbook = new SXSSFWorkbook(100); OutputStream out = response.getOutputStream()) {
	머시기 머시기 엑셀처리
} catch (IOException e) {
            e.printStackTrace();
            throw new BadRequestException(ServerResponse.FAIL_TO_CREATE_EXCEL);
}

Auto Try Close를 활용하여 close에 누락이 없도록 처리했다.

똑같았다.

💁‍♀️2

sheet.setColumnWidth(i, 256 * 15); // 기본 너비 설정

기본너비로 설정해준 값보다 열 값을 많이 넣으면 그럴 수 있다고 한다.
아니었다.

💁‍♀️3

엑셀파일 전송을 위한 content-type 및 header를 다시 확인해보았다.

// HTTP 응답 설정
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
String encodedFilename = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
response.setHeader("Content-Disposition",
        String.format("attachment; filename*=UTF-8''%s.xlsx", encodedFilename));

딱히 문제되는 부분이 없었다.

🙆‍♂️해결

다소 어이없는 해결이었는데

Controller 단에서는 일괄적으로 이렇게 ResponseEntity를 전송하고있었다.

	@PostMapping("/list/download/excel")
	public ResponseEntity<ServerResponse> createExcel(@RequestParam Map<String, Object> param, HttpServletResponse response) {
		contentService.selectContentListToExcel(response, param);
		return ResponseEntity.ok(ServerResponse.SUCCESS);
	}

 

그런데 이 ResponseEntity에서 Content-type을 json으로 수정한다는 얘기가 있었다.

그래서 아래와 같이 void리턴으로 수정했다.

	@PostMapping("/list/download/excel")
	public void createExcel(@RequestParam Map<String, Object> param, HttpServletResponse response) {
		contentService.selectContentListToExcel(response, param);
	}

🧚‍♀️결과

 

확인결과 기존에는 application/problem+json타입으로 오다가

 

위에서 지정했던 application/vnd.openxmlformats-officedocument.spreadsheetml.sheet 타입이 리턴되는부분을 확인했다.

엑셀시트를 열었을때도 오류가 없어진것을 확인할 수 있었다.

 

아마도 확장자는 xlsx인데 타입은 json이어서 오류가 났던것같다.