diff --git a/fesod-sheet/src/main/java/org/apache/fesod/sheet/metadata/AbstractParameterBuilder.java b/fesod-sheet/src/main/java/org/apache/fesod/sheet/metadata/AbstractParameterBuilder.java index 32a245518..c314b34e4 100644 --- a/fesod-sheet/src/main/java/org/apache/fesod/sheet/metadata/AbstractParameterBuilder.java +++ b/fesod-sheet/src/main/java/org/apache/fesod/sheet/metadata/AbstractParameterBuilder.java @@ -19,6 +19,7 @@ package org.apache.fesod.sheet.metadata; +import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Objects; @@ -39,10 +40,27 @@ public abstract class AbstractParameterBuilder> head) { - parameter().setHead(head); + parameter().setHead(toMutableListIfNecessary(head)); return self(); } + /** + * Ensures and returns a mutable head list. + * + * @param head The source list to create a mutable from. + * @return A new mutable list, or the original list if the input is null or empty. + */ + private List> toMutableListIfNecessary(List> head) { + if (null == head || head.isEmpty()) { + return head; + } + List> result = new ArrayList<>(); + for (List headColumn : head) { + result.add(new ArrayList<>(headColumn)); + } + return result; + } + /** * You can only choose one of the {@link #head(List)} and {@link #head(Class)} * diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataListener.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataListener.java new file mode 100644 index 000000000..e8c341e60 --- /dev/null +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataListener.java @@ -0,0 +1,64 @@ +/* + * 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.head; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import org.apache.fesod.sheet.context.AnalysisContext; +import org.apache.fesod.sheet.metadata.data.ReadCellData; +import org.apache.fesod.sheet.read.listener.ReadListener; +import org.junit.jupiter.api.Assertions; + +public class ImmutableListHeadDataListener implements ReadListener> { + + private List> list = new ArrayList>(); + + @Override + public void invokeHead(Map> headMap, AnalysisContext context) { + Assertions.assertNotNull(context.readRowHolder().getRowIndex()); + headMap.forEach((key, value) -> { + Assertions.assertEquals(value.getRowIndex(), context.readRowHolder().getRowIndex()); + Assertions.assertEquals(value.getColumnIndex(), key); + }); + } + + @Override + public void invoke(Map data, AnalysisContext context) { + list.add(data); + } + + @Override + public void doAfterAllAnalysed(AnalysisContext context) { + List> head = context.readSheetHolder().getHead(); + + Assertions.assertInstanceOf(ArrayList.class, head); + for (List item : head) { + Assertions.assertInstanceOf(ArrayList.class, item); + } + + Assertions.assertEquals(1, list.size()); + Map data = list.get(0); + Assertions.assertEquals("stringData", data.get(0)); + Assertions.assertEquals("1", data.get(1)); + Assertions.assertEquals("2025-10-31 01:01:01", data.get(2)); + Assertions.assertEquals("extraData", data.get(3)); + } +} diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataTest.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataTest.java new file mode 100644 index 000000000..e97741aa2 --- /dev/null +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataTest.java @@ -0,0 +1,102 @@ +/* + * 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.head; + +import java.io.File; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.apache.fesod.sheet.FastExcel; +import org.apache.fesod.sheet.util.DateUtils; +import org.apache.fesod.sheet.util.TestFileUtil; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; + +@TestMethodOrder(MethodOrderer.MethodName.class) +public class ImmutableListHeadDataTest { + + private static File file07; + private static File file03; + private static File fileCsv; + + @BeforeAll + public static void init() { + file07 = TestFileUtil.createNewFile("listHead07.xlsx"); + file03 = TestFileUtil.createNewFile("listHead03.xls"); + fileCsv = TestFileUtil.createNewFile("listHeadCsv.csv"); + } + + @Test + public void t01ReadAndWrite07() throws Exception { + readAndWrite(file07); + } + + @Test + public void t02ReadAndWrite03() throws Exception { + readAndWrite(file03); + } + + @Test + public void t03ReadAndWriteCsv() throws Exception { + readAndWrite(fileCsv); + } + + private void readAndWrite(File file) throws Exception { + FastExcel.write(file) + .head(head()) + .registerWriteHandler(new ImmutableListHeadDataWriteHandler()) + .sheet() + .doWrite(data()); + + FastExcel.read(file) + .head(head()) + .registerReadListener(new ImmutableListHeadDataListener()) + .sheet() + .doRead(); + } + + private List> head() { + List> list = new ArrayList>(); + List head0 = Arrays.asList("stringTitle"); + List head1 = new ArrayList(); + head1.add("numberTitle1"); + head1.add("numberTitle2"); + + list.add(head0); + list.add(Collections.unmodifiableList(head1)); + list.add(Collections.singletonList("datetimeTitle")); + return list; + } + + private List> data() throws ParseException { + List> list = new ArrayList>(); + List data0 = new ArrayList(); + data0.add("stringData"); + data0.add(1); + data0.add(DateUtils.parseDate("2025-10-31 01:01:01")); + data0.add("extraData"); + list.add(data0); + return list; + } +} diff --git a/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataWriteHandler.java b/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataWriteHandler.java new file mode 100644 index 000000000..3975a32f6 --- /dev/null +++ b/fesod-sheet/src/test/java/org/apache/fesod/sheet/head/ImmutableListHeadDataWriteHandler.java @@ -0,0 +1,39 @@ +/* + * 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.head; + +import java.util.ArrayList; +import java.util.List; +import org.apache.fesod.sheet.write.handler.SheetWriteHandler; +import org.apache.fesod.sheet.write.handler.context.SheetWriteHandlerContext; +import org.junit.jupiter.api.Assertions; + +public class ImmutableListHeadDataWriteHandler implements SheetWriteHandler { + + @Override + public void afterSheetDispose(SheetWriteHandlerContext context) { + List> head = context.getWriteContext().writeSheetHolder().getHead(); + + Assertions.assertInstanceOf(ArrayList.class, head); + for (List item : head) { + Assertions.assertInstanceOf(ArrayList.class, item); + } + } +}