Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,10 @@ private void createNewSheet() {
String newSheetName = String.format("Sheet%d", currentSheetIndex);
this.st = wb.createSheet(newSheetName);
Row headerRow = st.createRow(0);
int index = 0;
for (Integer i : sinkColumnsIndexInRow) {
String fieldName = seaTunnelRowType.getFieldName(i);
headerRow.createCell(i).setCellValue(fieldName);
headerRow.createCell(index++).setCellValue(fieldName);
}
currentRowInSheet = 0;
}
Expand All @@ -95,9 +96,10 @@ public ExcelGenerator(
Optional<String> sheetName = Optional.ofNullable(fileSinkConfig.getSheetName());
this.st = wb.createSheet(sheetName.orElseGet(() -> String.format("Sheet%d", 0)));
Row row = st.createRow(0);
int index = 0;
for (Integer i : sinkColumnsIndexInRow) {
String fieldName = seaTunnelRowType.getFieldName(i);
row.createCell(i).setCellValue(fieldName);
row.createCell(index++).setCellValue(fieldName);
}
this.dateFormat = fileSinkConfig.getDateFormat();
this.dateTimeFormat = fileSinkConfig.getDatetimeFormat();
Expand All @@ -117,8 +119,9 @@ public void writeData(SeaTunnelRow seaTunnelRow) {
}
Row excelRow = this.st.createRow(currentRowInSheet + HEADER_ROWS);
SeaTunnelDataType<?>[] fieldTypes = seaTunnelRowType.getFieldTypes();
int index = 0;
for (Integer i : sinkColumnsIndexInRow) {
Cell cell = excelRow.createCell(i);
Cell cell = excelRow.createCell(index++);
Object value = seaTunnelRow.getField(i);
setCellValue(fieldTypes[i], seaTunnelRowType.getFieldName(i), value, cell);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,98 @@ public void doAfterAllAnalysed(AnalysisContext context) {
assertTrue("Headers should be valid", headerValid.get());
assertEquals("Should have correct number of rows", expectedDataRows, rowCount.get());
}

@Test
public void testGenerateExcelFileWithReorderedColumns() throws IOException {
File outputDir = new File("target/test-output");
if (!outputDir.exists()) {
outputDir.mkdirs();
}

File outputFile = new File(outputDir, "reordered-columns-test.xlsx");

// Use non-consecutive indices to test the fix
List<Integer> reorderedColumnsIndexInRow = Arrays.asList(3, 1, 2, 0);
ExcelGenerator excelGenerator =
new ExcelGenerator(reorderedColumnsIndexInRow, rowType, fileSinkConfig);

SeaTunnelRow[] testData = {
new SeaTunnelRow(new Object[] {1, "Alice", 25, "[email protected]"}),
new SeaTunnelRow(new Object[] {2, "Bob", 30, "[email protected]"})
};

for (SeaTunnelRow row : testData) {
excelGenerator.writeData(row);
}

try (FileOutputStream fos = new FileOutputStream(outputFile)) {
excelGenerator.flushAndCloseExcel(fos);
}

assertTrue("File should exist", outputFile.exists());
assertTrue("File should not be empty", outputFile.length() > 0);

// Validate the reordered columns
validateReorderedColumnsFile(outputFile, 2, 0);
}

private void validateReorderedColumnsFile(File file, int expectedDataRows, int sheetNo)
throws IOException {
AtomicInteger rowCount = new AtomicInteger(0);
AtomicBoolean headerValid = new AtomicBoolean(false);
EasyExcel.read(file)
.registerReadListener(
new AnalysisEventListener<Map<Integer, String>>() {
@Override
public void invoke(Map<Integer, String> data, AnalysisContext context) {
rowCount.incrementAndGet();
// For reordered columns [3, 1, 2, 0], the values should be in this
// order

// Check that first column is email (index 3 in original row)
// Second column is name (index 1 in original row)
// Third column is age (index 2 in original row)
// Fourth column is id (index 0 in original row)
String email = data.get(0);
String name = data.get(1);
String age = data.get(2);
String id = data.get(3);
assertTrue(
"Email should be valid",
email != null && email.endsWith("@test.com"));
assertTrue(
"Name should be valid",
name != null
&& (name.equals("Alice") || name.equals("Bob")));
assertTrue(
"Age should be valid",
age != null && (age.equals("25") || age.equals("30")));
assertTrue(
"Id should be valid",
id != null && (id.equals("1") || id.equals("2")));
}

@Override
public void invokeHeadMap(
Map<Integer, String> headMap, AnalysisContext context) {
// For reordered columns [3, 1, 2, 0], headers should be in this
// order
headerValid.set(
"email".equals(headMap.get(0))
&& "name".equals(headMap.get(1))
&& "age".equals(headMap.get(2))
&& "id".equals(headMap.get(3)));
}

@Override
public void doAfterAllAnalysed(AnalysisContext context) {
log.info("Validation completed. Total rows: " + rowCount.get());
}
})
.sheet(sheetNo)
.doRead();

assertTrue("Headers should be valid", headerValid.get());
assertEquals("Should have correct number of rows", expectedDataRows, rowCount.get());
}
}