Search before asking
Fesod version
current main (4b426ba)
JDK version
Temurin 25 (code path is version-independent, affects 8+)
Operating system
Linux (not OS-specific)
Steps To Reproduce
public class Demo {
@ExcelProperty("name")
private String name;
// getter/setter/no-arg constructor
static List<Demo> rows(int count, String prefix) {
List<Demo> list = new ArrayList<>();
for (int i = 0; i < count; i++) {
Demo d = new Demo();
d.setName(prefix + i);
list.add(d);
}
return list;
}
}
// Write a workbook with two sheets: 3 rows and 4 rows
try (ExcelWriter writer = FesodSheet.write(file, Demo.class).build()) {
writer.write(Demo.rows(3, "First"), FesodSheet.writerSheet(0, "sheet0").build());
writer.write(Demo.rows(4, "Second"), FesodSheet.writerSheet(1, "sheet1").build());
}
// Read all sheets with one PageReadListener, page size 5
List<Demo> delivered = new ArrayList<>();
FesodSheet.read(file, Demo.class, new PageReadListener<Demo>(delivered::addAll, 5))
.doReadAll();
System.out.println(delivered.size()); // prints 10, expected 7
Current Behavior
The consumer receives the batches [3 rows], [5 rows], [2 rows] - 10 rows in total. The delivered sequence is:
First0, First1, First2, First0, First1, First2, Second0, Second1, Second2, Second3
The 3 rows of sheet0 are delivered twice: once in the end-of-sheet flush, and again at the start of the first full batch produced while reading sheet1.
Expected Behavior
The consumer receives [3 rows] (end of sheet0) and [4 rows] (end of sheet1) - 7 rows, each row exactly once:
First0, First1, First2, Second0, Second1, Second2, Second3
Anything else?
Root cause: PageReadListener.doAfterAllAnalysed flushes cachedDataList to the consumer but never resets it, while invoke only replaces the list when a batch fills up. DefaultAnalysisEventProcessor.endSheet calls doAfterAllAnalysed after every sheet, and the same listener instance is shared by all sheets in doReadAll(), so the next sheet keeps appending to the already-delivered list and the leftover rows are emitted again.
The bug only triggers with the two-argument constructor (batchCount > 1) when a sheet's row count is not a multiple of the batch size; the no-arg default (BATCH_COUNT = 1) flushes every row, and single-sheet reads are unaffected. Upstream EasyExcel carries the same latent code.
The fix is a one-line reset of cachedDataList in doAfterAllAnalysed; I have the fix and a regression test ready and will open a PR referencing this issue.
Are you willing to submit a PR?
Search before asking
Fesod version
current main (4b426ba)
JDK version
Temurin 25 (code path is version-independent, affects 8+)
Operating system
Linux (not OS-specific)
Steps To Reproduce
Current Behavior
The consumer receives the batches
[3 rows],[5 rows],[2 rows]- 10 rows in total. The delivered sequence is:The 3 rows of
sheet0are delivered twice: once in the end-of-sheet flush, and again at the start of the first full batch produced while readingsheet1.Expected Behavior
The consumer receives
[3 rows](end of sheet0) and[4 rows](end of sheet1) - 7 rows, each row exactly once:Anything else?
Root cause:
PageReadListener.doAfterAllAnalysedflushescachedDataListto the consumer but never resets it, whileinvokeonly replaces the list when a batch fills up.DefaultAnalysisEventProcessor.endSheetcallsdoAfterAllAnalysedafter every sheet, and the same listener instance is shared by all sheets indoReadAll(), so the next sheet keeps appending to the already-delivered list and the leftover rows are emitted again.The bug only triggers with the two-argument constructor (
batchCount > 1) when a sheet's row count is not a multiple of the batch size; the no-arg default (BATCH_COUNT = 1) flushes every row, and single-sheet reads are unaffected. Upstream EasyExcel carries the same latent code.The fix is a one-line reset of
cachedDataListindoAfterAllAnalysed; I have the fix and a regression test ready and will open a PR referencing this issue.Are you willing to submit a PR?