STUDY
JAVA | Apache POI를 이용한 Excel 파일 읽기, 수정, 다운로드
devvnn
2023. 2. 17. 11:11
사용 경위
- 가지고 있는 예시 엑셀 파일에 ibatis를 통해 DB에서 HashMap 형태로 받아온 데이터를 다시 그려준 뒤, 사용자가 다운로드 받을 수 있게 파일 읽기 - 수정 - 다운로드를 한 번에 할 수 있는 기능을 만들어야 함
- 시트가 100개 이상이고, 각 시트에 테이블 하나가 들어가는 구조이며 각 시트에 다른 SP를 실행한 결과값이 들어감
- 그래서 시트 정보가 들어있는 배열을 통해 반복문을 돌리고, 그 안에 테이블에 그려줄 결과를 그려줄 반복문을 한번 더 돌림
- HashMap 및 POI 라이브러리를 제대로 처음부터 끝까지 다뤄본 건 처음이라 많은 공부가 됐고, 기억하기 위해서 기록하려고 함
소스
- POI 라이브러리를 사용하기 위해서는 의존성 주입이 선행되어야 함
Row row = null; // 행
Cell cell = null; // 셀
int rowNo = 0; // 행넘버
int colNo = 0; // 열넘버
// 프로젝트(소스) 내부에 파일이 존재하고, 그 파일을 수정하여 새로운 엑셀 파일 생성
// 즉 파일을 읽어와서(양식) 새로 쓴 뒤 다운받을 수 있게 함
String path = "/file/";
String path2 = path.replace("/", File.separator) + "엑셀파일명.xlsx";
File file = new File(String.valueOf(request.getSession().getServletContext().getRealPath("/")) + path2);
// 엑셀 양식 파일 읽어오기
FileInputStream f = new FileInputStream(file);
// 워크북 생성
// HSSFWorkbook : MS Excel 97 ~ 2003 버전까지 지원(파일 확장자 .xls)
// XSSFWorkbook : MS Excel 2007 이상 버전부터 지원(파일 확장자 .xlsx)
// SXSSFWorkbook : XSSFWorkbook보다 대용량 파일 처리에 유리하나, 엑셀 파일 읽기는 불가능하고 쓰기만 가능
Workbook wb = new XSSFWorkbook(f);
// 스타일 및 폰트 설정
// 스타일을 생성한 뒤 주입시키는 방식
bodyCellStyle = wb.createCellStyle();
Font Font = wb.createFont();
Font.setFontName("맑은 고딕");// 폰트명
Font.setFontHeightInPoints((short)8);// 크기
bodyCellStyle.setFont(Font);
bodyCellStyle.setAlignment(HorizontalAlignment.CENTER); // 가로가운데정렬
bodyCellStyle.setVerticalAlignment(VerticalAlignment.CENTER); // 세로가운데정렬
// 배경색 설정 방법 1 - 색상표에 있는 컬러로 지정
bodyCellStyle.setFillForegroundColor(IndexedColors.LIGHT_YELLOW.getIndex());// LIGHT_YELLOW 컬러로 색상채우기
bodyCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 색상채울 때 setFillForegroundColor와 세트
// 배경색 설정 방법 2 - RGB로 지정
XSSFCellStyle numberCellStyle = (XSSFCellStyle) wb.createCellStyle();
numberCellStyle.setFillForegroundColor(new XSSFColor(new java.awt.Color(220, 220, 220) ));
numberCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
// 숫자형 포맷 설정 방법 1
DataFormat format = wb.createDataFormat();
numberCellStyle.setDataFormat(format.getFormat("#,##0")); // 천단위마다 콤마
numberCellStyle.setDataFormat(format.getFormat("_(* #,##0_);_(* (#,##0);_(* \"-\"?_);_(@_)")); // 셀 서식-사용자지정, 천단위마다 콤마/값이 0이면 -으로 치환
// 숫자형 포맷 설정 방법 2
numberCellStyle.setDataFormat((short)0x29); // 셀 서식-사용자지정, 0x29는 _-* #,##0_-;-* #,##0_-;_-* "-"_-;_-@_- 를 뜻함
// 텍스트가 너무 긴 경우 Excel에서 셀 크기를 자동으로 조정하여 크기에 맞게 축소 (셀서식-맞춤-셀에 맞춤)
numberCellStyle.setShrinkToFit(true);
// 시트 번호 설정
Sheet sheet = wb.getSheetAt((Integer)(i));
// 수정할 행넘버 설정
row = sheet.getRow((Integer) rowNo++); // 빈칸이 아닌 셀에 설정
row = sheet.createRow((Integer) rowNo++); // 빈칸인 셀에 설정, 값이 들어가있지 않은 곳에 getRow를 실행하면 NPE 에러
// 수정할 셀넘버 설정
cell = row.createCell((Integer) colNo++);
// for문 돌면서 body 데이터 넣어주기
for(int i = 0; i < arr.length; i++){
cell.setCellValue(arr[i]); // arr[i] = 들어갈 값
cell.setCellStyle(bodyCellStyle); // 미리 만들어둔 스타일 세팅
}
// 컨텐츠 타입과 파일명 지정
response.setHeader("Content-Type", "ms-vnd/excel; charset=EUC-KR");
response.setHeader("Set-Cookie", "fileDownload=true; path=/");
response.setHeader("Content-Disposition", "attachment;filename=" + FileHelper.GetDisposition(request, title) + ".xlsx");
// 파일 내보내기
wb.write(response.getOutputStream());
wb.close();
* 도움받은 곳