to read / write Excel file using annotations and reflections
Find a file
2026-06-29 20:55:50 +09:00
.idea Refactor XL engine: improve ExcelWriter API, update dependencies, and enhance documentation 2026-06-29 13:57:08 +09:00
.vscode Initialize XL project with basic module structure, annotations, utilities, core engine, and build-logic 2026-06-29 13:08:56 +09:00
annotations Initialize XL project with basic module structure, annotations, utilities, core engine, and build-logic 2026-06-29 13:08:56 +09:00
build-logic Initialize XL project with basic module structure, annotations, utilities, core engine, and build-logic 2026-06-29 13:08:56 +09:00
engine Exclude log4j-core from POI dependencies and add log4j-to-slf4j bridge for improved logging consistency 2026-06-29 20:55:50 +09:00
gradle Exclude log4j-core from POI dependencies and add log4j-to-slf4j bridge for improved logging consistency 2026-06-29 20:55:50 +09:00
util Exclude log4j-core from POI dependencies and add log4j-to-slf4j bridge for improved logging consistency 2026-06-29 20:55:50 +09:00
.gitattributes Initialize XL project with basic module structure, annotations, utilities, core engine, and build-logic 2026-06-29 13:08:56 +09:00
.gitignore Initialize XL project with basic module structure, annotations, utilities, core engine, and build-logic 2026-06-29 13:08:56 +09:00
AGENTS.md Initialize XL project with basic module structure, annotations, utilities, core engine, and build-logic 2026-06-29 13:08:56 +09:00
build.gradle.kts Refactor ExcelWriter API: rename toFile and toStream to export, update references, and bump version to 1.0.2 2026-06-29 14:14:50 +09:00
gradle.properties Initialize XL project with basic module structure, annotations, utilities, core engine, and build-logic 2026-06-29 13:08:56 +09:00
gradlew Initialize XL project with basic module structure, annotations, utilities, core engine, and build-logic 2026-06-29 13:08:56 +09:00
gradlew.bat Initialize XL project with basic module structure, annotations, utilities, core engine, and build-logic 2026-06-29 13:08:56 +09:00
LICENSE Initialize XL project with basic module structure, annotations, utilities, core engine, and build-logic 2026-06-29 13:08:56 +09:00
lombok.config Initialize XL project with basic module structure, annotations, utilities, core engine, and build-logic 2026-06-29 13:08:56 +09:00
README.md Refactor ExcelWriter API: rename toFile and toStream to export, update references, and bump version to 1.0.2 2026-06-29 14:14:50 +09:00
REQUIREMENTS.md Refactor XL engine: improve ExcelWriter API, update dependencies, and enhance documentation 2026-06-29 13:57:08 +09:00
settings.gradle.kts Initialize XL project with basic module structure, annotations, utilities, core engine, and build-logic 2026-06-29 13:08:56 +09:00

XL to read / write Excel

Apache POI의 복잡한 로우 레벨 코드를 추상화하여, 자바 객체(POJO)와 엑셀 시트 간의 데이터 읽기/쓰기를 직관적이고 빠르게 처리하는 경량 라이브러리.

repositories {
    maven {
        name = "Elex Repository"
        url = "https://artifacts.elex-project.com/repository/maven/"
    }
}
dependencies {
    implementation("com.elex_project:xl-annotations:1.0.0")
    implementation("com.elex_project:xl:1.0.0")
    
    implementation("org.apache.poi:poi:5.5.1")
    implementation("org.apache.poi:poi-ooxml:5.5.1")
}

Usage

@NoArgsConstructor
@ExcelSheet(name = "회원 매출 현황")
public class MemberSalesDto {

    @ExcelColumn(header = "회원 번호", order = 1)
    private Long memberId;

    @ExcelColumn(header = "고객명", order = 2)
    private String name;

    // 대용량 숫자에 콤마(,) 포맷팅 적용
    @ExcelColumn(header = "당월 매출", order = 3, format = "#,##0")
    private long monthlySales;

    // 날짜 포맷팅 적용
    @ExcelColumn(header = "최종 구매일", order = 4, format = "yyyy-MM-dd")
    private LocalDate lastPurchaseDate;
}
List<MemberSalesDto> list;
ExcelWriter.of(list)
        .decorator(DefaultTheme.EMERALD_GREEN)
        .streaming(true) // 대용량 OOM 방지 스리트밍 켜기
        .export(new File("sales_report.xlsx"));
ExcelReadResult<MemberSalesDto> result = ExcelReader.of(MemberSalesDto.class)
        .fromFile(excelFile);
@PostMapping("/upload/members")
public ResponseEntity<?> uploadMemberExcel(@RequestParam("file") MultipartFile file) {
	// 1. 파일 빈 값 및 확장자 검증
	if (file.isEmpty()) {
		return ResponseEntity.badRequest().body("업로드된 파일이 비어 있습니다.");
	}

	String contentType = file.getContentType();
	if (contentType == null || (!contentType.contains("sheet") && !contentType.contains("excel"))) {
		return ResponseEntity.badRequest().body("올바른 엑셀 파일(.xlsx, .xls) 형식이 아닙니다.");
	}

	try (InputStream is = file.getInputStream()) {
		// 2. xl 라이브러리의 ExcelReader를 활용해 MultipartStream을 즉시 파싱
		ExcelReadResult<MemberSalesDto> result = ExcelReader.of(MemberSalesDto.class)
				.fromStream(is);
	}
	if (result.hasErrors()) {
	}
}

Low-level RAW Utility Classes

dependencies {
    implementation("com.elex_project:xl-raw:1.0.0")
    
    implementation("org.apache.poi:poi:5.5.1")
    implementation("org.apache.poi:poi-ooxml:5.5.1")
}

Usage

// 워크북 생성
Workbook workbook = createWorkbook();

// 시트 생성
Sheet sheet = getSheet(workbook, "Test 1");

// 행 가져오기
Row row = getRow(sheet, 0);

// 셀(0, 0) 가져오기, 셀에 문자열 쓰기
Cell cell = getCell(row, 0);
write(cell, "Hello");

// 셀(0, 1) 가져오기, 셀에 날짜 쓰기
cell = getCell(row, 1);
write(cell, LocalDate.now(), workbook);

// 셀(3, 3) 가져오기, 셀에 숫자 쓰기
cell = getCell(sheet, 3, 3);
write(cell, 123.45);
Font font = new FontBuilder(workbook)
        .height((short) 16)
        .color(IndexedColors.RED)
        .bold()
        .get();
CellStyle cellStyle = new CellStyleBuilder(workbook)
        .align(HorizontalAlignment.CENTER)
        .background(IndexedColors.YELLOW)
        .font(font)
        .get();
// 셀에 스타일 적용
cell.setCellStyle(cellStyle);

// 셀의 높이 설정
setHeight(cell, 20);

// 셀 합치기
mergeCells(sheet, 1, 2, 1, 1);

// 셀의 너비 자동 조정
autoWidth(sheet);

// 워크북을 파일로 저장
try (FileOutputStream fileOutputStream = new FileOutputStream(outFile1)) {
    writeOut(workbook, fileOutputStream);
    workbook.close();
}