Spring Boot에서 Excel 파일 다운로드 기능 구현하기

..·2025년 9월 8일

finder

목록 보기
22/23

데이터를 목록 형태로 제공하는 마트를 구현하는 과정에서, 목록 데이터를 엑셀 파일로 다운로드에 대한 요청이 발생했다.
Java로 Microsoft Office 문서를 처리하는 표준 라이브러리인 Apache POI를 이용하여 엑셀 파일 다운로드 API를 구현한 과정을 정리했다.


의존성 추가하기

build.gradle


dependencies {
	...
    implementation 'org.apache.poi:poi:5.2.4'
	implementation 'org.apache.poi:poi-ooxml:5.2.4'
}

Spring Boot에서 엑셀 파일을 생성하기 위해서는 Apache POI가 필요하다.
위와 같이 build.gradlepom.xml 의존성을 추가한다.


엑셀 파일을 생성하는 Service 구현하기

ExcelService.java

@Service
public class ExcelService {
	
    public Workbook createExcel(List<ExcelDTO> excels) {
    	
    	Workbook workbook = new XSSFWorkbook();
        Sheet sheet = workbook.createSheet("excel sheet name");
        
     	...
        
        // 헤더 행 생성
        Row headerRow = sheet.createRow(0);
        String[] headers = {"column_1", "column_2", ... };
        
        for (int i = 0; i< headers.length; i++) {
        	Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
        }
        
        // 데이터 셀 생성
        int rowNum = 1;
        for (ExcelDTO dto : excels) {
        	Row row = sheet.createRow(rowNum++);
            
            Cell firstColumnCell = row.createCell(0);
            firstColumnCell.setCellValue(dto.getFirstColumn));
            
            ...
            
        }
        
        // 셀 크기 지정
        for (int i = 0; i< headers.length; i++) {
        	sheet.autoSizeColumn(i);
            if (sheet.getColumnWidth(i) > 5000) {
            	sheet.setColumnWidth(i, 5000);
            }
        }
        return workbook;
    }
}

엑셀 파일 생성 대상인 데이터를 ExcelDTO로 선언했다.
엑셀 파일을 생성하는 API는 데이터를 List<ExcelDTO> 형태로 받고, ExcelService에서 파일을 생성한다.
여기서 DTO의 값들은 모두 String 형식으로 선언했다.


Controller 구현하기

ExcelController.java

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class ExcelController {

	@Autowired
    private ExcelService excelService;
    
    public ExcelController(ExcelService excelService) {
    	this.excelService = excelService;
    }
    
    @PostMapping
    @RequestMapping("/excel/download")
    public ResponseEntity<?> downloadExcel(@RequestBody List<ExcelDTO> excels) throws IOException {
    
    	// 데이터 유효성 검사
    	...
        
        // 엑셀 파일 생성
        Workbook workbook = excelService.createExcel(excels);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        workbook.write(out);
        workbook.close();
        
        // HTTP 헤더 생성
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDisposition(ContentDisposition.builder("attachment")
                .filename("DataFile.xlsx")
                .build());
                
        return ResponseEntity.ok()
                .headers(headers)
                .body(out.toByteArray()); 
    }
}

엑셀 파일을 생성할 때, 파일에 사용할 데이터를 JSON 형태로 POST 요청을 보낸다. DTO 형식의 배열 데이터를 활용하여 엑셀 파일을 생성하고, 이를 반환하여 다운로드 한다.

API 구조

엑셀 다운로드 기능은 클라이언트가 요청을 보내면, Controller에서 RequestBody로 전달받은 데이터를 DTO 형태로 Service에 전달한다. Service에서는 Workbook을 사용한 엑셀 시트 파일 데이터를 생성하여 Controller에 반환하고, Controller에서는 Client에게 해당 파일을 다운로드 가능한 형태로 전달하며 종료된다.

위의 내용으로 구현한 API를 통해, 다운로드 가능한 엑셀 파일을 전달받을 수 있었다.


마무리

나는 Spring Boot를 이용하면서 매번 형변환 부분에서 헷갈리고 실수하는 것 같다.
처음에는 엑셀 파일 다운로드를 위해 DTO를 생성하는 과정에서 기존에 사용하던 DTO와 데이터가 같아서 그대로 사용했는데 오류가 발생했다.
예를 들어, 기존의 항목은 Integer로 선언되었지만, get() 메소드 오버라이팅을 통해 문자열 데이터가 되면서 같은 데이터 형식이라도 동일한 DTO에서 인식하지 못하는 문제가 있었다. 이 부분은 ExcelDTO를 추가로 구현하여 해결했지만, 이런 부분에서 실수하지 않도록 조금 더 확인할 필요가 있을 것 같다.

0개의 댓글