POI를 이용한 대용량 엑셀 다운로드(SXSSF 방식 + sqlSessionFactory + ResultHandler + VO 활용)
|2024. 10. 18. 15:50
Controller 부분
@GetMapping("/test/testExcel")
public void testExcelList2(HttpServletRequest req, HttpServletResponse resp) throws Exception {
// 화면단에서 보내는 값을 받음
Map<String, Object> paraMap = getParam(req);
// 화면에서 받은 값을 보냄
excelTestService.testExcel(paraMap, resp);
}
Service 부분
public void testExcel(Map<String, Object> paraMap, HttpServletResponse response) {
// sqlSessionFactory 생성
SqlSession sqlSession = sqlSessionFactory.openSession();
SXSSFWorkbook wb = new SXSSFWorkbook(1000);
// 시트 생성 및 타이틀
Sheet sheet = wb.createSheet("테스트용");
CellStyle styleOfBoardFillFontRedBold14;
CellStyle styleOfBoardFontBlack11;
// 1. 폰트 설정
Font black11 = wb.createFont();
black11.setFontName("나눔고딕"); // 글씨체
black11.setFontHeight((short) (11 * 20)); // 사이즈
// 2.셀 스타일 및 폰트 설정(헤더 텍스트)
styleOfBoardFillFontRedBold14 = wb.createCellStyle();
// 정렬
styleOfBoardFillFontRedBold14.setAlignment(HorizontalAlignment.CENTER); // 가운데 정렬
styleOfBoardFillFontRedBold14.setVerticalAlignment(VerticalAlignment.CENTER); // 높이 가운데 정렬
// 배경색
styleOfBoardFillFontRedBold14.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex());
styleOfBoardFillFontRedBold14.setFillPattern(FillPatternType.SOLID_FOREGROUND);
// 테두리 선 (우,좌,위,아래)
styleOfBoardFillFontRedBold14.setBorderRight(BorderStyle.THIN);
styleOfBoardFillFontRedBold14.setBorderLeft(BorderStyle.THIN);
styleOfBoardFillFontRedBold14.setBorderTop(BorderStyle.THIN);
styleOfBoardFillFontRedBold14.setBorderBottom(BorderStyle.THIN);
// 천단위 쉼표, 금액
styleOfBoardFillFontRedBold14.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0"));
// 3.셀 스타일 및 폰트 설정(일반 텍스트)
styleOfBoardFontBlack11 = wb.createCellStyle();
// 정렬
styleOfBoardFontBlack11.setAlignment(HorizontalAlignment.CENTER); // 가운데 정렬
styleOfBoardFontBlack11.setVerticalAlignment(VerticalAlignment.CENTER); // 높이 가운데 정
// 테두리 선 (우,좌,위,아래)
styleOfBoardFontBlack11.setBorderRight(BorderStyle.THIN);
styleOfBoardFontBlack11.setBorderLeft(BorderStyle.THIN);
styleOfBoardFontBlack11.setBorderTop(BorderStyle.THIN);
styleOfBoardFontBlack11.setBorderBottom(BorderStyle.THIN);
// 천단위 쉼표, 금액
styleOfBoardFontBlack11.setDataFormat(HSSFDataFormat.getBuiltinFormat("#,##0"));
// 폰트 설정 (위 폰트 사용)
styleOfBoardFontBlack11.setFont(black11);
try {
log.debug("엑셀 시작");
StopWatch stopWatch = StopWatch.createStarted();
// paraMap으로 화면에서 받은 값을 넘김, Test(VO)를 ResultHandler로 받음
sqlSession.select("com.test.test.test.mapper.TestExcelMapper.slctTestExcel", paraMap, new ResultHandler<Test>() {
int rowCnt = 0;
Row row;
Cell cell;
@Override
public void handleResult(ResultContext<? extends Test> resultContext) {
Test testVo = resultContext.getResultObject();
// 첫 ROW에 헤드 생성
if (rowCnt == 0) {
// 헤드 row 생성
row = sheet.createRow(rowCnt++);
row.createCell(0).setCellStyle(styleOfBoardFillFontRedBold14);
row.getCell(0).setCellValue("내용1");
row.createCell(1).setCellStyle(styleOfBoardFillFontRedBold14);
row.getCell(1).setCellValue("내용2");
row.createCell(2).setCellStyle(styleOfBoardFillFontRedBold14);
row.getCell(2).setCellValue("내용3");
row.createCell(3).setCellStyle(styleOfBoardFillFontRedBold14);
row.getCell(3).setCellValue("내용4");
row.createCell(4).setCellStyle(styleOfBoardFillFontRedBold14);
// 값 row 생성
row = sheet.createRow(rowCnt++);
cell = row.createCell(0);
cell.setCellValue(testVo.getTest_name1());
cell.setCellStyle(styleOfBoardFontBlack11);
cell = row.createCell(1);
cell.setCellValue(testVo. getTest_name2());
cell.setCellStyle(styleOfBoardFontBlack11);
cell = row.createCell(2);
cell.setCellValue(testVo. getTest_name3());
cell.setCellStyle(styleOfBoardFontBlack11);
cell = row.createCell(4);
// 값이 숫자일 경우 Integer를 사용하여 변환
cell.setCellValue(Integer.parseInt(testVo. getTest_name4()));
cell.setCellStyle(styleOfBoardFontBlack11);
} else {
// 값 row 생성
row = sheet.createRow(rowCnt++);
cell = row.createCell(0);
cell.setCellValue(testVo.getTest_name1());
cell.setCellStyle(styleOfBoardFontBlack11);
cell = row.createCell(1);
cell.setCellValue(testVo. getTest_name2());
cell.setCellStyle(styleOfBoardFontBlack11);
cell = row.createCell(2);
cell.setCellValue(testVo. getTest_name3());
cell.setCellStyle(styleOfBoardFontBlack11);
cell = row.createCell(4);
// 값이 숫자일 경우 Integer를 사용하여 변환
cell.setCellValue(Integer.parseInt(testVo. getTest_name4()));
cell.setCellStyle(styleOfBoardFontBlack11);
}
}
});
// 컬럼 사이즈 지정
sheet.setColumnWidth((short) 0, (short) 7000);
sheet.setColumnWidth((short) 1, (short) 8555);
sheet.setColumnWidth((short) 2, (short) 9445);
sheet.setColumnWidth((short) 3, (short) 2450);
// 파일명
String fileName = URLEncoder.encode("테스트_엑셀", "UTF-8") + ".xlsx";
response.setHeader("Set-Cookie", "fileDownload=true; path=/");
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
wb.write(response.getOutputStream());
stopWatch.stop();
log.debug("엑셀 종료 ");
log.debug("엑셀 경과 시간 : " + stopWatch.toString());
} catch(Exception e) {
response.setHeader("Set-Cookie", "fileDownload=false; path=/");
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
response.setHeader("Content-Type","text/html; charset=utf-8");
OutputStream out = null;
try {
out = response.getOutputStream();
byte[] data = new String("fail..").getBytes();
out.write(data, 0, data.length);
} catch(Exception ignore) {
ignore.printStackTrace();
} finally {
if(out != null) try { out.close(); } catch(Exception ignore) {}
}
} finally {
sqlSession.close();
// 디스크 적었던 임시파일을 제거합니다.
wb.dispose();
try { wb.close(); } catch(Exception ignore) {}
}
}
Mapper 부분
public void slctTestListExcel2(ResultHandler<Test> resultHandler);
xml 부분 - fetchSize를 사용하여 쿼리 속도를 증가시킴
<select id="slctTestExcel" resultType="com.test.test.test.vo.Test" parameterType="hashmap" fetchSize="10000">
SELECT
test_name1
, test_name2
, test_name3
, test_name4
FROM test_data a
</select>
VO설정
@Setter
@Getter
@AllArgsConstructor
public class Test {
private String test_name1;
private String test_name2;
private String test_name3;
private String test_name4;
}
'개발자 > Java' 카테고리의 다른 글
| [Java] Web에서 서버에 저장된 PDF 보여주기 OR PDF 다운로드 (1) | 2025.01.16 |
|---|---|
| [Java] Jaspersoft Studio VO를 활용한 List 출력 (0) | 2024.12.13 |
| [Java] 숫자, 금액을 한글로 변환 (0) | 2024.06.26 |
| [Java] Collections.frequency() 사용법 (0) | 2024.06.13 |
| [Java] Jaspersoft Studio 출력 방식(PDF, 바로 프린트) (0) | 2024.06.12 |