본문 바로가기

자바☕

엑셀 다운로드를 위한 엑셀 생성 로직 리팩토링 : 속도 개선

728x90

https://cdaosldk.tistory.com/344

 

엑셀 파일 생성 로직 구현 : Map 활용, 클래스 단위로 응용 가능

1. 문제점 파악 기존 구글링을 통한 엑셀 다운로드 로직들을 살펴보면서 스터디 하던 도중, 전부 컨트롤러 단에서 구현해야하는 모든 로우를 작성한 다음, 반환하는 수고를 하는 케이스가 대부

cdaosldk.tistory.com


지난 구현 글에서 해당 로직을 테스트하다, 데이터 13만 개를 변환하니 속도가 진행되지 않고, 사용자의 다수 요청이 누적되어 OOM이 발생하게 되었다.

 

정답은 메서드 간 역할 분담!

 

그리고 메모리를 많이 잡아먹는 반복문 구간을 줄이고, 조건문의 실행 구간을 단순화했다

public void writeExcelSheetToWorkbook(Workbook workbook, String sheetName, Map<String, String> cellValues, int minWidth, List<Map<String, Object>> dataList) {
		Sheet sheet = workbook.createSheet(sheetName);
		createHeaderRow(sheet, cellValues);

		CellStyle integerStyle = configCellStyleNumeric(workbook, false);
		CellStyle decimalStyle = configCellStyleNumeric(workbook, true);

		for (int rowIndex = 0; rowIndex < dataList.size(); rowIndex++) {
			createDataRow(sheet, rowIndex + 1, dataList.get(rowIndex), cellValues, integerStyle, decimalStyle);
		}

		adjustColumnWidth(cellValues, minWidth, sheet);
	}

	private void createHeaderRow(Sheet sheet, Map<String, String> cellValues) {
		Row headerRow = sheet.createRow(0);
		int cellIndex = 0;
		for (String header : cellValues.values()) {
			headerRow.createCell(cellIndex++).setCellValue(header);
		}
	}

	private void createDataRow(Sheet sheet, int rowNum, Map<String, Object> dataMap, Map<String, String> cellValues, CellStyle integerStyle, CellStyle decimalStyle) {
		Row dataRow = sheet.createRow(rowNum);
		int cellIndex = 0;
		for (String key : cellValues.keySet()) {
			Cell cell = dataRow.createCell(cellIndex++);
			Object value = dataMap.get(key);
			setCellValue(cell, value, integerStyle, decimalStyle);
		}
	}

	private void setCellValue(Cell cell, Object value, CellStyle integerStyle, CellStyle decimalStyle) {
		if (value == null) {
			cell.setCellValue("");
		} else if (value instanceof String) {
			cell.setCellValue((String) value);
		} else if (value instanceof Number) {
			Number numValue = (Number) value;
			if (value instanceof Integer || value instanceof Long) {
				cell.setCellValue(numValue.longValue());
				cell.setCellStyle(integerStyle);
			} else {
				cell.setCellValue(numValue.doubleValue());
				cell.setCellStyle(decimalStyle);
			}
		} else {
			cell.setCellValue(value.toString());
		}
	}

 

속도 개선 결과 : 기존 13만개 데이터의 경우 약 1분만에 변환이 모두 완료되었다.

 

느낀 점 : 메서드의 역할을 항상 유념하고, 메서드를 설계할 때에도 컴포넌트 단위로 쪼개서 설계하는 것 같이 설계할 것.

728x90

'자바☕' 카테고리의 다른 글

엑셀 파일 생성 로직 구현 : Map 활용, 클래스 단위로 응용 가능  (2) 2024.10.21
자바 옵셔널(Optional<T>)  (0) 2022.12.11
스트림 API  (0) 2022.12.11
함수형 인터페이스와 람다 표현식  (0) 2022.12.11
Lombok  (0) 2022.12.06