diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/context/WriteContextImpl.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/context/WriteContextImpl.java index 5a1768606..2e2f8b9c5 100644 --- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/context/WriteContextImpl.java +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/context/WriteContextImpl.java @@ -28,9 +28,13 @@ import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; +import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.UUID; +import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.MapUtils; import org.apache.fesod.common.util.ListUtils; import org.apache.fesod.common.util.StringUtils; import org.apache.fesod.sheet.enums.HeaderMergeStrategy; @@ -488,6 +492,36 @@ public void finish(boolean onException) { return; } finished = true; + + // executes the callback after all sheets has been fully written. + Map writeSheetHolderMap = writeWorkbookHolder.getHasBeenInitializedSheetIndexMap(); + if (MapUtils.isNotEmpty(writeSheetHolderMap)) { + if (MapUtils.size(writeSheetHolderMap) == 1) { + SheetWriteHandlerContext sheetWriteHandlerContext = + WriteHandlerUtils.createSheetWriteHandlerContext(this); + WriteHandlerUtils.afterSheetDispose(sheetWriteHandlerContext); + } else { + List sheetNos = writeSheetHolderMap.keySet().stream() + .filter(Objects::nonNull) + .sorted() + .collect(Collectors.toList()); + + for (Integer sheetNo : sheetNos) { + WriteSheetHolder holder = writeSheetHolderMap.get(sheetNo); + if (Objects.nonNull(holder)) { + // switch context + this.writeSheetHolder = holder; + this.writeTableHolder = null; + this.currentWriteHolder = holder; + + SheetWriteHandlerContext sheetWriteHandlerContext = + WriteHandlerUtils.createSheetWriteHandlerContext(this); + WriteHandlerUtils.afterSheetDispose(sheetWriteHandlerContext); + } + } + } + } + WriteHandlerUtils.afterWorkbookDispose(writeWorkbookHolder.getWorkbookWriteHandlerContext()); if (writeWorkbookHolder == null) { return; diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/WriteHandlerUtils.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/WriteHandlerUtils.java index c616d6e1a..e6b88be4c 100644 --- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/WriteHandlerUtils.java +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/util/WriteHandlerUtils.java @@ -230,8 +230,7 @@ public static void afterRowDispose(RowWriteHandlerContext context) { } } - public static void afterSheetDispose(WriteContext writeContext) { - SheetWriteHandlerContext context = WriteHandlerUtils.createSheetWriteHandlerContext(writeContext); + public static void afterSheetDispose(SheetWriteHandlerContext context) { SheetHandlerExecutionChain sheetHandlerExecutionChain = getSheetHandlerExecutionChain(context, false); if (sheetHandlerExecutionChain != null) { sheetHandlerExecutionChain.afterSheetDispose(context); diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/ExcelBuilderImpl.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/ExcelBuilderImpl.java index 97128f56c..e1b4d8f32 100644 --- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/ExcelBuilderImpl.java +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/write/ExcelBuilderImpl.java @@ -32,7 +32,6 @@ import org.apache.fesod.sheet.exception.ExcelGenerateException; import org.apache.fesod.sheet.support.ExcelTypeEnum; import org.apache.fesod.sheet.util.FileUtils; -import org.apache.fesod.sheet.util.WriteHandlerUtils; import org.apache.fesod.sheet.write.executor.ExcelWriteAddExecutor; import org.apache.fesod.sheet.write.executor.ExcelWriteFillExecutor; import org.apache.fesod.sheet.write.metadata.WriteSheet; @@ -81,8 +80,6 @@ public void addContent(Collection data, WriteSheet writeSheet, WriteTable wri excelWriteAddExecutor = new ExcelWriteAddExecutor(context); } excelWriteAddExecutor.add(data); - // execute callback after the sheet is written - WriteHandlerUtils.afterSheetDispose(context); } catch (RuntimeException e) { finishOnException(); throw e; @@ -106,8 +103,6 @@ public void fill(Object data, FillConfig fillConfig, WriteSheet writeSheet) { excelWriteFillExecutor = new ExcelWriteFillExecutor(context); } excelWriteFillExecutor.fill(data, fillConfig); - // execute callback after the sheet is written - WriteHandlerUtils.afterSheetDispose(context); } catch (RuntimeException e) { finishOnException(); throw e; diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/handler/CountingWriteHandler.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/handler/CountingWriteHandler.java new file mode 100644 index 000000000..ec82bdbba --- /dev/null +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/handler/CountingWriteHandler.java @@ -0,0 +1,332 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.fesod.sheet.handler; + +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.fesod.sheet.metadata.Head; +import org.apache.fesod.sheet.metadata.data.WriteCellData; +import org.apache.fesod.sheet.write.handler.CellWriteHandler; +import org.apache.fesod.sheet.write.handler.RowWriteHandler; +import org.apache.fesod.sheet.write.handler.SheetWriteHandler; +import org.apache.fesod.sheet.write.handler.WorkbookWriteHandler; +import org.apache.fesod.sheet.write.handler.context.SheetWriteHandlerContext; +import org.apache.fesod.sheet.write.metadata.holder.WriteSheetHolder; +import org.apache.fesod.sheet.write.metadata.holder.WriteTableHolder; +import org.apache.fesod.sheet.write.metadata.holder.WriteWorkbookHolder; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Row; +import org.junit.jupiter.api.Assertions; + +public class CountingWriteHandler + implements WorkbookWriteHandler, SheetWriteHandler, RowWriteHandler, CellWriteHandler { + + private long beforeCellCreate = 0L; + private long afterCellCreate = 0L; + private long afterCellDataConverted = 0L; + private long afterCellDispose = 0L; + private long beforeRowCreate = 0L; + private long afterRowCreate = 0L; + private long afterRowDispose = 0L; + private long beforeSheetCreate = 0L; + private long afterSheetCreate = 0L; + private long afterSheetDispose = 0L; + private List afterSheetDisposeSheetNos = new ArrayList<>(); + private long beforeWorkbookCreate = 0L; + private long afterWorkbookCreate = 0L; + private long afterWorkbookDispose = 0L; + + private final HookInvocationCounter counter; + + private CountingWriteHandler(HookInvocationCounter counter) { + this.counter = counter; + } + + public static HookInvocationCounter builder() { + return new HookInvocationCounter(); + } + + @Override + public void beforeCellCreate( + WriteSheetHolder writeSheetHolder, + WriteTableHolder writeTableHolder, + Row row, + Head head, + Integer columnIndex, + Integer relativeRowIndex, + Boolean isHead) { + if (isHead) { + beforeCellCreate++; + } + } + + @Override + public void afterCellCreate( + WriteSheetHolder writeSheetHolder, + WriteTableHolder writeTableHolder, + Cell cell, + Head head, + Integer relativeRowIndex, + Boolean isHead) { + if (isHead) { + afterCellCreate++; + } + } + + @Override + public void afterCellDataConverted( + WriteSheetHolder writeSheetHolder, + WriteTableHolder writeTableHolder, + WriteCellData cellData, + Cell cell, + Head head, + Integer relativeRowIndex, + Boolean isHead) { + afterCellDataConverted++; + } + + @Override + public void afterCellDispose( + WriteSheetHolder writeSheetHolder, + WriteTableHolder writeTableHolder, + List> cellDataList, + Cell cell, + Head head, + Integer relativeRowIndex, + Boolean isHead) { + if (isHead) { + afterCellDispose++; + } + } + + @Override + public void beforeRowCreate( + WriteSheetHolder writeSheetHolder, + WriteTableHolder writeTableHolder, + Integer rowIndex, + Integer relativeRowIndex, + Boolean isHead) { + if (isHead) { + beforeRowCreate++; + } + } + + @Override + public void afterRowCreate( + WriteSheetHolder writeSheetHolder, + WriteTableHolder writeTableHolder, + Row row, + Integer relativeRowIndex, + Boolean isHead) { + if (isHead) { + afterRowCreate++; + } + } + + @Override + public void afterRowDispose( + WriteSheetHolder writeSheetHolder, + WriteTableHolder writeTableHolder, + Row row, + Integer relativeRowIndex, + Boolean isHead) { + if (isHead) { + afterRowDispose++; + } + } + + @Override + public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { + beforeSheetCreate++; + } + + @Override + public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) { + afterSheetCreate++; + } + + @Override + public void beforeWorkbookCreate() { + beforeWorkbookCreate++; + } + + @Override + public void afterWorkbookCreate(WriteWorkbookHolder writeWorkbookHolder) { + afterWorkbookCreate++; + } + + @Override + public void afterWorkbookDispose(WriteWorkbookHolder writeWorkbookHolder) { + afterWorkbookDispose++; + } + + @Override + public void afterSheetDispose(SheetWriteHandlerContext context) { + afterSheetDispose++; + + afterSheetDisposeSheetNos.add(context.getWriteSheetHolder().getSheetNo()); + } + + public void afterAll() { + Assertions.assertEquals( + counter.beforeCellCreate, beforeCellCreate, "beforeCellCreate executes an unexpected number of times"); + Assertions.assertEquals( + counter.afterCellCreate, afterCellCreate, "'afterCellCreate' executes an unexpected number of times"); + Assertions.assertEquals( + counter.afterCellDataConverted, + afterCellDataConverted, + "'afterCellDataConverted' executes an unexpected number of times"); + Assertions.assertEquals( + counter.afterCellDispose, + afterCellDispose, + "'afterCellDispose' executes an unexpected number of times"); + Assertions.assertEquals( + counter.beforeRowCreate, beforeRowCreate, "'beforeRowCreate' executes an unexpected number of times"); + Assertions.assertEquals( + counter.afterRowCreate, afterRowCreate, "'afterRowCreate' executes an unexpected number of times"); + Assertions.assertEquals( + counter.afterRowDispose, afterRowDispose, "'afterRowDispose' executes an unexpected number of times"); + Assertions.assertEquals( + counter.beforeSheetCreate, + beforeSheetCreate, + "'beforeSheetCreate' executes an unexpected number of times"); + Assertions.assertEquals( + counter.afterSheetCreate, + afterSheetCreate, + "'afterSheetCreate' executes an unexpected number of times"); + Assertions.assertEquals( + counter.beforeWorkbookCreate, + beforeWorkbookCreate, + "'beforeWorkbookCreate' executes an unexpected number of times"); + Assertions.assertEquals( + counter.afterWorkbookCreate, + afterWorkbookCreate, + "'afterWorkbookCreate' executes an unexpected number of times"); + Assertions.assertEquals( + counter.afterWorkbookDispose, + afterWorkbookDispose, + "'afterWorkbookDispose' executes an unexpected number of times"); + Assertions.assertEquals( + counter.afterSheetDispose, + afterSheetDispose, + "'afterSheetDispose' executes an unexpected number of times"); + + if (CollectionUtils.isNotEmpty(counter.afterSheetDisposeSheetNos)) { + Assertions.assertIterableEquals( + counter.afterSheetDisposeSheetNos, + afterSheetDisposeSheetNos, + "'afterSheetDisposeSheetNos' does not match"); + } + } + + public static class HookInvocationCounter { + private long beforeCellCreate = 0L; + private long afterCellCreate = 0L; + private long afterCellDataConverted = 0L; + private long afterCellDispose = 0L; + private long beforeRowCreate = 0L; + private long afterRowCreate = 0L; + private long afterRowDispose = 0L; + private long beforeSheetCreate = 0L; + private long afterSheetCreate = 0L; + private long afterSheetDispose = 0L; + private List afterSheetDisposeSheetNos; + private long beforeWorkbookCreate = 0L; + private long afterWorkbookCreate = 0L; + private long afterWorkbookDispose = 0L; + + private HookInvocationCounter() {} + + public HookInvocationCounter withBeforeCellCreate(long beforeCellCreate) { + this.beforeCellCreate = beforeCellCreate; + return this; + } + + public HookInvocationCounter withAfterCellCreate(long afterCellCreate) { + this.afterCellCreate = afterCellCreate; + return this; + } + + public HookInvocationCounter withAfterCellDataConverted(long afterCellDataConverted) { + this.afterCellDataConverted = afterCellDataConverted; + return this; + } + + public HookInvocationCounter withAfterCellDispose(long afterCellDispose) { + this.afterCellDispose = afterCellDispose; + return this; + } + + public HookInvocationCounter withBeforeRowCreate(long beforeRowCreate) { + this.beforeRowCreate = beforeRowCreate; + return this; + } + + public HookInvocationCounter withAfterRowCreate(long afterRowCreate) { + this.afterRowCreate = afterRowCreate; + return this; + } + + public HookInvocationCounter withAfterRowDispose(long afterRowDispose) { + this.afterRowDispose = afterRowDispose; + return this; + } + + public HookInvocationCounter withBeforeSheetCreate(long beforeSheetCreate) { + this.beforeSheetCreate = beforeSheetCreate; + return this; + } + + public HookInvocationCounter withAfterSheetCreate(long afterSheetCreate) { + this.afterSheetCreate = afterSheetCreate; + return this; + } + + public HookInvocationCounter withBeforeWorkbookCreate(long beforeWorkbookCreate) { + this.beforeWorkbookCreate = beforeWorkbookCreate; + return this; + } + + public HookInvocationCounter withAfterWorkbookCreate(long afterWorkbookCreate) { + this.afterWorkbookCreate = afterWorkbookCreate; + return this; + } + + public HookInvocationCounter withAfterWorkbookDispose(long afterWorkbookDispose) { + this.afterWorkbookDispose = afterWorkbookDispose; + return this; + } + + public HookInvocationCounter withAfterSheetDispose(long afterSheetDispose) { + this.afterSheetDispose = afterSheetDispose; + return this; + } + + public HookInvocationCounter withAfterSheetDisposeSheetNos(List afterSheetDisposeSheetNos) { + this.afterSheetDisposeSheetNos = afterSheetDisposeSheetNos; + return this; + } + + public CountingWriteHandler build() { + return new CountingWriteHandler(this); + } + } +} diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/handler/WriteHandlerTest.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/handler/WriteHandlerTest.java index 475c55669..5fae91626 100644 --- a/fesod-sheet/src/test/java/org/apache/fesod/sheet/handler/WriteHandlerTest.java +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/handler/WriteHandlerTest.java @@ -26,11 +26,21 @@ package org.apache.fesod.sheet.handler; import java.io.File; +import java.net.URISyntaxException; +import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import org.apache.fesod.sheet.ExcelWriter; import org.apache.fesod.sheet.FesodSheet; import org.apache.fesod.sheet.util.TestFileUtil; -import org.junit.jupiter.api.BeforeAll; +import org.apache.fesod.sheet.write.metadata.WriteSheet; +import org.apache.fesod.sheet.write.metadata.WriteTable; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; @@ -41,15 +51,31 @@ @TestMethodOrder(MethodOrderer.MethodName.class) public class WriteHandlerTest { - private static File file07; - private static File file03; - private static File fileCsv; + private File file07; + private File file03; + private File fileCsv; - @BeforeAll - public static void init() { + private File fillTemplate07; + private File fillTemplate03; + private File fill07; + private File fill03; + + @BeforeEach + void init() throws Exception { file07 = TestFileUtil.createNewFile("writeHandler07.xlsx"); file03 = TestFileUtil.createNewFile("writeHandler03.xls"); fileCsv = TestFileUtil.createNewFile("writeHandlerCsv.csv"); + + fillTemplate07 = loadTemplate("fillHandler07.xlsx"); + fillTemplate03 = loadTemplate("fillHandler03.xls"); + fill07 = TestFileUtil.createNewFile("fill07.xlsx"); + fill03 = TestFileUtil.createNewFile("fill03.xls"); + } + + private File loadTemplate(String filename) throws URISyntaxException { + URL resource = getClass().getClassLoader().getResource("fill" + File.separator + filename); + Assertions.assertNotNull(resource); + return new File(resource.toURI()); } @Test @@ -97,6 +123,86 @@ public void t23TableWriteCsv() throws Exception { tableWrite(fileCsv); } + @Test + public void t31SheetWrite07() throws Exception { + writeSheetWithMultiWrites(file07); + } + + @Test + public void t32SheetWrite03() throws Exception { + writeSheetWithMultiWrites(file03); + } + + @Test + public void t33SheetWriteCsv() throws Exception { + writeSheetWithMultiWrites(fileCsv); + } + + @Test + public void t41TableWrite07() throws Exception { + writeTableWithMultiWrites(file07); + } + + @Test + public void t42TableWrite03() throws Exception { + writeTableWithMultiWrites(file03); + } + + @Test + public void t43TableWriteCsv() throws Exception { + writeTableWithMultiWrites(fileCsv); + } + + @Test + public void t51SheetFill07() throws Exception { + fillSheetWithMultiFills(fillTemplate07, fill07); + } + + @Test + public void t52SheetFill03() throws Exception { + fillSheetWithMultiFills(fillTemplate03, fill03); + } + + @Test + public void t61MultiSheetWrite07() throws Exception { + writeMultiSheet(file07); + } + + @Test + public void t62MultiSheetWrite03() throws Exception { + writeMultiSheet(file03); + } + + @Test + public void t71MultiSheetTableWrite07() throws Exception { + writeTableWithMultiSheetAndWrites(file07); + } + + @Test + public void t72MultiSheetTableWrite03() throws Exception { + writeTableWithMultiSheetAndWrites(file03); + } + + @Test + public void t81MultiSheetFill07() throws Exception { + fillMultiSheet(fillTemplate07, file07); + } + + @Test + public void t82MultiSheetFill03() throws Exception { + fillMultiSheet(fillTemplate03, file03); + } + + @Test + public void t91MultiSheetWithSheetLevelHandler07() throws Exception { + writeMultiSheetWithSheetLevelHandler(file07); + } + + @Test + public void t92MultiSheetWithSheetLevelHandler03() throws Exception { + writeMultiSheetWithSheetLevelHandler(file03); + } + private void workbookWrite(File file) { WriteHandler writeHandler = new WriteHandler(); FesodSheet.write(file) @@ -117,6 +223,39 @@ private void sheetWrite(File file) { writeHandler.afterAll(); } + private void writeSheetWithMultiWrites(File file) { + CountingWriteHandler writeHandler = CountingWriteHandler.builder() + .withBeforeCellCreate(1L) + .withAfterCellCreate(1L) + .withAfterCellDataConverted(2L) + .withAfterCellDispose(1L) + .withBeforeRowCreate(1L) + .withAfterRowCreate(1L) + .withAfterRowDispose(1L) + .withBeforeSheetCreate(1L) + .withAfterSheetCreate(1L) + .withAfterSheetDispose(1L) + .withAfterSheetDisposeSheetNos(Collections.singletonList(0)) + .withBeforeWorkbookCreate(1L) + .withAfterWorkbookCreate(1L) + .withAfterWorkbookDispose(1L) + .build(); + + try (ExcelWriter writer = + FesodSheet.write(file).head(WriteHandlerData.class).build()) { + + WriteSheet writeSheet = FesodSheet.writerSheet() + .needHead(Boolean.TRUE) + .registerWriteHandler(writeHandler) + .build(); + + writer.write(data(), writeSheet); + writer.write(data(), writeSheet); + } + + writeHandler.afterAll(); + } + private void tableWrite(File file) { WriteHandler writeHandler = new WriteHandler(); FesodSheet.write(file) @@ -128,6 +267,262 @@ private void tableWrite(File file) { writeHandler.afterAll(); } + private void writeTableWithMultiWrites(File file) { + CountingWriteHandler writeHandler = CountingWriteHandler.builder() + .withBeforeCellCreate(2L) + .withAfterCellCreate(2L) + .withAfterCellDataConverted(2L) + .withAfterCellDispose(2L) + .withBeforeRowCreate(2L) + .withAfterRowCreate(2L) + .withAfterRowDispose(2L) + .withBeforeSheetCreate(1L) + .withAfterSheetCreate(1L) + .withAfterSheetDispose(1L) + .withAfterSheetDisposeSheetNos(Collections.singletonList(0)) + .withBeforeWorkbookCreate(1L) + .withAfterWorkbookCreate(1L) + .withAfterWorkbookDispose(1L) + .build(); + + try (ExcelWriter writer = + FesodSheet.write(file).head(WriteHandlerData.class).build()) { + + WriteSheet writeSheet = FesodSheet.writerSheet() + .needHead(Boolean.FALSE) + .registerWriteHandler(writeHandler) + .build(); + WriteTable table1 = FesodSheet.writerTable(0).needHead(Boolean.TRUE).build(); + WriteTable table2 = FesodSheet.writerTable(1).needHead(Boolean.TRUE).build(); + + writer.write(data(), writeSheet, table1); + writer.write(data(), writeSheet, table2); + } + + writeHandler.afterAll(); + } + + private void writeTableWithMultiSheetAndWrites(File file) { + CountingWriteHandler writeHandler = CountingWriteHandler.builder() + .withBeforeCellCreate(4L) + .withAfterCellCreate(4L) + .withAfterCellDataConverted(4L) + .withAfterCellDispose(4L) + .withBeforeRowCreate(4L) + .withAfterRowCreate(4L) + .withAfterRowDispose(4L) + .withBeforeSheetCreate(2L) + .withAfterSheetCreate(2L) + .withAfterSheetDispose(2L) + .withAfterSheetDisposeSheetNos(Arrays.asList(0, 1)) + .withBeforeWorkbookCreate(1L) + .withAfterWorkbookCreate(1L) + .withAfterWorkbookDispose(1L) + .build(); + + try (ExcelWriter writer = FesodSheet.write(file) + .head(WriteHandlerData.class) + .registerWriteHandler(writeHandler) + .build()) { + + WriteSheet writeSheet1 = + FesodSheet.writerSheet(0).needHead(Boolean.FALSE).build(); + + writer.write( + data(), + writeSheet1, + FesodSheet.writerTable(0).needHead(Boolean.TRUE).build()); + writer.write( + data(), + writeSheet1, + FesodSheet.writerTable(1).needHead(Boolean.TRUE).build()); + + WriteSheet writeSheet2 = + FesodSheet.writerSheet(1).needHead(Boolean.FALSE).build(); + + writer.write( + data(), + writeSheet2, + FesodSheet.writerTable(0).needHead(Boolean.TRUE).build()); + writer.write( + data(), + writeSheet2, + FesodSheet.writerTable(1).needHead(Boolean.TRUE).build()); + } + + writeHandler.afterAll(); + } + + private void fillSheetWithMultiFills(File template, File file) { + CountingWriteHandler writeHandler = CountingWriteHandler.builder() + .withBeforeCellCreate(0L) + .withAfterCellCreate(0L) + .withAfterCellDataConverted(4L) + .withAfterCellDispose(0L) + .withBeforeRowCreate(0L) + .withAfterRowCreate(0L) + .withAfterRowDispose(0L) + .withBeforeSheetCreate(1L) + .withAfterSheetCreate(1L) + .withAfterSheetDispose(1L) + .withAfterSheetDisposeSheetNos(Collections.singletonList(0)) + .withBeforeWorkbookCreate(1L) + .withAfterWorkbookCreate(1L) + .withAfterWorkbookDispose(1L) + .build(); + + try (ExcelWriter writer = FesodSheet.write(file).withTemplate(template).build()) { + + WriteSheet writeSheet = + FesodSheet.writerSheet().registerWriteHandler(writeHandler).build(); + + Map data1 = new HashMap<>(); + data1.put("name", "Tom"); + + Map data2 = new HashMap<>(); + data2.put("code", "Custom Code"); + + writer.fill(data1, writeSheet); + writer.fill(data2, writeSheet); + } + + writeHandler.afterAll(); + } + + private void writeMultiSheet(File file) { + CountingWriteHandler writeHandler = CountingWriteHandler.builder() + .withBeforeCellCreate(2L) + .withAfterCellCreate(2L) + .withAfterCellDataConverted(2L) + .withAfterCellDispose(2L) + .withBeforeRowCreate(2L) + .withAfterRowCreate(2L) + .withAfterRowDispose(2L) + .withBeforeSheetCreate(2L) + .withAfterSheetCreate(2L) + .withAfterSheetDispose(2L) + .withAfterSheetDisposeSheetNos(Arrays.asList(0, 1)) + .withBeforeWorkbookCreate(1L) + .withAfterWorkbookCreate(1L) + .withAfterWorkbookDispose(1L) + .build(); + + try (ExcelWriter writer = FesodSheet.write(file) + .head(WriteHandlerData.class) + .registerWriteHandler(writeHandler) + .build()) { + + WriteSheet writeSheet1 = + FesodSheet.writerSheet(0).needHead(Boolean.TRUE).build(); + writer.write(data(), writeSheet1); + + WriteSheet writeSheet2 = + FesodSheet.writerSheet(1).needHead(Boolean.TRUE).build(); + writer.write(data(), writeSheet2); + } + + writeHandler.afterAll(); + } + + private void fillMultiSheet(File template, File file) { + CountingWriteHandler writeHandler = CountingWriteHandler.builder() + .withBeforeCellCreate(0L) + .withAfterCellCreate(0L) + .withAfterCellDataConverted(8L) + .withAfterCellDispose(0L) + .withBeforeRowCreate(0L) + .withAfterRowCreate(0L) + .withAfterRowDispose(0L) + .withBeforeSheetCreate(2L) + .withAfterSheetCreate(2L) + .withAfterSheetDispose(2L) + .withAfterSheetDisposeSheetNos(Arrays.asList(0, 1)) + .withBeforeWorkbookCreate(1L) + .withAfterWorkbookCreate(1L) + .withAfterWorkbookDispose(1L) + .build(); + + try (ExcelWriter writer = FesodSheet.write(file) + .withTemplate(template) + .registerWriteHandler(writeHandler) + .build()) { + + WriteSheet writeSheet0 = FesodSheet.writerSheet(0).build(); + Map data1 = new HashMap<>(); + data1.put("name", "Tom"); + Map data2 = new HashMap<>(); + data2.put("code", "Code1"); + writer.fill(data1, writeSheet0); + writer.fill(data2, writeSheet0); + + WriteSheet writeSheet1 = FesodSheet.writerSheet(1).build(); + Map data3 = new HashMap<>(); + data3.put("name", "Jerry"); + Map data4 = new HashMap<>(); + data4.put("code", "Code2"); + writer.fill(data3, writeSheet1); + writer.fill(data4, writeSheet1); + } + + writeHandler.afterAll(); + } + + private void writeMultiSheetWithSheetLevelHandler(File file) { + CountingWriteHandler writeHandler1 = CountingWriteHandler.builder() + .withBeforeCellCreate(1L) + .withAfterCellCreate(1L) + .withAfterCellDataConverted(1L) + .withAfterCellDispose(1L) + .withBeforeRowCreate(1L) + .withAfterRowCreate(1L) + .withAfterRowDispose(1L) + .withBeforeSheetCreate(1L) + .withAfterSheetCreate(1L) + .withAfterSheetDispose(1L) + .withAfterSheetDisposeSheetNos(Collections.singletonList(0)) + .withBeforeWorkbookCreate(1L) + .withAfterWorkbookCreate(1L) + // The data has not been fully written yet + .withAfterWorkbookDispose(0L) + .build(); + + CountingWriteHandler writeHandler2 = CountingWriteHandler.builder() + .withBeforeCellCreate(1L) + .withAfterCellCreate(1L) + .withAfterCellDataConverted(1L) + .withAfterCellDispose(1L) + .withBeforeRowCreate(1L) + .withAfterRowCreate(1L) + .withAfterRowDispose(1L) + .withBeforeSheetCreate(1L) + .withAfterSheetCreate(1L) + .withAfterSheetDispose(1L) + .withAfterSheetDisposeSheetNos(Collections.singletonList(1)) + .withBeforeWorkbookCreate(1L) + .withAfterWorkbookCreate(1L) + .withAfterWorkbookDispose(1L) + .build(); + + try (ExcelWriter writer = + FesodSheet.write(file).head(WriteHandlerData.class).build()) { + + WriteSheet writeSheet1 = FesodSheet.writerSheet(0) + .needHead(Boolean.TRUE) + .registerWriteHandler(writeHandler1) + .build(); + writer.write(data(), writeSheet1); + + WriteSheet writeSheet2 = FesodSheet.writerSheet(1) + .needHead(Boolean.TRUE) + .registerWriteHandler(writeHandler2) + .build(); + writer.write(data(), writeSheet2); + } + + writeHandler1.afterAll(); + writeHandler2.afterAll(); + } + private List data() { List list = new ArrayList(); for (int i = 0; i < 1; i++) { diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/WriteHandlerUtilsTest.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/WriteHandlerUtilsTest.java index 737c5f164..75819218f 100644 --- a/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/WriteHandlerUtilsTest.java +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/util/WriteHandlerUtilsTest.java @@ -248,17 +248,21 @@ void test_afterSheetCreate_chain_null() { @Test void test_afterSheetDispose_execution() { + SheetWriteHandlerContext context = Mockito.mock(SheetWriteHandlerContext.class); + Mockito.when(context.getWriteContext()).thenReturn(writeContext); Mockito.when(abstractWriteHolder.getSheetHandlerExecutionChain()).thenReturn(sheetChain); - Assertions.assertDoesNotThrow(() -> WriteHandlerUtils.afterSheetDispose(writeContext)); + Assertions.assertDoesNotThrow(() -> WriteHandlerUtils.afterSheetDispose(context)); Mockito.verify(sheetChain).afterSheetDispose(ArgumentMatchers.any(SheetWriteHandlerContext.class)); } @Test void test_afterSheetDispose_chain_null() { + SheetWriteHandlerContext context = Mockito.mock(SheetWriteHandlerContext.class); + Mockito.when(context.getWriteContext()).thenReturn(writeContext); Mockito.when(abstractWriteHolder.getSheetHandlerExecutionChain()).thenReturn(null); - Assertions.assertDoesNotThrow(() -> WriteHandlerUtils.afterSheetDispose(writeContext)); + Assertions.assertDoesNotThrow(() -> WriteHandlerUtils.afterSheetDispose(context)); } @Test diff --git a/fesod-sheet/src/test/resources/fill/fillHandler03.xls b/fesod-sheet/src/test/resources/fill/fillHandler03.xls new file mode 100644 index 000000000..176acb9d5 Binary files /dev/null and b/fesod-sheet/src/test/resources/fill/fillHandler03.xls differ diff --git a/fesod-sheet/src/test/resources/fill/fillHandler07.xlsx b/fesod-sheet/src/test/resources/fill/fillHandler07.xlsx new file mode 100644 index 000000000..fb83f7599 Binary files /dev/null and b/fesod-sheet/src/test/resources/fill/fillHandler07.xlsx differ