1. 의존성 추가
Apache POI
- Microsoft Office 파일(Word, Excel, PowerPoint)을 JAVA로 읽고 쓰기 위한 라이브러리이다.
- Excel에서는 .xls, .xlsx 파일 형식 모두 지원한다.
implementation 'org.apache.poi:poi-ooxml:5.2.2'
implementation 'org.apache.poi:poi:5.2.2'
2. Apache POI 구현체
Apache POI의 구현체
- HSSF (Horrible Spreadsheet Format): Excel 97-2003(.xls) 파일 형식을 지원
- XSSF (XML Spreadsheet Format): Excel 2007 이상(.xlsx) 파일 형식을 지원
- SXSSF (Streaming XML Spreadsheet Format): 대용량 .xlsx 파일을 처리하기 위해 스트리밍 방식으로 지원
XSSF는 메모리 사용량이 높아 대용량 데이터를 처리할 때 성능 문제가 발생할 수 있다.
따라서 대용량 데이터를 처리하기 위해 설계된 구현체가 SXSSF이다.
SXSSF는 메모리 사용량을 최소화하기 위해 내부적으로 필요한 데이터만 메모리에 유지하고, 나머지는 디스크에 flush 하여 저장한다.
또한 내부적으로 XSSF를 사용하여, XSSF의 대부분의 기능을 사용할 수 있다.
(차트, 조건부 서식과 같은 일부 기능은 제한)
기본 표 템플릿에 맞추어, 단순히 셀에 데이터 값을 기입하는 기능을 목표로 하기에
메모리를 효율적으로 사용하는 SXSSF에 초점에 맞춰 정리해보자!!
3. SXSSFWorkbook
1) 초기 엑셀 파일 생성하여 작업
템플릿 없이 초기 엑셀 파일로 작업을 할 경우는 단순하다!
바로 SXSSFWorkbook 객체를 생성하여 데이터를 추가한 후, response 출력 스트림에 넣어주면 된다.
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import java.io.IOException;
public class ExcelDownloadService {
public void dataExcelDownload(DataDto dto, HttpServletResponse response) {
// 1) .xlsx 파일 형식의 Workbook 생성
SXSSFWorkbook workbook = new SXSSFWorkbook();
// 2) 새로운 시트 생성
Sheet sheet = workbook.createSheet("첫 번째 시트");
// 3) 첫 번째 row 생성 (1행)
Row headerRow = sheet.createRow(0);
// 4) 첫 번째 row의 첫 번째 column에 해당하는 셀 생성 (1행 1열)
Cell cell = headerRow.createCell(0);
cell.setCellValue("Header1");
// 5) 응답 헤더 설정
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=\"output.xlsx\"");
// 6) 파일 저장
try {
workbook.write(response.getOutputStream()); // workbook 내용을 HTTP response 출력 스트림에 기록
workbook.close(); // 메모리 자원 해제
} catch (IOException e) {
e.printStackTrace();
}
}
}
2) 기존 템플릿 바탕으로 작업
기존 템플릿을 활용하는 경우는 살짝 번거롭다.. (그래도 템플릿 활용하는 것이 좋지!)
먼저 FileInputStream으로 템플릿 파일을 읽고, XSSFWorkbook 객체를 생성해야 한다.
그리고 XSSFWorkbook 객체로 SXSSFWorkbook 객체를 만들어주고, 1번과 똑같이 작업을 하면 된다.
public class ExcelDownloadService {
public void dataExcelDownloadWithTemplate(DataDto dto, HttpServletResponse response) {
// 템플릿 파일 경로
String templatePath = "/path/to/template.xlsx";
// XSSFWorkbook 생성 후, SXSSFWorkbook 변환
try (InputStream inputStream = new FileInputStream(templatePath);
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(inputStream)){
SXSSFWorkbook workbook = new SXSSFWorkbook(xssfWorkbook);
// 첫 번째 시트 접근
Sheet sheet = workbook.getSheetAt(0);
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setHeader("Content-Disposition", "attachment; filename=\"output.xlsx\"");
workbook.write(response.getOutputStream());
workbook.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. 관련 함수
1) 셀 스타일링
모든 셀에 적용할 기본적인 셀 스타일링을 정의하기 위해 별도로 createCellStyle 함수를 만들었다.
여기에서 workbook.createCellStyle()로 초기 셀 스타일을 생성하고, 셀의 테두리와 가운데 정렬을 기본으로 정의해두었다.
private CellStyle createCellStyle(SXSSFWorkbook workbook) {
// 셀 스타일 생성
CellStyle cellStyle = workbook.createCellStyle();
// 테두리 설정
cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
// 가운데 정렬 설정
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
return cellStyle;
}
추가로, 셀의 배경색을 입히고 싶을 때는 기본 셀 스타일과 RGB 색상을 파라미터로 넣어주면 된다.
private CellStyle printCellColor(CellStyle cellStyle, Integer R, Integer G, Integer B) {
// 셀 색상 설정
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
XSSFColor color = new XSSFColor(new java.awt.Color(R, G, B), new DefaultIndexedColorMap());
cellStyle.setFillForegroundColor(color);
return cellStyle;
}
다음과 같이 사용할 수 있다.
Row row = sheet.createRow(0); // 1행
Cell cell = row.createCell(0); // 1행 1열
CellStyle cellStyle = createCellStyle(workbook); // 기본 셀 스타일
CellStyle colorStyle = printCellColor(cellStyle, 255, 255, 255); // 셀 배경색 스타일
cell.setCellStyle(cellStyle);
cell.setCellStyle(colorStyle);
2) 셀 병합
셀 병합을 하는데 있어서, 아래의 CellRangeAddress 객체를 사용한다.
(firstRow, firstCol) ~ (lastRow, lastCol) 구역의 셀을 병합하는 기능을 한다.
public CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) {
super(firstRow, lastRow, firstCol, lastCol);
if (lastRow < firstRow || lastCol < firstCol) {
throw new IllegalArgumentException("Invalid cell range, having lastRow < firstRow || lastCol < firstCol, " +
"had rows " + lastRow + " >= " + firstRow + " or cells " + lastCol + " >= " + firstCol);
}
}
다음과 같이 사용할 수 있다.
private void createMergedCell(Sheet sheet) {
Row row = sheet.createRow(0); // 1행
Cell cell = row.createCell(0); // 1행 1열
// 셀 병합
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 5));
cell.setCellValue("value"); // 병합한 셀에 값 기입
}
'Spring > 끄적끄적' 카테고리의 다른 글
@JoinColumn(name =" ", referecedColumnName= " ") (0) | 2024.07.15 |
---|---|
HttpURLConnection, RestTemplate, WebClient 비교 (0) | 2024.07.11 |
WebClient 네이버 지도 비동기 API 호출하기 (2) (1) | 2024.05.20 |
WebClient 네이버 지도 비동기 API 호출하기 (1) (0) | 2024.05.20 |