This is an automated email from the ASF dual-hosted git repository.

delei pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fesod.git


The following commit(s) were added to refs/heads/main by this push:
     new c65712dc fix: correct SheetWriteHandler.afterSheetDispose to avoid 
repeated execution (#900)
c65712dc is described below

commit c65712dc271ef0493201cdf637bd7c9bd81b3a7e
Author: Bengbengbalabalabeng 
<[email protected]>
AuthorDate: Mon Aug 17 08:53:01 2026 +0800

    fix: correct SheetWriteHandler.afterSheetDispose to avoid repeated 
execution (#900)
    
    * fix: correct SheetWriteHandler.afterSheetDispose to avoid repeated 
execution
    
    * fix: adjust afterSheetDispose execution position
    
    * fix: trigger afterSheetDispose for each sheet in multi-sheet write
    
    * fix: handle conflicts
    
    * feat: address suggestion1
    
    ---------
    
    Co-authored-by: DeleiGuo <[email protected]>
---
 .../fesod/sheet/context/WriteContextImpl.java      |  36 +++
 .../apache/fesod/sheet/util/WriteHandlerUtils.java |   3 +-
 .../apache/fesod/sheet/write/ExcelBuilderImpl.java |   5 -
 .../fesod/sheet/handler/CountingWriteHandler.java  | 332 +++++++++++++++++++++
 .../fesod/sheet/handler/WriteHandlerTest.java      | 330 ++++++++++++++++++++
 .../fesod/sheet/util/WriteHandlerUtilsTest.java    |   8 +-
 .../src/test/resources/fill/fillHandler03.xls      | Bin 0 -> 19456 bytes
 .../src/test/resources/fill/fillHandler07.xlsx     | Bin 0 -> 10407 bytes
 8 files changed, 705 insertions(+), 9 deletions(-)

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 e97149e2..fd118305 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 @@ package org.apache.fesod.sheet.context;
 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;
@@ -489,6 +493,38 @@ public class WriteContextImpl implements WriteContext {
             return;
         }
         finished = true;
+
+        // executes the callback after all sheets has been fully written.
+        boolean shouldSkip = onException && 
!writeWorkbookHolder.getWriteExcelOnException();
+        Map<Integer, WriteSheetHolder> writeSheetHolderMap =
+                shouldSkip ? null : 
writeWorkbookHolder.getHasBeenInitializedSheetIndexMap();
+        if (MapUtils.isNotEmpty(writeSheetHolderMap)) {
+            if (MapUtils.size(writeSheetHolderMap) == 1) {
+                SheetWriteHandlerContext sheetWriteHandlerContext =
+                        WriteHandlerUtils.createSheetWriteHandlerContext(this);
+                WriteHandlerUtils.afterSheetDispose(sheetWriteHandlerContext);
+            } else {
+                List<Integer> 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 c616d6e1..e6b88be4 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 class WriteHandlerUtils {
         }
     }
 
-    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 97128f56..e1b4d8f3 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.enums.WriteTypeEnum;
 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 class ExcelBuilderImpl implements ExcelBuilder {
                 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 class ExcelBuilderImpl implements ExcelBuilder {
                 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 00000000..ec82bdbb
--- /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<Integer> 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<WriteCellData<?>> 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<Integer> 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<Integer> 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 ebb90523..8c5da18c 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,7 +26,11 @@
 package org.apache.fesod.sheet.handler;
 
 import java.io.File;
+import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.fesod.sheet.ExcelWriter;
 import org.apache.fesod.sheet.FesodSheet;
 import org.apache.fesod.sheet.testkit.Tags;
 import org.apache.fesod.sheet.testkit.base.AbstractExcelTest;
@@ -34,6 +38,10 @@ import 
org.apache.fesod.sheet.testkit.builders.TestDataBuilder;
 import org.apache.fesod.sheet.testkit.enums.ExcelFormat;
 import org.apache.fesod.sheet.testkit.models.SimpleData;
 import org.apache.fesod.sheet.testkit.params.ExcelFormatSource;
+import org.apache.fesod.sheet.testkit.params.FormatCapability;
+import org.apache.fesod.sheet.testkit.params.FormatScope;
+import org.apache.fesod.sheet.write.metadata.WriteSheet;
+import org.apache.fesod.sheet.write.metadata.WriteTable;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.params.ParameterizedTest;
 
@@ -86,4 +94,326 @@ public class WriteHandlerTest extends AbstractExcelTest {
                 .doWrite(TestDataBuilder.simpleData(1));
         writeHandler.afterAll();
     }
+
+    @ParameterizedTest
+    @ExcelFormatSource(value = FormatScope.BINARY)
+    void sheetMultiWrites(ExcelFormat format) throws Exception {
+        File file = createTempFile(format);
+        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(SimpleData.class)
+                .includeColumnFieldNames(Collections.singletonList("name"))
+                .build()) {
+
+            WriteSheet writeSheet = FesodSheet.writerSheet()
+                    .needHead(Boolean.TRUE)
+                    .registerWriteHandler(writeHandler)
+                    .build();
+
+            writer.write(TestDataBuilder.simpleData(1), writeSheet);
+            writer.write(TestDataBuilder.simpleData(1), writeSheet);
+        }
+
+        writeHandler.afterAll();
+    }
+
+    @ParameterizedTest
+    @ExcelFormatSource(value = FormatScope.BINARY)
+    void multiTableWrites(ExcelFormat format) throws Exception {
+        File file = createTempFile(format);
+        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(SimpleData.class)
+                .includeColumnFieldNames(Collections.singletonList("name"))
+                .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(TestDataBuilder.simpleData(1), writeSheet, table1);
+            writer.write(TestDataBuilder.simpleData(1), writeSheet, table2);
+        }
+
+        writeHandler.afterAll();
+    }
+
+    @ParameterizedTest
+    @ExcelFormatSource(value = FormatScope.BINARY)
+    void complexMultiSheetAndMultiTableWrites(ExcelFormat format) throws 
Exception {
+        File file = createTempFile(format);
+        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(SimpleData.class)
+                .includeColumnFieldNames(Collections.singletonList("name"))
+                .registerWriteHandler(writeHandler)
+                .build()) {
+
+            WriteSheet writeSheet1 =
+                    FesodSheet.writerSheet(0).needHead(Boolean.FALSE).build();
+
+            writer.write(
+                    TestDataBuilder.simpleData(1),
+                    writeSheet1,
+                    FesodSheet.writerTable(0).needHead(Boolean.TRUE).build());
+            writer.write(
+                    TestDataBuilder.simpleData(1),
+                    writeSheet1,
+                    FesodSheet.writerTable(1).needHead(Boolean.TRUE).build());
+
+            WriteSheet writeSheet2 =
+                    FesodSheet.writerSheet(1).needHead(Boolean.FALSE).build();
+
+            writer.write(
+                    TestDataBuilder.simpleData(1),
+                    writeSheet2,
+                    FesodSheet.writerTable(0).needHead(Boolean.TRUE).build());
+            writer.write(
+                    TestDataBuilder.simpleData(1),
+                    writeSheet2,
+                    FesodSheet.writerTable(1).needHead(Boolean.TRUE).build());
+        }
+
+        writeHandler.afterAll();
+    }
+
+    @ParameterizedTest
+    @ExcelFormatSource(value = FormatScope.BINARY, requires = 
FormatCapability.TEMPLATES)
+    void sheetFills(ExcelFormat format) throws Exception {
+        File file = createTempFile(format);
+        File template = readFile("fill" + File.separator + "fillHandler" + 
(format == ExcelFormat.XLSX ? "07" : "03")
+                + format.getExtension());
+        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<String, String> data1 = new HashMap<>();
+            data1.put("name", "Tom");
+
+            Map<String, String> data2 = new HashMap<>();
+            data2.put("code", "Custom Code");
+
+            writer.fill(data1, writeSheet);
+            writer.fill(data2, writeSheet);
+        }
+
+        writeHandler.afterAll();
+    }
+
+    @ParameterizedTest
+    @ExcelFormatSource(value = FormatScope.BINARY)
+    void multiSheetWrites(ExcelFormat format) throws Exception {
+        File file = createTempFile(format);
+        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(SimpleData.class)
+                .includeColumnFieldNames(Collections.singletonList("name"))
+                .registerWriteHandler(writeHandler)
+                .build()) {
+
+            WriteSheet writeSheet1 =
+                    FesodSheet.writerSheet(0).needHead(Boolean.TRUE).build();
+            writer.write(TestDataBuilder.simpleData(1), writeSheet1);
+
+            WriteSheet writeSheet2 =
+                    FesodSheet.writerSheet(1).needHead(Boolean.TRUE).build();
+            writer.write(TestDataBuilder.simpleData(1), writeSheet2);
+        }
+
+        writeHandler.afterAll();
+    }
+
+    @ParameterizedTest
+    @ExcelFormatSource(value = FormatScope.BINARY, requires = 
FormatCapability.TEMPLATES)
+    void multiSheetFills(ExcelFormat format) throws Exception {
+        File file = createTempFile(format);
+        File template = readFile("fill" + File.separator + "fillHandler" + 
(format == ExcelFormat.XLSX ? "07" : "03")
+                + format.getExtension());
+        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<String, String> data1 = new HashMap<>();
+            data1.put("name", "Tom");
+            Map<String, String> data2 = new HashMap<>();
+            data2.put("code", "Code1");
+            writer.fill(data1, writeSheet0);
+            writer.fill(data2, writeSheet0);
+
+            WriteSheet writeSheet1 = FesodSheet.writerSheet(1).build();
+            Map<String, String> data3 = new HashMap<>();
+            data3.put("name", "Jerry");
+            Map<String, String> data4 = new HashMap<>();
+            data4.put("code", "Code2");
+            writer.fill(data3, writeSheet1);
+            writer.fill(data4, writeSheet1);
+        }
+
+        writeHandler.afterAll();
+    }
+
+    @ParameterizedTest
+    @ExcelFormatSource(value = FormatScope.BINARY)
+    void multiSheetLevelHandlerWrites(ExcelFormat format) throws Exception {
+        File file = createTempFile(format);
+        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(SimpleData.class)
+                .includeColumnFieldNames(Collections.singletonList("name"))
+                .build()) {
+
+            WriteSheet writeSheet1 = FesodSheet.writerSheet(0)
+                    .needHead(Boolean.TRUE)
+                    .registerWriteHandler(writeHandler1)
+                    .build();
+            writer.write(TestDataBuilder.simpleData(1), writeSheet1);
+
+            WriteSheet writeSheet2 = FesodSheet.writerSheet(1)
+                    .needHead(Boolean.TRUE)
+                    .registerWriteHandler(writeHandler2)
+                    .build();
+            writer.write(TestDataBuilder.simpleData(1), writeSheet2);
+        }
+
+        writeHandler1.afterAll();
+        writeHandler2.afterAll();
+    }
 }
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 17792ec4..176c5576 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
@@ -251,17 +251,21 @@ class WriteHandlerUtilsTest {
 
     @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 00000000..176acb9d
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 00000000..fb83f759
Binary files /dev/null and 
b/fesod-sheet/src/test/resources/fill/fillHandler07.xlsx differ


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to