Skip to content

Commit 811fd06

Browse files
committed
adds select sheet name and index for excel reader
1 parent b2c4cc0 commit 811fd06

File tree

3 files changed

+164
-28
lines changed

3 files changed

+164
-28
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ configure(allprojects){
2525
testNgVersion = '7.7.0'
2626
loggerVersion = '2.24.3'
2727
jnaVersion = '5.3.1'
28-
version '3.2.0'
28+
version '3.2.1'
2929
}
3030
group "$groupName"
3131

src/main/java/com/automationanywhere/botcommand/actions/config/ExcelReader.java

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
*/
2626
@BotCommand
2727
@CommandPkg(label = "Read Excel",
28-
node_label = "file: {{inputFilePath}}, sheet {{sheetName}} with {{parsingMethod}} and save to" +
28+
node_label = "file: {{inputFilePath}}, sheet {{selectSheetBy == 'name' ? sheetName : 'index ' + sheetIndex}} with {{parsingMethod}} and save to" +
2929
"{{returnTo}}",
3030
description = "Read values from Excel file and save to dictionary",
3131
icon = "excel.svg", name = "config_read_excel",
@@ -47,11 +47,28 @@ public DictionaryValue action(
4747
@FileExtension("xlsx,xls")
4848
String inputFilePath,
4949

50-
@Idx(index = "2", type = AttributeType.TEXT)
51-
@Pkg(label = "Enter sheet name to read")
50+
@Idx(index = "2", type = AttributeType.SELECT, options = {
51+
@Idx.Option(index = "2.1", pkg = @Pkg(label = "Name", value = "name")),
52+
@Idx.Option(index = "2.2", pkg = @Pkg(label = "Index", value = "index"))
53+
})
54+
@Pkg(label = "Select sheet by", description = "Select sheet by name or index",
55+
default_value = "name", default_value_type = DataType.STRING)
56+
@NotEmpty
57+
@SelectModes
58+
String selectSheetBy,
59+
60+
@Idx(index = "2.1.1", type = AttributeType.TEXT)
61+
@Pkg(label = "Sheet name")
5262
@NotEmpty
5363
String sheetName,
5464

65+
@Idx(index = "2.2.1", type = AttributeType.NUMBER)
66+
@Pkg(label = "Sheet index", description = "Index of the sheet (0-based)")
67+
@NotEmpty
68+
@NumberInteger
69+
@GreaterThanEqualTo("0")
70+
Double sheetIndex,
71+
5572
@Idx(index = "3", type = AttributeType.CHECKBOX)
5673
@Pkg(label = "File is password protected", description = "Select to supply password")
5774
Boolean isPasswordProtected,
@@ -137,10 +154,21 @@ public DictionaryValue action(
137154
workbook = WorkbookFactory.create(inputStream);
138155
}
139156

140-
// Get sheet by name
141-
Sheet sheet = workbook.getSheet(sheetName);
142-
if (sheet == null) {
143-
throw new BotCommandException("Sheet with name '" + sheetName + "' not found");
157+
// Get sheet based on selection method
158+
Sheet sheet;
159+
if ("name".equalsIgnoreCase(selectSheetBy)) {
160+
sheet = workbook.getSheet(sheetName);
161+
if (sheet == null) {
162+
throw new BotCommandException("Sheet with name '" + sheetName + "' not found");
163+
}
164+
} else { // index
165+
int sheetIdx = sheetIndex.intValue();
166+
int sheetCount = workbook.getNumberOfSheets();
167+
if (sheetIdx < 0 || sheetIdx >= sheetCount) {
168+
throw new BotCommandException("Invalid sheet index: " + sheetIdx +
169+
". Valid range is 0 to " + (sheetCount - 1));
170+
}
171+
sheet = workbook.getSheetAt(sheetIdx);
144172
}
145173

146174
// Initialize data formatter for cell value extraction
@@ -153,7 +181,8 @@ public DictionaryValue action(
153181
if (hasHeader) {
154182
Row headerRow = sheet.getRow(0);
155183
if (headerRow == null) {
156-
throw new BotCommandException("Header row not found in sheet '" + sheetName + "'");
184+
throw new BotCommandException("Header row not found in sheet '" +
185+
(selectSheetBy.equals("name") ? sheetName : "at index " + sheetIndex.intValue()) + "'");
157186
}
158187
keyIdx = findColumnIndex(headerRow, keyColumnName);
159188
valueIdx = findColumnIndex(headerRow, valueColumnName);

src/test/java/config/ExcelReaderTest.java

Lines changed: 126 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@ public class ExcelReaderTest {
2121
private static final String COLUMN_AGE = "Age";
2222
private static final String COLUMN_INDEX = "INDEX";
2323
private static final String COLUMN_HEADER = "HEADER";
24+
private static final String SELECT_BY_NAME = "name";
25+
private static final String SELECT_BY_INDEX = "index";
2426
private static final int INDEX_NAME = 0; // assuming 'Name' is in the first column
2527
private static final int INDEX_AGE = 1; // assuming 'Age' is in the second column
28+
private static final int SHEET_INDEX_0 = 0; // Sheet1
29+
private static final int SHEET_INDEX_1 = 1; // Sheet2
2630
private ExcelReader excelReader;
2731

2832
@BeforeMethod
@@ -39,15 +43,17 @@ public void tearDown() {
3943
public void testReadExcelByHeader() {
4044
DictionaryValue result = excelReader.action(
4145
SAMPLE_EXCEL_PATH,
42-
SHEET_NAME_1,
46+
SELECT_BY_NAME, // select sheet by name
47+
SHEET_NAME_1, // sheet name
48+
null, // sheet index (not used when selecting by name)
4349
false,
44-
null, // no password needed for this test
50+
null, // no password needed for this test
4551
COLUMN_HEADER,
46-
null, // not using index for header parsing method
47-
null, // not using index for header parsing method
52+
null, // not using index for header parsing method
53+
null, // not using index for header parsing method
4854
COLUMN_NAME,
4955
COLUMN_AGE,
50-
false // assuming we do not want to trim values for this test
56+
false // assuming we do not want to trim values for this test
5157
);
5258

5359
Assert.assertNotNull(result, "The result should not be null.");
@@ -58,15 +64,17 @@ public void testReadExcelByHeader() {
5864
public void testReadExcelByIndex() {
5965
DictionaryValue result = excelReader.action(
6066
SAMPLE_EXCEL_PATH,
61-
SHEET_NAME_1,
67+
SELECT_BY_NAME, // select sheet by name
68+
SHEET_NAME_1, // sheet name
69+
null, // sheet index (not used when selecting by name)
6270
false,
63-
null, // no password needed for this test
71+
null, // no password needed for this test
6472
COLUMN_INDEX,
6573
(double) INDEX_NAME,
6674
(double) INDEX_AGE,
67-
null, // header name not needed for index parsing method
68-
null, // header name not needed for index parsing method
69-
false // assuming we do not want to trim values for this test
75+
null, // header name not needed for index parsing method
76+
null, // header name not needed for index parsing method
77+
false // assuming we do not want to trim values for this test
7078
);
7179

7280
Assert.assertNotNull(result, "The result should not be null.");
@@ -77,15 +85,80 @@ public void testReadExcelByIndex() {
7785
public void testReadExcelByIndexDifferentSheet() {
7886
DictionaryValue result = excelReader.action(
7987
SAMPLE_EXCEL_PATH,
80-
SHEET_NAME_2,
88+
SELECT_BY_NAME, // select sheet by name
89+
SHEET_NAME_2, // sheet name
90+
null, // sheet index (not used when selecting by name)
8191
false,
82-
null, // no password needed for this test
92+
null, // no password needed for this test
8393
COLUMN_INDEX,
8494
(double) INDEX_NAME,
8595
(double) INDEX_AGE,
86-
null, // header name not needed for index parsing method
87-
null, // header name not needed for index parsing method
88-
false // assuming we do not want to trim values for this test
96+
null, // header name not needed for index parsing method
97+
null, // header name not needed for index parsing method
98+
false // assuming we do not want to trim values for this test
99+
);
100+
101+
Assert.assertNotNull(result, "The result should not be null.");
102+
Assert.assertEquals(result.get().size(), 5, "Dictionary should be same size as non empty rows");
103+
}
104+
105+
@Test
106+
public void testReadExcelBySheetIndex() {
107+
DictionaryValue result = excelReader.action(
108+
SAMPLE_EXCEL_PATH,
109+
SELECT_BY_INDEX, // select sheet by index
110+
null, // sheet name (not used when selecting by index)
111+
(double) SHEET_INDEX_0, // sheet index for Sheet1
112+
false,
113+
null, // no password needed for this test
114+
COLUMN_INDEX,
115+
(double) INDEX_NAME,
116+
(double) INDEX_AGE,
117+
null, // header name not needed for index parsing method
118+
null, // header name not needed for index parsing method
119+
false // assuming we do not want to trim values for this test
120+
);
121+
122+
Assert.assertNotNull(result, "The result should not be null.");
123+
Assert.assertEquals(result.get().size(), 6, "Dictionary should be same size as non empty rows");
124+
}
125+
126+
@Test
127+
public void testReadExcelBySheetIndexDifferentSheet() {
128+
DictionaryValue result = excelReader.action(
129+
SAMPLE_EXCEL_PATH,
130+
SELECT_BY_INDEX, // select sheet by index
131+
null, // sheet name (not used when selecting by index)
132+
(double) SHEET_INDEX_1, // sheet index for Sheet2
133+
false,
134+
null, // no password needed for this test
135+
COLUMN_INDEX,
136+
(double) INDEX_NAME,
137+
(double) INDEX_AGE,
138+
null, // header name not needed for index parsing method
139+
null, // header name not needed for index parsing method
140+
false // assuming we do not want to trim values for this test
141+
);
142+
143+
Assert.assertNotNull(result, "The result should not be null.");
144+
Assert.assertEquals(result.get().size(), 5, "Dictionary should be same size as non empty rows");
145+
}
146+
147+
@Test
148+
public void testReadExcelBySheetIndexWithHeaderParsing() {
149+
DictionaryValue result = excelReader.action(
150+
SAMPLE_EXCEL_PATH,
151+
SELECT_BY_INDEX, // select sheet by index
152+
null, // sheet name (not used when selecting by index)
153+
(double) SHEET_INDEX_0, // sheet index for Sheet1
154+
false,
155+
null, // no password needed for this test
156+
COLUMN_HEADER,
157+
null, // not using index for header parsing method
158+
null, // not using index for header parsing method
159+
COLUMN_NAME,
160+
COLUMN_AGE,
161+
false // assuming we do not want to trim values for this test
89162
);
90163

91164
Assert.assertNotNull(result, "The result should not be null.");
@@ -96,7 +169,9 @@ public void testReadExcelByIndexDifferentSheet() {
96169
public void testReadExcelWithInvalidPath() {
97170
excelReader.action(
98171
"invalid/path/to/excel.xlsx",
99-
SHEET_NAME_1,
172+
SELECT_BY_NAME, // select sheet by name
173+
SHEET_NAME_1, // sheet name
174+
null, // sheet index (not used when selecting by name)
100175
false,
101176
null,
102177
COLUMN_HEADER,
@@ -108,7 +183,39 @@ public void testReadExcelWithInvalidPath() {
108183
);
109184
}
110185

111-
// Add more test methods as needed
186+
@Test(expectedExceptions = BotCommandException.class)
187+
public void testReadExcelWithInvalidSheetName() {
188+
excelReader.action(
189+
SAMPLE_EXCEL_PATH,
190+
SELECT_BY_NAME, // select sheet by name
191+
"NonExistentSheet", // invalid sheet name
192+
null, // sheet index (not used when selecting by name)
193+
false,
194+
null,
195+
COLUMN_HEADER,
196+
null,
197+
null,
198+
COLUMN_NAME,
199+
COLUMN_AGE,
200+
false
201+
);
202+
}
112203

113-
// Include private helper methods if necessary to assist with your tests
114-
}
204+
@Test(expectedExceptions = BotCommandException.class)
205+
public void testReadExcelWithInvalidSheetIndex() {
206+
excelReader.action(
207+
SAMPLE_EXCEL_PATH,
208+
SELECT_BY_INDEX, // select sheet by index
209+
null, // sheet name (not used when selecting by index)
210+
99.0, // invalid sheet index
211+
false,
212+
null,
213+
COLUMN_HEADER,
214+
null,
215+
null,
216+
COLUMN_NAME,
217+
COLUMN_AGE,
218+
false
219+
);
220+
}
221+
}

0 commit comments

Comments
 (0)