Spring

[Apache POI] Spring Boot 엑셀 다운로드

Karla Ko 2023. 1. 7. 20:46
728x90

설문조사 시스템에서 설문조사의 총 결과 데이터를 엑셀로 한눈에 볼 수 있도록 하는 기능을 추가했다.

첫 행은 설문조사의 문항, 두번째 행부터 설문조사의 답변을 조회할 수 있다.


1. pom.xml dependency 추가

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.13</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.13</version>
</dependency>

2. application.yml 추가

spring:
  mvc:
    contentnegotiation:
    favor-parameter: true
    favor-path-extension: true
    media-types:
    xls: application/vnd.ms-excel

 

3. ExcelService 생성 및 엑셀 다운로드 함수 추가

0) 조회할 설문의 데이터(SurveyDTO), 질문과 답변 데이터를 묶은 Map(header, row)

void createExcelDownloadResponse(HttpServletResponse response, SurveyDTO surveyDTO, Map<String, Object> map)

1) Workbook 생성

Workbook workbook = new XSSFWorkbook();

2) sheet 추가

Sheet sheet = workbook.createSheet("설문조사결과");

3) 파일명 변수 선언

final String fileName = "설문결과_" + surveyDTO.getTitle();

3) 첫 줄, 헤더로 사용할 데이터

List<String> header = (List<String>) map.get("header");

Row row = sheet.createRow(0); //첫번째 행 생성
for (int i = 0; i < header.size(); i++) {
    Cell cell = row.createCell(i); // 열 생성
    cell.setCellValue(header.get(i)); // 생성된 열에 header 데이터 입력
}

4) 행 데이터 입력

List<AnswerQuestionDTO> answerList = (List<AnswerQuestionDTO>) map.get("row");
row = sheet.createRow(1);  //헤더 이후로 데이터가 출력되어야하니 +1
int rownum = 1;
for (int j = 0; j < answerList.size(); j++) {

	// 답변 데이터
    AnswerQuestionDTO answerQuestionDTO = answerList.get(j);
    
    Cell cell = null;
    cell = row.createCell(j); // 열생성
    cell.setCellValue(answerQuestionDTO.getAnsContent()); // 답변 데이터 입력
    
    if(j == header.size()-1){ // 모든 질문에 대한 답변 데이터가 입력되면
        row = sheet.createRow(rownum+1);  //헤더 이후로 데이터가 출력되어야하니 +1
   }
}

5) 엑셀 형식으로 출력, Workbook close

response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

workbook.write(response.getOutputStream());
workbook.close();
더보기
package com.cloud.survey.service;

import com.cloud.survey.dto.answer.AnswerQuestionDTO;
import com.cloud.survey.dto.survey.SurveyDTO;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.Workbook;

import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.ss.usermodel.*;

import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;


@Service
@Transactional
@RequiredArgsConstructor
public class ExcelService {

    // 엑셀 다운로드 구현
    void createExcelDownloadResponse(HttpServletResponse response, SurveyDTO surveyDTO, Map<String, Object> map) {

        try {
            Workbook workbook = new XSSFWorkbook();
            Sheet sheet = workbook.createSheet("설문조사결과");

            CellStyle numberCellStyle = workbook.createCellStyle();
            numberCellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0"));

            //파일명
            final String fileName = "설문결과_" + surveyDTO.getTitle();

            //헤더
            List<String> header = (List<String>) map.get("header");
            Row row = sheet.createRow(0);
            for (int i = 0; i < header.size(); i++) {
                Cell cell = row.createCell(i);
                cell.setCellValue(header.get(i));
            }



            List<AnswerQuestionDTO> answerList = (List<AnswerQuestionDTO>) map.get("row");
            row = sheet.createRow(1);  //헤더 이후로 데이터가 출력되어야하니 +1
            int rownum = 1;

            for (int j = 0; j < answerList.size(); j++) {
                AnswerQuestionDTO answerQuestionDTO = answerList.get(j);
                Cell cell = null;
                cell = row.createCell(j);
                cell.setCellValue(answerQuestionDTO.getAnsContent());
                if(j == header.size()-1){
                    row = sheet.createRow(rownum+1);  //헤더 이후로 데이터가 출력되어야하니 +1
                }

            }

            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");

            workbook.write(response.getOutputStream());
            workbook.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4. SurveyService에서 엑셀 다운로드 함수 호출

public void excelDownload (HttpServletResponse response, List<String> headerList, List<AnswerQuestionDTO> answerList, Integer surId){

    SurveyDTO surveyDTO = entityToDTO(surveyRepository.findBySurId(surId));

    Map<String,Object> map = new HashMap<>();
    map.put("header", headerList);
    map.put("row", answerList);

    excelService.createExcelDownloadResponse(response, surveyDTO, map);

}

5) SurveyController에서 api 생성

//엑셀 다운로드
@GetMapping(value = "/download/excel", produces = "application/vnd.ms-excel")
public void excelDownload(HttpServletResponse res, @RequestParam (value = "sur_id") Integer surId) throws UnsupportedEncodingException, ParseException {

    List<String> headerList = questionService.getSurveyQuestionContentList(surId);
    List<AnswerQuestionDTO> answerList = answerService.getAllAnswerList(surId);

   surveyService.excelDownload(res, headerList, answerList, surId);
}

 

 

 

728x90