diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/FesodSheet.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/FesodSheet.java index 2422718a3..d46cde86e 100644 --- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/FesodSheet.java +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/FesodSheet.java @@ -22,6 +22,7 @@ import java.io.File; import java.io.InputStream; import java.io.OutputStream; +import java.util.List; import org.apache.fesod.sheet.read.builder.ExcelReaderBuilder; import org.apache.fesod.sheet.read.builder.ExcelReaderSheetBuilder; import org.apache.fesod.sheet.read.listener.ReadListener; @@ -330,4 +331,20 @@ public static ExcelReaderSheetBuilder readSheet(Integer sheetNo, String sheetNam .sheetNameIfNotNull(sheetName) .numRowsIfNotNull(numRows); } + + /** + * Build excel the 'readSheet' targeting specific column indexes. + * + * @param sheetNo Index of sheet, 0 base. + * @param columnIndexes Specific columns to read (e.g., [0, 2] for Column A and C). + * @return Excel sheet reader builder. + */ + public static ExcelReaderSheetBuilder readSheetWithColumns( + Integer sheetNo, String sheetName, Integer numRows, List columnIndexes) { + return new ExcelReaderSheetBuilder() + .sheetNoIfNotNull(sheetNo) + .sheetNameIfNotNull(sheetName) + .numRowsIfNotNull(numRows) + .includeColumnIndexes(columnIndexes); + } } diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/analysis/v07/handlers/CellTagHandler.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/analysis/v07/handlers/CellTagHandler.java index 3978beff9..2c24b5cb5 100644 --- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/analysis/v07/handlers/CellTagHandler.java +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/analysis/v07/handlers/CellTagHandler.java @@ -26,6 +26,7 @@ package org.apache.fesod.sheet.analysis.v07.handlers; import java.math.BigDecimal; +import java.util.List; import org.apache.fesod.common.util.BooleanUtils; import org.apache.fesod.common.util.PositionUtils; import org.apache.fesod.common.util.StringUtils; @@ -81,6 +82,22 @@ public void startElement(XlsxReadContext xlsxReadContext, String name, Attribute public void endElement(XlsxReadContext xlsxReadContext, String name) { XlsxReadSheetHolder xlsxReadSheetHolder = xlsxReadContext.xlsxReadSheetHolder(); ReadCellData tempCellData = xlsxReadSheetHolder.getTempCellData(); + int targetColumnIndex = 0; + + List includeColumnIndexes = + xlsxReadContext.readSheetHolder().getReadSheet().getColumnIndexes(); + + if (includeColumnIndexes == null) { + targetColumnIndex = xlsxReadSheetHolder.getColumnIndex(); + } else { + // if it's a target column, rewrite the cell's internal index + targetColumnIndex = includeColumnIndexes.indexOf(xlsxReadSheetHolder.getColumnIndex()); + if (targetColumnIndex < 0) { + + return; + } + } + StringBuilder tempData = xlsxReadSheetHolder.getTempData(); String tempDataString = tempData.toString(); CellDataTypeEnum oldType = tempCellData.getType(); @@ -130,10 +147,9 @@ public void endElement(XlsxReadContext xlsxReadContext, String name) { tempCellData.setStringValue(tempCellData.getStringValue().trim()); } } - tempCellData.checkEmpty(); tempCellData.setRowIndex(xlsxReadSheetHolder.getRowIndex()); - tempCellData.setColumnIndex(xlsxReadSheetHolder.getColumnIndex()); - xlsxReadSheetHolder.getCellMap().put(xlsxReadSheetHolder.getColumnIndex(), tempCellData); + tempCellData.setColumnIndex(targetColumnIndex); + xlsxReadSheetHolder.getCellMap().put(targetColumnIndex, tempCellData); } } diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/read/builder/ExcelReaderSheetBuilder.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/read/builder/ExcelReaderSheetBuilder.java index 8c39c96ee..38040ce09 100644 --- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/read/builder/ExcelReaderSheetBuilder.java +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/read/builder/ExcelReaderSheetBuilder.java @@ -112,6 +112,23 @@ public ReadSheet build() { return readSheet; } + /** + * Specific columns to read + * + * @param columnIndexes + * @return + */ + public ExcelReaderSheetBuilder includeColumnIndexes(List columnIndexes) { + readSheet.setColumnIndexes(columnIndexes); + return this; + } + + public ExcelReaderSheetBuilder includeColumnIndexesIfNotNull(List columnIndexes) { + if (Objects.nonNull(columnIndexes)) { + readSheet.setColumnIndexes(columnIndexes); + } + return this; + } /** * Sax read */ diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/read/metadata/ReadSheet.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/read/metadata/ReadSheet.java index 9e9f644eb..411c648d3 100644 --- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/read/metadata/ReadSheet.java +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/read/metadata/ReadSheet.java @@ -25,6 +25,7 @@ package org.apache.fesod.sheet.read.metadata; +import java.util.List; import lombok.EqualsAndHashCode; /** @@ -54,6 +55,11 @@ public class ReadSheet extends ReadBasicParameter { */ public Integer numRows; + /** + * Specific columns to read (0-based indexes) + */ + private List columnIndexes; + public ReadSheet() {} public ReadSheet(Integer sheetNo) { @@ -71,6 +77,13 @@ public ReadSheet(Integer sheetNo, String sheetName, Integer numRows) { this.numRows = numRows; } + public ReadSheet(Integer sheetNo, String sheetName, Integer numRows, List numCols) { + this.sheetNo = sheetNo; + this.sheetName = sheetName; + this.numRows = numRows; + this.columnIndexes = numCols; + } + public Integer getSheetNo() { return sheetNo; } @@ -111,6 +124,14 @@ public void setVeryHidden(boolean sheetVeryHidden) { this.sheetVeryHidden = sheetVeryHidden; } + public List getColumnIndexes() { + return this.columnIndexes; + } + + public void setColumnIndexes(List columnIndexes) { + this.columnIndexes = columnIndexes; + } + public void copyBasicParameter(ReadSheet other) { if (other == null) { return; @@ -126,6 +147,7 @@ public void copyBasicParameter(ReadSheet other) { this.setNumRows(other.getNumRows()); this.setHidden(other.isHidden()); this.setVeryHidden(other.isVeryHidden()); + this.setColumnIndexes(other.getColumnIndexes()); } @Override diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/FesodSheetTest.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/FesodSheetTest.java index 44a8bee94..b086c585d 100644 --- a/fesod-sheet/src/test/java/org/apache/fesod/sheet/FesodSheetTest.java +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/FesodSheetTest.java @@ -24,9 +24,14 @@ import java.io.OutputStream; import java.lang.reflect.Method; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import org.apache.fesod.sheet.read.builder.ExcelReaderBuilder; import org.apache.fesod.sheet.read.builder.ExcelReaderSheetBuilder; import org.apache.fesod.sheet.read.listener.ReadListener; +import org.apache.fesod.sheet.read.metadata.ReadSheet; import org.apache.fesod.sheet.read.metadata.ReadWorkbook; import org.apache.fesod.sheet.testkit.Tags; import org.apache.fesod.sheet.write.builder.ExcelWriterBuilder; @@ -247,4 +252,42 @@ void testReadSheet_withAllParams_shouldReturnBuilder() { ExcelReaderSheetBuilder builder = FesodSheet.readSheet(0, "DataSheet", 100); Assertions.assertNotNull(builder); } + + @Test + void testReadSheet_withColumnIndexes_shouldConfigureAll() { + + List> head = new ArrayList<>(); + head.add(new ArrayList<>(Arrays.asList("ID"))); + head.add(new ArrayList<>(Arrays.asList("Name"))); + head.add(new ArrayList<>(Arrays.asList("Age"))); + head.add(new ArrayList<>(Arrays.asList("Gender"))); + + List> dataList = new ArrayList<>(); + dataList.add(Arrays.asList("1", "Alice", "30", "Female")); + + FesodSheet.write(tempFile).head(head).sheet("Sheet1").doWrite(dataList); + + List targetColumns = Arrays.asList(0, 2); + + ExcelReaderSheetBuilder builder = FesodSheet.readSheetWithColumns(0, "Sheet1", 100, targetColumns); + ReadSheet configuredSheet = builder.build(); + List> readResults = FesodSheet.read(tempFile) + .sheet(0) + .includeColumnIndexes(targetColumns) + .doReadSync(); + + // builder tests + Assertions.assertNotNull(builder, "Builder should not be null"); + Assertions.assertNotNull(configuredSheet, "The internal ReadSheet should be created"); + Assertions.assertEquals(0, configuredSheet.getSheetNo()); + Assertions.assertEquals("Sheet1", configuredSheet.getSheetName()); + Assertions.assertEquals(100, configuredSheet.getNumRows()); + Assertions.assertEquals(targetColumns, configuredSheet.getColumnIndexes()); + // data related tests + Assertions.assertNotNull(readResults); + Map parsedRow = readResults.get(0); + Assertions.assertEquals(2, parsedRow.size()); + Assertions.assertEquals("1", parsedRow.get(0)); + Assertions.assertEquals("30", parsedRow.get(1)); + } }