Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '23'
java-version: '21'

- name: Grant execute permission for Gradle
run: chmod +x gradlew
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/maven-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
- name: Set up JDK 11
uses: actions/setup-java@v4
with:
java-version: '23'
java-version: '21'
distribution: 'temurin'
cache: 'gradle'

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ plugins {
}

group = 'io.github.hee9841.excel'
version = '0.0.2'
version = '0.0.3'

repositories {
mavenCentral()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io.github.hee9841.excel.strategy.SheetStrategy;
import java.text.MessageFormat;
import java.util.List;
import org.apache.poi.ss.usermodel.Sheet;

/**
* DefaultExcelExporter is a concrete implementation of {@link SXSSFExporter} that provides functionality
Expand Down Expand Up @@ -69,7 +70,7 @@ public class DefaultExcelExporter<T> extends SXSSFExporter<T> {
setSheetStrategy(sheetStrategy);

this.initialize(type, data);
this.createExcelFile(data);
this.createExcel(data);
}


Expand All @@ -85,6 +86,22 @@ public static <T> DefaultExcelExporterBuilder<T> builder(Class<T> type, List<T>
return new DefaultExcelExporterBuilder<>(type, data, supplyExcelVersion.getMaxRows());
}

/**
* Sets the sheet strategy for this exporter.
*
* <p>This method also configures the workbook's Zip64 mode based on the selected strategy.</p>
*
* @param strategy The sheet strategy to use (ONE_SHEET or MULTI_SHEET)-
*/
private void setSheetStrategy(SheetStrategy strategy) {

this.sheetStrategy = strategy;
workbook.setZip64Mode(sheetStrategy.getZip64Mode());

logger.debug("Set sheet strategy and Zip64Mode - strategy: {}, Zip64Mode: {}.",
strategy.name(), sheetStrategy.getZip64Mode().name());
}


/**
* Validates the data size against the maximum rows per sheet limit.
Expand All @@ -107,7 +124,7 @@ protected void validate(Class<?> type, List<T> data) {
}

/**
* Creates the Excel file with the provided data.
* Creates the Excel(workBook) with the provided data.
*
* <p>This method handles the creation of sheets and rows based on the data:</p>
* <ul>
Expand All @@ -118,17 +135,19 @@ protected void validate(Class<?> type, List<T> data) {
* @param data The list of data objects to be exported
*/
@Override
protected void createExcelFile(List<T> data) {
protected void createExcel(List<T> data) {
// 1. If data is empty, create createHeader only.
if (data.isEmpty()) {
createNewSheetWithHeader();
Sheet newSheet = createNewSheet();
createHeader(newSheet, ROW_START_INDEX);
logger.warn("Empty data provided - Excel file will be created with headers only.");
return;
}

//2. Add rows
createNewSheetWithHeader();
addRows(data);
Sheet newSheet = createNewSheet();
createHeader(newSheet, ROW_START_INDEX);
addRows(newSheet, data);
}

/**
Expand All @@ -144,10 +163,10 @@ protected void createExcelFile(List<T> data) {
* @throws ExcelException if ONE_SHEET strategy is used and data exceeds max rows limit
*/
@Override
public void addRows(List<T> data) {
public void addRows(Sheet sheet, List<T> data) {
int leftDataSize = data.size();
for (Object renderedData : data) {
createBody(renderedData, currentRowIndex++);
createBody(sheet, renderedData, currentRowIndex++);
leftDataSize--;
if (currentRowIndex == maxRowsPerSheet && leftDataSize > 0) {
//If one sheet strategy, throw exception
Expand All @@ -158,47 +177,46 @@ public void addRows(List<T> data) {
}

//If multi sheet strategy, create new sheet
createNewSheetWithHeader();
currentRowIndex = ROW_START_INDEX;
sheet = createNewSheet();
createHeader(sheet, ROW_START_INDEX);
}
}
}

/**
* Sets the sheet strategy for this exporter.
* Override createHeader Method to add currentRowIndex.
*
* <p>This method also configures the workbook's Zip64 mode based on the selected strategy.</p>
*
* @param strategy The sheet strategy to use (ONE_SHEET or MULTI_SHEET)-
* @param sheet The sheet to add headers to
* @param headerRowIndex The headers row index
*/
private void setSheetStrategy(SheetStrategy strategy) {

this.sheetStrategy = strategy;
workbook.setZip64Mode(sheetStrategy.getZip64Mode());

logger.debug("Set sheet strategy and Zip64Mode - strategy: {}, Zip64Mode: {}.",
strategy.name(), sheetStrategy.getZip64Mode().name());
@Override
protected void createHeader(Sheet sheet, Integer headerRowIndex) {
super.createHeader(sheet, headerRowIndex);
currentRowIndex++;
}


/**
* Creates a new sheet with headers.
*
* <p>This method resets the current row index, creates a new sheet, and adds headers to it.
* If a sheet name is provided, it will be used as a base name with an index(index starts from
* 0) suffix.</p>
*/
private void createNewSheetWithHeader() {
currentRowIndex = ROW_START_INDEX;

private Sheet createNewSheet() {
//If sheet name is provided, create sheet with sheet name + idx
if (sheetName != null) {
sheet = workbook.createSheet(String.format("%s%d", sheetName, currentSheetIndex++));
} else {
sheet = workbook.createSheet();
}
final String finalSheetName = (sheetName != null)
? String.format("%s%d", sheetName, currentSheetIndex++)
: null;

Sheet sheet = (finalSheetName != null)
? workbook.createSheet(finalSheetName)
: workbook.createSheet();

logger.debug("Create new Sheet : {}.", sheet.getSheetName());

createHeaderWithNewSheet(sheet, ROW_START_INDEX);
currentRowIndex++;
return sheet;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import org.apache.poi.ss.usermodel.Sheet;

/**
* Core interface for Excel file operations in the library.
Expand Down Expand Up @@ -31,5 +32,5 @@ public interface ExcelExporter<T> {
*
* @param data The list of data objects to be added as rows
*/
void addRows(List<T> data);
void addRows(Sheet sheet, List<T> data);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package io.github.hee9841.excel.core.exporter;

import io.github.hee9841.excel.exception.ExcelException;
import io.github.hee9841.excel.core.meta.ColumnInfo;
import io.github.hee9841.excel.core.meta.ColumnInfoMapper;
import io.github.hee9841.excel.exception.ExcelException;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
Expand Down Expand Up @@ -44,7 +44,6 @@ public abstract class SXSSFExporter<T> implements ExcelExporter<T> {

protected SXSSFWorkbook workbook;
protected Map<Integer, ColumnInfo> columnsMappingInfo;
protected Sheet sheet;

protected String dtoTypeName;

Expand Down Expand Up @@ -73,34 +72,15 @@ protected void initialize(Class<?> type, List<T> data) {
this.columnsMappingInfo = ColumnInfoMapper.of(type, workbook).map();
}

/**
* Validates the provided data and type.
* This method can be overridden by subclasses to add custom validation logic.
*
* @param type The class of the data type
* @param data The list of data objects to be exported
*/
protected void validate(Class<?> type, List<T> data) {
}

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

/**
* Creates headers for a new sheet using the column mapping information.
* Creates headers using the column mapping information.
*
* @param newSheet The sheet to add headers to
* @param startRowIndex The row index where headers should start
* @param sheet The sheet to add headers to
* @param headerRowIndex The headers row index
*/
protected void createHeaderWithNewSheet(Sheet newSheet, Integer startRowIndex) {
this.sheet = newSheet;
Row row = sheet.createRow(startRowIndex);
protected void createHeader(Sheet sheet, Integer headerRowIndex) {
Row row = sheet.createRow(headerRowIndex);
for (Integer colIndex : columnsMappingInfo.keySet()) {
ColumnInfo columnMappingInfo = columnsMappingInfo.get(colIndex);
Cell cell = row.createCell(colIndex);
Expand All @@ -113,11 +93,12 @@ protected void createHeaderWithNewSheet(Sheet newSheet, Integer startRowIndex) {
* Creates a row in the Excel sheet for the given data object.
* This method handles field access and cell value setting based on column mapping information.
*
* @param data The data object to create a row for
* @param sheet The Sheet object to create a row.
* @param data The data object for rendering data to cell
* @param rowIndex The index of the row to create
* @throws ExcelException if field access fails
*/
protected void createBody(Object data, int rowIndex) {
protected void createBody(Sheet sheet, Object data, int rowIndex) {
logger.debug("Add rows data - row:{}.", rowIndex);
Row row = sheet.createRow(rowIndex);
for (Integer colIndex : columnsMappingInfo.keySet()) {
Expand Down Expand Up @@ -146,7 +127,7 @@ protected void createBody(Object data, int rowIndex) {
* @throws IOException if an I/O error occurs during writing
*/
@Override
public void write(OutputStream stream) throws IOException {
public final void write(OutputStream stream) throws IOException {
if (stream == null) {
throw new ExcelException("Output stream is null.");
}
Expand All @@ -159,4 +140,22 @@ public void write(OutputStream stream) throws IOException {
}
}

/**
* Validates the provided data and type.
* This method can be overridden by subclasses to add custom validation logic.
*
* @param type The class of the data type
* @param data The list of data objects to be exported
*/
protected abstract void validate(Class<?> type, List<T> data);

/**
* Creates the Excel file with the provided data.
* This method must be implemented by subclasses to define their specific sheet management
* strategy.
*
* @param data The list of data objects to be exported
*/
protected abstract void createExcel(List<T> data);

}