diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/ClassUtils.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/ClassUtils.java index 2e75fc3e3..980fc8548 100644 --- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/ClassUtils.java +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/ClassUtils.java @@ -364,7 +364,11 @@ private static FieldCache doDeclaredFields(Class clazz, ConfigurationHolder c // The current field needs to be ignored if (writeHolder.ignore(field.getFieldName(), entry.getKey())) { ignoreSet.add(field.getFieldName()); - indexFieldMap.remove(index); + // indexFieldMap is keyed by the field's explicit @ExcelProperty(index), which for + // explicit-index fields equals the sortedFieldMap position (entry.getKey()); remove + // by that key, not the running counter, otherwise an unrelated explicit-index entry + // is dropped and the ignored field's entry may survive. + indexFieldMap.remove(key); } else { // Mandatory sorted fields if (indexFieldMap.containsKey(key)) { diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/ClassUtilsTest.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/ClassUtilsTest.java index 3db502620..18664737a 100644 --- a/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/ClassUtilsTest.java +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/ClassUtilsTest.java @@ -202,6 +202,29 @@ void test_declaredFields_WriteHolder_exclude() { Assertions.assertTrue(hasAge); } + @Test + void test_declaredFields_WriteHolder_exclude_preservesUnrelatedExplicitIndex() { + // Excluding a field that has NO explicit @ExcelProperty(index) (here "email", + // which uses order=10) must not perturb indexFieldMap, which only holds fields + // that DO carry an explicit index (ComplexEntity: id->0, name->2). + Mockito.when(globalConfiguration.getFiledCacheLocation()).thenReturn(CacheLocationEnum.NONE); + + Mockito.when(writeHolder.excludeColumnFieldNames()).thenReturn(Collections.singleton("email")); + Mockito.when(writeHolder.ignore(Mockito.anyString(), Mockito.anyInt())).thenReturn(false); + Mockito.when(writeHolder.ignore(Mockito.eq("email"), Mockito.anyInt())).thenReturn(true); + + FieldCache fieldCache = ClassUtils.declaredFields(ComplexEntity.class, writeHolder); + + Map indexFieldMap = fieldCache.getIndexFieldMap(); + // id (@ExcelProperty(index = 0)) and name (index = 2) must still be present and + // bound to their explicit indices; the ignored field was never in this map. + Assertions.assertTrue(indexFieldMap.containsKey(0), "explicit index 0 (id) must remain"); + Assertions.assertEquals("id", indexFieldMap.get(0).getFieldName()); + Assertions.assertTrue(indexFieldMap.containsKey(2), "explicit index 2 (name) must remain"); + Assertions.assertEquals("name", indexFieldMap.get(2).getFieldName()); + Assertions.assertFalse(indexFieldMap.values().stream().anyMatch(f -> "email".equals(f.getFieldName()))); + } + @Test void test_declaredFields_resort() { Mockito.when(globalConfiguration.getFiledCacheLocation()).thenReturn(CacheLocationEnum.NONE);