Search before asking
Fesod version
current main (50a6b5b)
JDK version
Temurin 25 (code path is version-independent, affects 8+)
Operating system
Linux (not OS-specific)
Steps To Reproduce
When a WriteHolder excludes a column and the bean has fields with explicit @ExcelProperty(index = N), the wrong entry is removed from the internal indexFieldMap, dropping an unrelated explicit-index field.
private static class ComplexEntity {
@ExcelProperty(index = 0)
private String id; // explicit index 0 -> indexFieldMap[0]
@ExcelProperty(index = 2)
private String name; // explicit index 2 -> indexFieldMap[2]
@ExcelProperty(order = 10)
private String email; // no explicit index -> NOT in indexFieldMap
private String noAnnotationField;
}
// exclude "email" (a field WITHOUT an explicit index)
WriteHolder writeHolder = ...; // excludeColumnFieldNames = {"email"}
FieldCache fieldCache = ClassUtils.declaredFields(ComplexEntity.class, writeHolder);
Map<Integer, FieldWrapper> indexFieldMap = fieldCache.getIndexFieldMap();
// expected: id and name remain (email was never in the map)
// actual: id (index 0) is gone; indexFieldMap == {2: name}
Current Behavior
After excluding email, indexFieldMap is {2: name} — the id entry (explicit index 0) has been wrongly removed, even though id was not excluded.
Expected Behavior
indexFieldMap should be {0: id, 2: name}. Excluding a field that has no explicit index must not perturb the explicit-index map.
Anything else?
Root cause: in the exclude/include loop, the ignored branch removes from indexFieldMap using the running counter index instead of the field's own key:
https://github.com/apache/fesod/blob/main/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/ClassUtils.java#L364-L368
if (writeHolder.ignore(field.getFieldName(), entry.getKey())) {
ignoreSet.add(field.getFieldName());
indexFieldMap.remove(index); // BUG: 'index' is the running counter, not the field's key
} else {
...
}
indexFieldMap is keyed by the field's explicit @ExcelProperty(index = N) value (see declaredOneField), and for explicit-index fields the sortedFieldMap position entry.getKey() equals that explicit index (see buildSortedAllFieldMap). So the ignored field's own entry is keyed by entry.getKey(), not by the running counter. Removing by the counter drops whichever explicit-index entry happens to match the counter and leaves the ignored field's entry in place when their indices differ.
The fix is to remove by the field's own key:
indexFieldMap.remove(key);
For a field with an explicit index, key == entry.getKey() is its indexFieldMap key, so its own entry is removed; for a field without an explicit index, key is not in indexFieldMap, so the call is a no-op (correct — it was never there).
The corruption is observable downstream: ExcelHeadProperty.initColumnProperties passes indexFieldMap.containsKey(entry.getKey()) as forceIndex into each Head, so an excluded unrelated field flips a sibling column's forceIndex from true to false, which DefaultAnalysisEventProcessor reads to drive head-to-column matching.
Are you willing to submit a PR?
Search before asking
Fesod version
current main (50a6b5b)
JDK version
Temurin 25 (code path is version-independent, affects 8+)
Operating system
Linux (not OS-specific)
Steps To Reproduce
When a
WriteHolderexcludes a column and the bean has fields with explicit@ExcelProperty(index = N), the wrong entry is removed from the internalindexFieldMap, dropping an unrelated explicit-index field.Current Behavior
After excluding
email,indexFieldMapis{2: name}— theidentry (explicit index 0) has been wrongly removed, even thoughidwas not excluded.Expected Behavior
indexFieldMapshould be{0: id, 2: name}. Excluding a field that has no explicit index must not perturb the explicit-index map.Anything else?
Root cause: in the exclude/include loop, the ignored branch removes from
indexFieldMapusing the running counterindexinstead of the field's own key:https://github.com/apache/fesod/blob/main/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/ClassUtils.java#L364-L368
indexFieldMapis keyed by the field's explicit@ExcelProperty(index = N)value (seedeclaredOneField), and for explicit-index fields thesortedFieldMappositionentry.getKey()equals that explicit index (seebuildSortedAllFieldMap). So the ignored field's own entry is keyed byentry.getKey(), not by the running counter. Removing by the counter drops whichever explicit-index entry happens to match the counter and leaves the ignored field's entry in place when their indices differ.The fix is to remove by the field's own key:
For a field with an explicit index,
key == entry.getKey()is itsindexFieldMapkey, so its own entry is removed; for a field without an explicit index,keyis not inindexFieldMap, so the call is a no-op (correct — it was never there).The corruption is observable downstream:
ExcelHeadProperty.initColumnPropertiespassesindexFieldMap.containsKey(entry.getKey())asforceIndexinto eachHead, so an excluded unrelated field flips a sibling column'sforceIndexfromtruetofalse, whichDefaultAnalysisEventProcessorreads to drive head-to-column matching.Are you willing to submit a PR?