• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

hee9841 / excel-module / #38

25 Apr 2025 09:07AM UTC coverage: 82.791%. Remained the same
#38

push

github

web-flow
Release 0.0.1 (#58)

* Docs: 초기 배포를 위한 docs 추가 (#21)

* Docs: README 추가

* Chore: gitignore에 maven pushing에 사용할 설정 파일 추가

* Deploy: Coveralls 추가, CI 추가 (#22)

* Release 0.0.1

* Deploy: 배포시 Readme 버전 설정 추가 (#25)

* Deploy: 베포시 readme 버전 설정

* Fix: 테스트로 추가했던 dev 브런치 삭제

* Docs: javadocs 관련 의존성 추가 및 배포된 maven repository url 추가 (#30)

* Docs: javaDocs 만들기 위한 추가 의존성 추가

* Docs: Maven Central url README에 추가

* Fix: slf4j-api 의존성의 implementation으로 변경 (#33)

* Feat: 로그 info 메세지 변경 (#34)

* Feat: 로깅 메세지 변경

* Feat: 로그 info 메세지 변경(dto 클래스명 SimpleName에서 패키지 포함으로 변경)

* Feat: Excel, ExcelColumn 어노테이션 정합성 예외 처리 (#35)

* Feat: SystemValues 클레스에 ExcelColumn에 허용되는 타입들 추가

* Feat: Excel, ExcelColumn 어노테이션 관련 적합성에 대한 예외 처리 추가

* Fix: ExcelColumnAnnotationProcessor에 AutoService import

* Fix: Supported source version에 대한 경고 제거 (#36)

* Fix: AutoService 제거

- 의존성 삭제
- 프로세서에 어노테이션 제거

* Fix: 어노테이션 프로세서 SourceVersion을 latestSupported로 변경

* Fix: poi 의존성을 implementation에서 api로 변경 (#38)

* Fix: 에러 메세지 수정(STY_CU_003_B, STG_CT_001_B,STG_ID_002_B 테스트 사항) (#46)

* Fix: 에러 메세지 수정(STY_CU_003_B, STG_CT_001_B,STG_ID_002_B 테스트 사항)

* Style: comment, 및 포멧 수정

* Fix: compile 옵션 변경, toolchain java 버전 변경 (#47)

* Chore: gradle 버전 변경 gradle-8.5 -> gradle-8.10

* Chore: java compile source, target 8 에서 release 8로 변경

- toolchain을 23으로 변경

* Refactor: ExcelExporter의 validate 메서드 추가(data size, sheet Strategy에 따른) (#48)

- validate 오버라이딩으로 생성자의 setSheetStrategy 메서드호출과 initialize 호출 시점 변경,

* Refactor: VerticalAlignment의 default 값을 CENTER로 설정 (#49)

* Refactor: poi 라이브러리의 클래스명과 겹치는 클래스명 변경 (#50)

* Rename: IndexedColor 관련 클래스명 rename

- IndexedColors.java ->  ColorPalette.java
- IndexedExcelColor.java -> PaletteExcelColor.java

* Rename: CellType.java -> ColumnDataType.java으로 클래스명 변경

* Rename: Alignment 관련 Enum 클래스 'Excel' 접두사 추가

* Rename: BorderStyle.java -> ExcelBorderStyle.java로 변경

* Refactor: Excel, ExcelColumn 어노테이션 프로세서 추가 구현 (#52)

* Refactor: ExcelAnnotationProcessor와 ExcelColumnAn... (continued)

105 of 168 new or added lines in 16 files covered. (62.5%)

29 existing lines in 7 files now uncovered.

534 of 645 relevant lines covered (82.79%)

0.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.36
/src/main/java/io/github/hee9841/excel/core/SXSSFExcelFile.java
1
package io.github.hee9841.excel.core;
2

3
import io.github.hee9841.excel.exception.ExcelException;
4
import io.github.hee9841.excel.meta.ColumnInfo;
5
import io.github.hee9841.excel.meta.ColumnInfoMapper;
6
import java.io.IOException;
7
import java.io.OutputStream;
8
import java.lang.reflect.Field;
9
import java.util.List;
10
import java.util.Map;
11
import org.apache.commons.lang3.reflect.FieldUtils;
12
import org.apache.poi.ss.SpreadsheetVersion;
13
import org.apache.poi.ss.usermodel.Cell;
14
import org.apache.poi.ss.usermodel.Row;
15
import org.apache.poi.ss.usermodel.Sheet;
16
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
17
import org.slf4j.Logger;
18
import org.slf4j.LoggerFactory;
19

20
/**
21
 * Abstract base class for Excel file operations using Apache POI's SXSSF (Streaming XML Spreadsheet
22
 * Format).
23
 * This class provides the core functionality for handling Excel files with streaming support for
24
 * large datasets.
25
 *
26
 * <p>Key features:</p>
27
 * <ul>
28
 *     <li>Uses SXSSFWorkbook for memory-efficient handling of large Excel files</li>
29
 *     <li>Supports Excel 2007+ format (XLSX)</li>
30
 *     <li>Provides column mapping and header generation</li>
31
 *     <li>Handles cell styling and data type conversion</li>
32
 * </ul>
33
 *
34
 * <p>This class implements the core functionality while leaving sheet management strategies
35
 * to be implemented by concrete subclasses.</p>
36
 *
37
 * @param <T> The type of data to be handled in the Excel file
38
 */
39
public abstract class SXSSFExcelFile<T> implements ExcelFile<T> {
40

41
    protected static final Logger logger = LoggerFactory.getLogger(SXSSFExcelFile.class);
1✔
42

43
    protected static final SpreadsheetVersion supplyExcelVersion = SpreadsheetVersion.EXCEL2007;
1✔
44

45
    protected SXSSFWorkbook workbook;
46
    protected Map<Integer, ColumnInfo> columnsMappingInfo;
47
    protected Sheet sheet;
48

49
    protected String dtoTypeName;
50

51
    /**
52
     * Constructs a new SXSSFExcelFile with a new SXSSFWorkbook instance.
53
     */
54
    protected SXSSFExcelFile() {
1✔
55
        this.workbook = new SXSSFWorkbook();
1✔
56
    }
1✔
57

58
    /**
59
     * Initializes the Excel file with the specified type and data.
60
     * This method performs validation and sets up column mapping information.
61
     *
62
     * @param type The class type of the data to be exported
63
     * @param data The list of data objects to be exported
64
     */
65
    protected void initialize(Class<?> type, List<T> data) {
66
        this.dtoTypeName = type.getName();
1✔
67
        logger.info("Initializing Excel file for DTO: {}.java.", dtoTypeName);
1✔
68

69
        validate(type, data);
1✔
70

71
        logger.debug("Mapping DTO to Excel data - DTO class({}).", dtoTypeName);
1✔
72
        //Map DTO to Excel data
73
        this.columnsMappingInfo = ColumnInfoMapper.of(type, workbook).map();
1✔
74
    }
1✔
75

76
    /**
77
     * Validates the provided data and type.
78
     * This method can be overridden by subclasses to add custom validation logic.
79
     *
80
     * @param type The class of the data type
81
     * @param data The list of data objects to be exported
82
     */
83
    protected void validate(Class<?> type, List<T> data) {
UNCOV
84
    }
×
85

86
    /**
87
     * Creates the Excel file with the provided data.
88
     * This method must be implemented by subclasses to define their specific sheet management
89
     * strategy.
90
     *
91
     * @param data The list of data objects to be exported
92
     */
93
    protected abstract void createExcelFile(List<T> data);
94

95
    /**
96
     * Creates headers for a new sheet using the column mapping information.
97
     *
98
     * @param newSheet      The sheet to add headers to
99
     * @param startRowIndex The row index where headers should start
100
     */
101
    protected void createHeaderWithNewSheet(Sheet newSheet, Integer startRowIndex) {
102
        this.sheet = newSheet;
1✔
103
        Row row = sheet.createRow(startRowIndex);
1✔
104
        for (Integer colIndex : columnsMappingInfo.keySet()) {
1✔
105
            ColumnInfo columnMappingInfo = columnsMappingInfo.get(colIndex);
1✔
106
            Cell cell = row.createCell(colIndex);
1✔
107
            cell.setCellValue(columnMappingInfo.getHeaderName());
1✔
108
            cell.setCellStyle(columnMappingInfo.getHeaderStyle());
1✔
109
        }
1✔
110
    }
1✔
111

112
    /**
113
     * Creates a row in the Excel sheet for the given data object.
114
     * This method handles field access and cell value setting based on column mapping information.
115
     *
116
     * @param data     The data object to create a row for
117
     * @param rowIndex The index of the row to create
118
     * @throws ExcelException if field access fails
119
     */
120
    protected void createBody(Object data, int rowIndex) {
121
        logger.debug("Add rows data - row:{}.", rowIndex);
1✔
122
        Row row = sheet.createRow(rowIndex);
1✔
123
        for (Integer colIndex : columnsMappingInfo.keySet()) {
1✔
124
            ColumnInfo columnInfo = columnsMappingInfo.get(colIndex);
1✔
125
            try {
126
                Field field = FieldUtils.getField(data.getClass(), columnInfo.getFieldName(), true);
1✔
127
                Cell cell = row.createCell(colIndex);
1✔
128
                //Set cell value by cell type
129
                columnInfo.getColumnType().setCellValueByCellType(cell, field.get(data));
1✔
130
                //Set cell style
131
                cell.setCellStyle(columnInfo.getBodyStyle());
1✔
UNCOV
132
            } catch (IllegalAccessException e) {
×
UNCOV
133
                throw new ExcelException(
×
UNCOV
134
                    String.format("Failed to create body(column:%d, row:%d) : "
×
135
                            + "Access to field %s failed.",
136
                        colIndex, rowIndex, columnInfo.getFieldName()), e);
×
137
            }
1✔
138
        }
1✔
139
    }
1✔
140

141
    /**
142
     * Writes the Excel file content to the specified output stream.
143
     * This method ensures proper resource cleanup using try-with-resources.
144
     *
145
     * @param stream The output stream to write the Excel file to
146
     * @throws IOException if an I/O error occurs during writing
147
     */
148
    @Override
149
    public void write(OutputStream stream) throws IOException {
150
        if (stream == null) {
1✔
NEW
151
            throw new ExcelException("Output stream is null.");
×
152
        }
153
        logger.info("Start to write Excel file for DTO class({}.java).", dtoTypeName);
1✔
154

155
        try (SXSSFWorkbook autoCloseableWb = this.workbook;
1✔
156
            OutputStream autoCloseableStream = stream) {
1✔
157
            autoCloseableWb.write(autoCloseableStream);
1✔
158
            logger.info("Successfully wrote Excel file for DTO class({}.java).", dtoTypeName);
1✔
159
        }
160
    }
1✔
161

162
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc