diff --git a/spring-batch-excel/src/main/java/org/springframework/batch/extensions/excel/AbstractExcelItemReader.java b/spring-batch-excel/src/main/java/org/springframework/batch/extensions/excel/AbstractExcelItemReader.java index e5f3d6fa..837d7337 100644 --- a/spring-batch-excel/src/main/java/org/springframework/batch/extensions/excel/AbstractExcelItemReader.java +++ b/spring-batch-excel/src/main/java/org/springframework/batch/extensions/excel/AbstractExcelItemReader.java @@ -16,7 +16,11 @@ package org.springframework.batch.extensions.excel; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; import java.util.Locale; +import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -63,6 +67,8 @@ public abstract class AbstractExcelItemReader extends AbstractItemCountingIte private RowSetFactory rowSetFactory = new DefaultRowSetFactory(); + private Set sheetNames = Collections.emptySet(); + private RowSet rs; private String password; @@ -188,6 +194,10 @@ protected void doOpen() throws Exception { private boolean nextSheet() { while (this.currentSheet < this.getNumberOfSheets()) { final Sheet sheet = this.getSheet(this.currentSheet); + if (!this.sheetNames.isEmpty() && !this.sheetNames.contains(sheet.getName())) { + this.currentSheet++; + continue; + } this.rs = this.rowSetFactory.create(sheet); if (this.logger.isDebugEnabled()) { this.logger.debug("Opening sheet " + sheet.getName() + "."); @@ -214,6 +224,16 @@ protected void doClose() throws Exception { this.rs = null; } + /** + * Select sheets by name. By default, the reader processes every sheet in workbook + * order. + * @param sheetNames sheet names to process, or no names to process every sheet + */ + public void setSheetNames(String... sheetNames) { + Assert.noNullElements(sheetNames, "Sheet names must not contain null elements"); + this.sheetNames = new HashSet<>(Arrays.asList(sheetNames)); + } + /** * Public setter for the input resource. * @param resource the {@code Resource} pointing to the Excelfile diff --git a/spring-batch-excel/src/test/java/org/springframework/batch/extensions/excel/SheetSelectionTests.java b/spring-batch-excel/src/test/java/org/springframework/batch/extensions/excel/SheetSelectionTests.java new file mode 100644 index 00000000..c5819ed5 --- /dev/null +++ b/spring-batch-excel/src/test/java/org/springframework/batch/extensions/excel/SheetSelectionTests.java @@ -0,0 +1,77 @@ +/* + * Copyright 2026 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.batch.extensions.excel; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import org.springframework.batch.extensions.excel.mapping.PassThroughRowMapper; +import org.springframework.batch.infrastructure.item.ExecutionContext; + +import static org.assertj.core.api.Assertions.assertThat; + +class SheetSelectionTests { + + @Test + void readsAllSheetsByDefault() throws Exception { + assertThat(read(reader())).containsExactly("first", "second", "third"); + } + + @Test + void readsSelectedSheetsInWorkbookOrder() throws Exception { + MockExcelItemReader reader = reader(); + reader.setSheetNames("third", "first"); + assertThat(read(reader)).containsExactly("first", "third"); + } + + @Test + void readsNoRowsWhenNoSheetMatches() throws Exception { + MockExcelItemReader reader = reader(); + reader.setSheetNames("missing"); + assertThat(read(reader)).isEmpty(); + } + + private MockExcelItemReader reader() { + List sheets = new ArrayList<>(List.of(sheet("first"), sheet("second"), sheet("third"))); + MockExcelItemReader reader = new MockExcelItemReader<>(sheets); + reader.setRowMapper(new PassThroughRowMapper()); + reader.afterPropertiesSet(); + return reader; + } + + private MockSheet sheet(String name) { + return new MockSheet(name, List.of(new String[] { name })); + } + + private List read(MockExcelItemReader reader) throws Exception { + List rows = new ArrayList<>(); + reader.open(new ExecutionContext()); + try { + String[] row; + while ((row = reader.read()) != null) { + rows.add(row[0]); + } + return rows; + } + finally { + reader.close(); + } + } + +}