엑셀 다운로드 기능은 쉽다면 쉽고, 어렵다면 어려운데
나는 조회한 값에 회원의 이름과 지역, 전화번호, 신청 교육 리스트가 있다면
엑셀 표 안에는 아래와 같은 식으로 들어가야 했다.
이름 | 지역 | 전화번호 | 신청교육 제목1 | 신청교육 제목2 | 신청교육 제목3 |
---|---|---|---|---|---|
임씨 | 서울 | 01012341234 | 수강률(%) | 수강률(%) | 수강률(%) |
장씨 | 부산 | 01056785678 | 수강률(%) | 수강률(%) | 수강률(%) |
이씨 | 서울 | 01012345678 | 수강률(%) | 수강률(%) | 수강률(%) |
이름과 지역, 전화번호까지 해주는건 그럭저럭 괜찮았는데....신청 교육 리스트 부분이 꽤나 까다로웠다.
일단 POI 라이브러리를 사용해보자.
build.gradle 에서 선언하고 코끼리 한번 클릭해서 build를 해주자.
// excel download : poi implementation 'org.apache.poi:poi:5.2.2' // .xls 확장자 implementation 'org.apache.poi:poi-ooxml:5.2.2' // .xlsx 확장자
참고한 글이다.
내가 구현한 코드는 거의 알고리즘 코딩테스트 느낌으로 엄청난 for문이 존재하므로,
참고한 글처럼 Controller 단에서 구현했다면 테스트를 하러갈 수 있다.
오히려 더 간단한 버전일수가 있는데, 해당 API에 직접 접근하면 된다.
Controller 단
@GetMapping(value = "/edu/excel-download") public void eduExcelDownload(HttpServletResponse response) throws IOException { Workbook wb = new XSSFWorkbook(); Sheet sheet = wb.createSheet("교육 진행률"); Row row = null; Cell cell = null; int rowNum = 0; List<String> excelHeaderList = userAdminService.getHeaderName(EduReaderListDTO.class); List<EduReaderListDTO> excelBodyList = userReaderCustomRepository.findEduPercentageList(); List<EduContents> excelEduContents = eduContentsRepository.findAll(); // 콘텐츠 id들을 담는 배열 int[] contentsIds = new int[excelEduContents.size()]; for(int i=0; i<contentsIds.length; i++) { contentsIds[i] = excelEduContents.get(i).getId(); System.out.println("contentsId: " + contentsIds[i]); } // Header row = sheet.createRow(rowNum++); for(int i=0; i<excelHeaderList.size(); i++) { cell = row.createCell(i); cell.setCellValue(excelHeaderList.get(i)); } for(int i=0; i<excelEduContents.size(); i++) { cell = row.createCell(excelHeaderList.size() + i); cell.setCellValue(excelEduContents.get(i).getTitle()); } // Body for (int i=0; i<excelBodyList.size(); i++) { row = sheet.createRow(rowNum++); cell = row.createCell(0); cell.setCellValue(excelBodyList.get(i).getId()); cell = row.createCell(1); cell.setCellValue(excelBodyList.get(i).getUserRegion()); cell = row.createCell(2); cell.setCellValue(excelBodyList.get(i).getUserName()); cell = row.createCell(3); cell.setCellValue(excelBodyList.get(i).getUserBirth()); cell = row.createCell(4); cell.setCellValue(excelBodyList.get(i).getUserGender()); cell = row.createCell(5); cell.setCellValue(excelBodyList.get(i).getUserTel()); cell = row.createCell(6); if(excelBodyList.get(i).getEduPercentage() == null) { cell.setCellValue(0); } else { cell.setCellValue(excelBodyList.get(i).getEduPercentage()); } int[] userContentIds = new int[excelBodyList.get(i).getEduInfos().size()]; for(int n=0; n<userContentIds.length; n++) { if(excelBodyList.get(i).getEduInfos().get(n).getEduContentId() == null) { userContentIds[n] = 0; } else { userContentIds[n] = excelBodyList.get(i).getEduInfos().get(n).getEduContentId(); } } // 각 교육 콘텐츠당 퍼센테이지를 담을 배열 [0,0,0,0...,0] int[] percentages = new int[excelEduContents.size()]; // 대상자가 가지고 있는 교육 콘텐츠 id와 교육 콘텐츠 배열의 값이 일치하면 해당 퍼센테이지 배열의 idx값에 대상자 percentage로 변경 for(int j=0; j<userContentIds.length; j++) { for(int m=0; m<contentsIds.length; m++) { if(userContentIds[j] == contentsIds[m]) { percentages[m] = excelBodyList.get(i).getEduInfos().get(j).getEduEachPercentage(); } } } for(int p=0; p<percentages.length; p++){ cell = row.createCell(7+p); cell.setCellValue(percentages[p]); } } // 컨텐츠 타입과 파일명 지정 response.setContentType("ms-vnd/excel"); String fileName = "엑셀 파일 이름"; String outputFileName = new String(fileName.getBytes("KSC5601"), "8859_1"); // 엑셀 파일 이름이 한글이라면 넣어주자~ response.setHeader("Content-Disposition", "attachment;filename=" + outputFileName + ".xlsx"); // Excel File Output wb.write(response.getOutputStream()); wb.close(); }
이런식으로 코드를 짜줬다면, http://localhost:8080/edu/excel-download
포스트맨에서 쓰는 것처럼 바로 그 API를 브라우저에 넣어주면 다운로드가 된다.
잘 다운로드 된다!