diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 7348fb743..d642d931e 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -15,7 +15,7 @@ Apache Fesod (Incubating) is a Java library for processing spreadsheets (XLS/XLS ./mvnw clean install -DskipTests # Run tests (must explicitly enable) -./mvnw clean package -Dmaven.test.skip=false -pl fesod-common,fesod-shaded,fesod-sheet,fesod-examples/fesod-sheet-examples +./mvnw clean package -Dmaven.test.skip=false -pl fesod-common,fesod-shaded,fesod-sheet # Format check / auto-format ./mvnw spotless:check @@ -46,21 +46,21 @@ Apache Fesod (Incubating) is a Java library for processing spreadsheets (XLS/XLS ├── fesod-common/ # Zero-dependency utilities (org.apache.fesod.common.util) ├── fesod-shaded/ # Relocated Spring ASM/cglib (org.apache.fesod.shaded) ├── fesod-bom/ # BOM for downstream consumers -├── fesod-sheet/ # Core library: read/write XLS/XLSX/CSV via POI -│ ├── src/main/java/org/apache/fesod/sheet/ -│ │ ├── FesodSheet.java # Main entry: FesodSheet.read() / FesodSheet.write() -│ │ ├── analysis/ # Read pipeline (v03=XLS BIFF, v07=XLSX SAX, csv) -│ │ ├── write/ # Write pipeline (builder, executor, handler chains) -│ │ ├── metadata/ # Data models, builders, csv/ property/ -│ │ ├── converters/ # Type conversion framework (by Java type) -│ │ └── util/ # DateUtils, NumberUtils, WorkBookUtil, etc. -│ └── src/test/java/org/apache/fesod/sheet/ -│ └── testkit/ # Test infrastructure (NOT a separate module) -│ ├── Tags.java # @Tag constants: unit, round-trip, read, write, format, fuzz -│ ├── base/ # AbstractExcelTest (round-trip base) -│ ├── assertions/ # ExcelAssertions fluent API -│ └── builders/ # TestDataBuilder -└── fesod-examples/ # Usage examples +└── fesod-sheet/ # Core library: read/write XLS/XLSX/CSV via POI + ├── src/main/java/org/apache/fesod/sheet/ + │ ├── FesodSheet.java # Main entry: FesodSheet.read() / FesodSheet.write() + │ ├── analysis/ # Read pipeline (v03=XLS BIFF, v07=XLSX SAX, csv) + │ ├── write/ # Write pipeline (builder, executor, handler chains) + │ ├── metadata/ # Data models, builders, csv/ property/ + │ ├── converters/ # Type conversion framework (by Java type) + │ └── util/ # DateUtils, NumberUtils, WorkBookUtil, etc. + └── src/test/java/org/apache/fesod/sheet/ + └── testkit/ # Test infrastructure (NOT a separate module) + ├── Tags.java # @Tag constants: unit, round-trip, read, write, format, fuzz + ├── base/ # AbstractExcelTest (round-trip base) + ├── assertions/ # ExcelAssertions fluent API + └── builders/ # TestDataBuilder + ``` ## Testing Conventions diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f48f76c16..065e9c6e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -86,7 +86,7 @@ jobs: restore-keys: | ${{ runner.os }}-m2 - name: Test with Maven - run: ./mvnw clean package -B -Dmaven.test.skip=false -pl fesod-common,fesod-shaded,fesod-sheet,fesod-examples/fesod-sheet-examples + run: ./mvnw clean package -B -Dmaven.test.skip=false -pl fesod-common,fesod-shaded,fesod-sheet - name: Publish Unit Test Results uses: EnricoMi/publish-unit-test-result-action@v2 if: (!cancelled()) diff --git a/fesod-examples/fesod-sheet-examples/pom.xml b/fesod-examples/fesod-sheet-examples/pom.xml deleted file mode 100644 index 3c01afb2b..000000000 --- a/fesod-examples/fesod-sheet-examples/pom.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - - 4.0.0 - - - org.apache.fesod - fesod-examples - ${revision} - - - fesod-sheet-examples - jar - Fesod Sheet Examples - - - false - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - **/*Test.java - **/*ITCase.java - - - 1 - false - - - - - - - - - org.apache.fesod - fesod-sheet - ${project.version} - - - - ch.qos.logback - logback-classic - ${logback-classic.version} - - - - org.apache.logging.log4j - log4j-to-slf4j - - - - com.alibaba.fastjson2 - fastjson2 - - - - org.springframework.boot - spring-boot-starter-web - - - - org.junit.jupiter - junit-jupiter - test - - - - org.springframework.boot - spring-boot-starter-test - test - - - diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/CustomConverterExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/CustomConverterExample.java deleted file mode 100644 index dc4e1f798..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/CustomConverterExample.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * 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.examples.advanced; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.context.AnalysisContext; -import org.apache.fesod.sheet.examples.advanced.converter.CustomStringStringConverter; -import org.apache.fesod.sheet.examples.advanced.data.CustomConverterData; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; -import org.apache.fesod.sheet.read.listener.ReadListener; - -/** - * Demonstrates registering a custom converter at the builder level for read and write. - * - *

Scenario

- *

You need the same data transformation applied to ALL fields of a matching type, - * not just a specific annotated field. For example, adding a "Custom:" prefix to every - * string column, or encrypting/decrypting all string values.

- * - *

Key Concepts: Per-Field vs. Global Converter Registration

- * - * - * - * - * - * - * - * - * - * - * - * - *
ApproachScopeHow
Per-fieldSingle field only{@code @ExcelProperty(converter = MyConverter.class)}
Global (this example)All fields matching Java type + Excel type{@code .registerConverter(new MyConverter())} on the builder
- * - *

How It Works

- *
    - *
  1. Write: The {@link CustomStringStringConverter} is registered on the write builder. - * During write, every {@code String} field is transformed (prefixed with "Custom:").
  2. - *
  3. Read: The same converter is registered on the read builder. - * During read, every string cell is transformed back through the converter.
  4. - *
- * - *

Converter Resolution Priority

- *
- * 1. Field-level converter (@ExcelProperty(converter = ...))  ← highest
- * 2. Builder-level converter (.registerConverter(...))         ← this example
- * 3. Built-in default converter                                ← lowest
- * 
- * - *

Related Examples

- * - * - * @see CustomStringStringConverter - * @see org.apache.fesod.sheet.converters.Converter - */ -@Slf4j -public class CustomConverterExample { - - public static void main(String[] args) { - String fileName = ExampleFileUtil.getTempPath("customConverter" + System.currentTimeMillis() + ".xlsx"); - customConverterWrite(fileName); - customConverterRead(fileName); - } - - /** - * Writes data with a globally registered converter that prefixes all string values. - * - *

The {@link CustomStringStringConverter} transforms "String0" → "Custom:String0" - * for every string field in the data model.

- */ - public static void customConverterWrite(String fileName) { - FesodSheet.write(fileName, CustomConverterData.class) - .registerConverter(new CustomStringStringConverter()) - .sheet("CustomConverter") - .doWrite(data()); - log.info("Successfully wrote file with custom converter: {}", fileName); - } - - /** - * Reads the previously written file with the same converter registered. - * - *

The converter's {@code convertToJavaData()} method is applied during read, - * transforming cell values as they are parsed.

- */ - public static void customConverterRead(String fileName) { - FesodSheet.read(fileName, CustomConverterData.class, new ReadListener() { - @Override - public void invoke(CustomConverterData data, AnalysisContext context) { - log.info("Read data with custom converter: {}", data); - } - - @Override - public void doAfterAllAnalysed(AnalysisContext context) { - log.info("Custom converter read completed"); - } - }) - .registerConverter(new CustomStringStringConverter()) - .sheet() - .doRead(); - } - - private static List data() { - List list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - CustomConverterData data = new CustomConverterData(); - data.setString("String" + i); - data.setDate(new Date()); - data.setDoubleData(0.56); - list.add(data); - } - return list; - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/LargeFileWriteExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/LargeFileWriteExample.java deleted file mode 100644 index d6bd78327..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/LargeFileWriteExample.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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.examples.advanced; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.ExcelWriter; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; -import org.apache.fesod.sheet.examples.write.data.DemoData; -import org.apache.fesod.sheet.util.FileUtils; -import org.apache.fesod.sheet.write.handler.WorkbookWriteHandler; -import org.apache.fesod.sheet.write.handler.context.WorkbookWriteHandlerContext; -import org.apache.fesod.sheet.write.metadata.WriteSheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.streaming.SXSSFWorkbook; - -/** - * Demonstrates writing very large Excel files (100,000+ rows) with memory optimization. - * - *

Scenario

- *

You need to export a large dataset (e.g., database dump, log analysis) that would - * exhaust memory if all rows were held at once. Fesod uses Apache POI's streaming - * API (SXSSF) internally, but temporary XML files can consume significant disk space.

- * - *

Key Optimization: Temporary File Compression

- *

When POI writes large XLSX files, it creates temporary XML files on disk - * (one per sheet). These can be several times larger than the final file. - * Enabling compression via {@code setCompressTempFiles(true)} significantly reduces - * disk usage at the cost of slightly more CPU.

- * - *

Architecture

- *
- * Data (in memory, batched)        Fesod          POI/SXSSF
- *     │                              │                 │
- *     ├─ 100 rows batch ───────────▶ write() ──────▶ temp XML (compressed)
- *     ├─ 100 rows batch ───────────▶ write() ──────▶ temp XML (append)
- *     │  ... (1000 batches)           │                 │
- *     └─ close() ──────────────────▶ finalize ─────▶ final .xlsx
- * 
- * - *

Performance Tips

- *
    - *
  • Use {@code ExcelWriter} (try-with-resources) for batch writing instead of - * loading all data with {@code doWrite()}.
  • - *
  • Enable temp file compression for disk-constrained environments.
  • - *
  • Tune batch size (100 rows here) based on your row width and available memory.
  • - *
  • Monitor temp directory size: {@code FileUtils.getPoiFilesPath()}.
  • - *
- * - *

Expected Result

- *

Writes 100,000 rows (1000 batches x 100 rows) to a single sheet without - * OutOfMemoryError, using compressed temp files on disk.

- * - *

Related Examples

- *
    - *
  • {@link org.apache.fesod.sheet.examples.write.BasicWriteExample} — Simple small-file write.
  • - *
- * - * @see ExcelWriter - * @see org.apache.poi.xssf.streaming.SXSSFWorkbook#setCompressTempFiles(boolean) - */ -@Slf4j -public class LargeFileWriteExample { - - public static void main(String[] args) { - compressedTemporaryFile(); - } - - /** - * Writes 100,000 rows in batches with compressed temporary files. - * - *

Uses a {@link WorkbookWriteHandler} to access the underlying POI - * {@link SXSSFWorkbook} and enable temp file compression. Writing is done - * in 1,000 batches of 100 rows each via the {@link ExcelWriter} API.

- */ - public static void compressedTemporaryFile() { - log.info("Temporary XML files are stored at: {}", FileUtils.getPoiFilesPath()); - String fileName = ExampleFileUtil.getTempPath("largeFile" + System.currentTimeMillis() + ".xlsx"); - - try (ExcelWriter excelWriter = FesodSheet.write(fileName, DemoData.class) - .registerWriteHandler(new WorkbookWriteHandler() { - @Override - public void afterWorkbookCreate(WorkbookWriteHandlerContext context) { - Workbook workbook = context.getWriteWorkbookHolder().getWorkbook(); - if (workbook instanceof SXSSFWorkbook) { - // Enable temporary file compression. - ((SXSSFWorkbook) workbook).setCompressTempFiles(true); - } - } - }) - .build()) { - WriteSheet writeSheet = FesodSheet.writerSheet("Template").build(); - // Write 100,000 rows in batches. - for (int i = 0; i < 1000; i++) { - excelWriter.write(data(), writeSheet); - } - } - log.info("Successfully wrote large file: {}", fileName); - } - - private static List data() { - List list = new ArrayList<>(); - for (int i = 0; i < 100; i++) { - DemoData data = new DemoData(); - data.setString("String" + i); - data.setDate(new Date()); - data.setDoubleData(0.56); - list.add(data); - } - return list; - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/PasswordProtectionExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/PasswordProtectionExample.java deleted file mode 100644 index 572609433..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/PasswordProtectionExample.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 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.examples.advanced; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.context.AnalysisContext; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; -import org.apache.fesod.sheet.examples.write.data.DemoData; -import org.apache.fesod.sheet.read.listener.ReadListener; - -/** - * Demonstrates reading and writing password-protected Excel files. - * - *

Scenario

- *

You need to protect sensitive data (financial reports, personal information) - * with Excel's built-in password encryption. Fesod supports both writing encrypted - * files and reading them with the correct password.

- * - *

Key Concepts

- *
    - *
  • {@code .password("xxx")} — Available on both read and write builders. - * For write, it encrypts the output file. For read, it decrypts the input file.
  • - *
  • Uses Excel's native encryption (AES for .xlsx), compatible with all Excel versions.
  • - *
  • Without the correct password, reading will throw an - * {@code EncryptedDocumentException}.
  • - *
- * - *

Usage

- *
{@code
- * // Write with password
- * FesodSheet.write(fileName).password("secret").head(MyData.class).sheet().doWrite(data);
- *
- * // Read with password
- * FesodSheet.read(fileName, MyData.class, listener).password("secret").sheet().doRead();
- * }
- * - *

Security Notes

- *
    - *
  • Excel password protection encrypts the file content, making it unreadable - * without the password.
  • - *
  • In production, avoid hardcoding passwords — use configuration or secrets management.
  • - *
- * - *

Related Examples

- *
    - *
  • {@link org.apache.fesod.sheet.examples.write.BasicWriteExample} — Write without encryption.
  • - *
  • {@link org.apache.fesod.sheet.examples.read.BasicReadExample} — Read without encryption.
  • - *
- * - * @see FesodSheet#write(String) - * @see FesodSheet#read(String, Class, org.apache.fesod.sheet.read.listener.ReadListener) - */ -@Slf4j -public class PasswordProtectionExample { - - public static void main(String[] args) { - String fileName = ExampleFileUtil.getTempPath("password" + System.currentTimeMillis() + ".xlsx"); - String password = "password123"; - - log.info("Starting password protection example..."); - passwordWrite(fileName, password); - passwordRead(fileName, password); - } - - /** - * Writes an Excel file encrypted with the given password. - * - *

The output file can only be opened in Excel (or read by Fesod) with - * the matching password. The encryption is applied at the file level.

- * - * @param fileName output file path - * @param password encryption password - */ - public static void passwordWrite(String fileName, String password) { - FesodSheet.write(fileName) - .password(password) - .head(DemoData.class) - .sheet("PasswordSheet") - .doWrite(data()); - log.info("Successfully wrote password-protected file: {}", fileName); - } - - /** - * Reads a password-protected Excel file. - * - *

The password must match the one used during write. If incorrect, - * an {@code EncryptedDocumentException} will be thrown.

- * - * @param fileName input file path - * @param password decryption password - */ - public static void passwordRead(String fileName, String password) { - FesodSheet.read(fileName, DemoData.class, new ReadListener() { - @Override - public void invoke(DemoData data, AnalysisContext context) { - log.info("Read password-protected data: {}", data); - } - - @Override - public void doAfterAllAnalysed(AnalysisContext context) { - log.info("Password-protected file read completed"); - } - }) - .password(password) - .sheet() - .doRead(); - } - - private static List data() { - List list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - DemoData data = new DemoData(); - data.setString("String" + i); - data.setDate(new Date()); - data.setDoubleData(0.56); - list.add(data); - } - return list; - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/converter/CustomStringStringConverter.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/converter/CustomStringStringConverter.java deleted file mode 100644 index eeaded15f..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/converter/CustomStringStringConverter.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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.examples.advanced.converter; - -import org.apache.fesod.sheet.converters.Converter; -import org.apache.fesod.sheet.enums.CellDataTypeEnum; -import org.apache.fesod.sheet.metadata.GlobalConfiguration; -import org.apache.fesod.sheet.metadata.data.ReadCellData; -import org.apache.fesod.sheet.metadata.data.WriteCellData; -import org.apache.fesod.sheet.metadata.property.ExcelContentProperty; - -/** - * Custom String-to-String converter that adds a "Custom:" prefix during both read and write. - * - *

Conversion Behavior

- *
- * Read:  Excel cell "Hello"  →  Java string "Custom:Hello"
- * Write: Java string "Hello" →  Excel cell "Custom:Hello"
- * 
- * - *

Difference from Read Converter

- *

Unlike {@link org.apache.fesod.sheet.examples.read.converters.CustomStringStringConverter} - * (which uses the newer {@code ReadConverterContext}/{@code WriteConverterContext} API), - * this converter uses the legacy method signatures with - * {@link ExcelContentProperty} and {@link GlobalConfiguration} parameters. - * Both approaches are supported by Fesod.

- * - *

API Versions

- * - * - * - * - * - * - * - * - * - * - * - * - *
StyleMethod SignatureUsed By
New (recommended){@code convertToJavaData(ReadConverterContext)}read/converters/ package
Legacy (still supported){@code convertToJavaData(ReadCellData, ExcelContentProperty, GlobalConfiguration)}this class
- * - * @see Converter - * @see org.apache.fesod.sheet.examples.advanced.CustomConverterExample - */ -public class CustomStringStringConverter implements Converter { - - @Override - public Class supportJavaTypeKey() { - return String.class; - } - - @Override - public CellDataTypeEnum supportExcelTypeKey() { - return CellDataTypeEnum.STRING; - } - - @Override - public String convertToJavaData( - ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return "Custom:" + cellData.getStringValue(); - } - - @Override - public WriteCellData convertToExcelData( - String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) { - return new WriteCellData<>("Custom:" + value); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/data/CustomConverterData.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/data/CustomConverterData.java deleted file mode 100644 index d7aa09113..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/advanced/data/CustomConverterData.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.advanced.data; - -import java.util.Date; -import lombok.Data; -import org.apache.fesod.sheet.annotation.ExcelProperty; -import org.apache.fesod.sheet.annotation.format.DateTimeFormat; -import org.apache.fesod.sheet.annotation.format.NumberFormat; -import org.apache.fesod.sheet.examples.advanced.converter.CustomStringStringConverter; - -/** - * Data model demonstrating three types of data conversion during Excel read/write. - * - *

This class uses a custom converter, a date format annotation, and a number format - * annotation to control how Excel cell values are converted to and from Java objects.

- * - *

Conversion Mapping

- *
- * Field      | Type   | Annotation / Converter                    | Excel Cell → Java Value
- * ───────────|────────|───────────────────────────────────────────|────────────────────────
- * string     | String | @ExcelProperty(converter=Custom...)        | "Hello" → "Custom:Hello"
- * date       | Date   | @DateTimeFormat("yyyy-MM-dd HH:mm:ss")    | 2025-01-01 → Date object
- * doubleData | Double | @NumberFormat("#.##%")                     | 0.56 → 0.56 (displayed as "56%")
- * 
- * - *

Converter Types

- *
    - *
  • Custom converter ({@link CustomStringStringConverter}) — Implements - * {@link org.apache.fesod.sheet.converters.Converter} for full control over the - * transformation logic. Applied via {@code @ExcelProperty(converter = ...)}.
  • - *
  • Date format ({@code @DateTimeFormat}) — Specifies the date pattern used - * when converting between Excel date cells and {@link java.util.Date} objects.
  • - *
  • Number format ({@code @NumberFormat}) — Specifies the number pattern used - * when converting between Excel numeric cells and {@link Double} values.
  • - *
- * - * @see CustomStringStringConverter - * @see DateTimeFormat - * @see NumberFormat - */ -@Data -public class CustomConverterData { - - /** - * Custom converter. - */ - @ExcelProperty(converter = CustomStringStringConverter.class) - private String string; - - /** - * Date format. - */ - @DateTimeFormat("yyyy-MM-dd HH:mm:ss") - private Date date; - - /** - * Number format. - */ - @NumberFormat("#.##%") - private Double doubleData; -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/fill/FillBasicExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/fill/FillBasicExample.java deleted file mode 100644 index 7d876cc21..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/fill/FillBasicExample.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.fill; - -import java.io.File; -import java.util.HashMap; -import java.util.Map; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.fill.data.FillData; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; - -/** - * Demonstrates filling data into a pre-designed Excel template with placeholders. - * - *

Scenario

- *

You have a pre-formatted Excel template (designed by a non-developer) with - * placeholder variables like {@code {name}} and {@code {number}}. You want to fill in - * actual data at runtime without rebuilding the layout programmatically.

- * - *

Template Format

- *

The template file ({@code templates/simple.xlsx}) contains cells with placeholders:

- *
- * Template:        | Name: {name}  | Score: {number} |
- *                       ↓                  ↓
- * Filled result:   | Name: Zhang San | Score: 5.2 |
- * 
- * - *

Two Data Sources

- *
    - *
  • Object-based — Create a {@link FillData} object. Fesod maps field names - * to template placeholders automatically.
  • - *
  • Map-based — Use a {@code Map} where keys match placeholder names. - * Useful when the structure is dynamic or you don't want to create a POJO.
  • - *
- * - *

Placeholder Syntax

- *
    - *
  • {@code {fieldName}} — Replaced by a single value (for simple fills).
  • - *
  • {@code {.fieldName}} — Replaced by a list of values (for list fills, - * see {@link FillComplexExample}).
  • - *
- * - *

When to Use Fill vs. Write

- *
    - *
  • Fill — When you have a pre-designed template with specific formatting, - * merged cells, formulas, charts, or complex layouts.
  • - *
  • Write — When generating a simple tabular report from scratch.
  • - *
- * - *

Related Examples

- *
    - *
  • {@link FillComplexExample} — Fill templates with list data (multiple rows).
  • - *
  • {@link org.apache.fesod.sheet.examples.write.BasicWriteExample} — Write from scratch.
  • - *
- * - * @see FesodSheet#write(String) - * @see FillData - */ -@Slf4j -public class FillBasicExample { - - public static void main(String[] args) { - simpleFill(); - } - - /** - * Fills a simple template using both object-based and map-based data sources. - * - *

Demonstrates two equivalent approaches: - *

    - *
  1. Object fill — Uses a {@link FillData} POJO. The field names must match - * the placeholder names in the template.
  2. - *
  3. Map fill — Uses a {@code Map}. The map keys must match - * the placeholder names. More flexible for dynamic structures.
  4. - *
- * Both produce identical output files.

- */ - public static void simpleFill() { - String templateFileName = ExampleFileUtil.getExamplePath("templates" + File.separator + "simple.xlsx"); - - // Option 1: Fill based on an object - String fileName = ExampleFileUtil.getTempPath("simpleFill" + System.currentTimeMillis() + ".xlsx"); - FillData fillData = new FillData(); - fillData.setName("Zhang San"); - fillData.setNumber(5.2); - FesodSheet.write(fileName).withTemplate(templateFileName).sheet().doFill(fillData); - log.info("Successfully wrote file: {}", fileName); - - // Option 2: Fill based on a Map - fileName = ExampleFileUtil.getTempPath("simpleFillMap" + System.currentTimeMillis() + ".xlsx"); - Map map = new HashMap<>(); - map.put("name", "Zhang San"); - map.put("number", 5.2); - FesodSheet.write(fileName).withTemplate(templateFileName).sheet().doFill(map); - log.info("Successfully wrote file: {}", fileName); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/fill/FillComplexExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/fill/FillComplexExample.java deleted file mode 100644 index bd4f5c76c..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/fill/FillComplexExample.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.fill; - -import java.io.File; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.ExcelWriter; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.fill.data.FillData; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; -import org.apache.fesod.sheet.write.metadata.WriteSheet; - -/** - * Demonstrates filling list data into a template with repeating rows. - * - *

Scenario

- *

Your template has a list area that should expand with multiple rows of data — - * for example, an invoice with line items, or a report with multiple data rows. - * The template uses {@code {.fieldName}} (dot prefix) placeholders to mark the - * repeating area.

- * - *

Template Format

- *

The template file ({@code templates/list.xlsx}) contains a single row with - * list placeholders:

- *
- * Template:        | {.name}       | {.number} | {.date}     |
- *                       ↓               ↓           ↓
- * Filled result:   | Zhang San0    | 5.2       | 2025-01-01  |
- *                  | Zhang San1    | 5.2       | 2025-01-02  |
- *                  | ...           | ...       | ...         |
- * 
- * - *

Two Fill Strategies

- * - *

Strategy 1: Single-Pass Fill

- *

Load all data into memory and fill at once with {@code doFill(list)}. - * Simple but requires all data in memory.

- * - *

Strategy 2: Multi-Pass Fill (Memory-Efficient)

- *

Use {@link ExcelWriter} to fill in batches. Fesod uses file-based caching - * between passes, keeping memory usage low for large datasets.

- *
{@code
- * try (ExcelWriter writer = FesodSheet.write(fileName).withTemplate(template).build()) {
- *     WriteSheet sheet = FesodSheet.writerSheet().build();
- *     writer.fill(batch1, sheet);  // First batch
- *     writer.fill(batch2, sheet);  // Second batch
- * }
- * }
- * - *

Related Examples

- *
    - *
  • {@link FillBasicExample} — Simple single-value template fills.
  • - *
- * - * @see ExcelWriter#fill(Object, WriteSheet) - * @see FillData - */ -@Slf4j -public class FillComplexExample { - - public static void main(String[] args) { - listFill(); - } - - /** - * Fills a list template using both single-pass and multi-pass strategies. - * - *

Single-pass: All 10 rows loaded into memory, filled in one call.
- * Multi-pass: Two batches of 10 rows each, filled via {@link ExcelWriter} - * with file-backed caching for lower memory usage.

- */ - public static void listFill() { - String templateFileName = ExampleFileUtil.getExamplePath("templates" + File.separator + "list.xlsx"); - - // Option 1: Load all data into memory at once and fill - String fileName = ExampleFileUtil.getTempPath("listFill" + System.currentTimeMillis() + ".xlsx"); - FesodSheet.write(fileName).withTemplate(templateFileName).sheet().doFill(data()); - log.info("Successfully wrote file: {}", fileName); - - // Option 2: Fill in multiple passes, using file caching (saves memory) - fileName = ExampleFileUtil.getTempPath("listFillMultiple" + System.currentTimeMillis() + ".xlsx"); - try (ExcelWriter excelWriter = - FesodSheet.write(fileName).withTemplate(templateFileName).build()) { - WriteSheet writeSheet = FesodSheet.writerSheet().build(); - excelWriter.fill(data(), writeSheet); - excelWriter.fill(data(), writeSheet); - } - log.info("Successfully wrote file: {}", fileName); - } - - private static List data() { - List list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - FillData fillData = new FillData(); - fillData.setName("Zhang San" + i); - fillData.setNumber(5.2); - fillData.setDate(new Date()); - list.add(fillData); - } - return list; - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/fill/data/FillData.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/fill/data/FillData.java deleted file mode 100644 index 33efe388f..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/fill/data/FillData.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.fill.data; - -import java.util.Date; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -/** - * Data model for template fill operations. - * - *

Field names must exactly match the placeholder names in the Excel template. - * For example, if the template contains {@code {name}}, this class must have - * a field named {@code name} (or a getter {@code getName()}).

- * - *

Template Placeholder Mapping

- *
- * Template Placeholder → Java Field
- * ────────────────────────────────────
- * {name}    or {.name}   → name   (String)
- * {number}  or {.number} → number (double)
- * {date}    or {.date}   → date   (Date)
- * 
- * - *

{@code @ExcelProperty} annotations are NOT needed for fill operations — - * the mapping is by field name to placeholder name.

- * - * @see org.apache.fesod.sheet.examples.fill.FillBasicExample - * @see org.apache.fesod.sheet.examples.fill.FillComplexExample - */ -@Getter -@Setter -@EqualsAndHashCode -public class FillData { - private String name; - private double number; - private Date date; -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/quickstart/SimpleReadExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/quickstart/SimpleReadExample.java deleted file mode 100644 index 259adf557..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/quickstart/SimpleReadExample.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.quickstart; - -import com.alibaba.fastjson2.JSON; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.quickstart.data.DemoData; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; -import org.apache.fesod.sheet.read.listener.PageReadListener; - -/** - * The simplest way to read an Excel file with Apache Fesod. - * - *

Scenario

- *

You have an Excel file ({@code .xlsx} or {@code .xls}) and want to parse it into Java objects - * with minimal boilerplate. This is the recommended starting point for new users.

- * - *

Key Concepts

- *
    - *
  • {@link PageReadListener} — A built-in listener that collects rows into pages (default 100 rows per page) - * and delivers them via a lambda callback. Ideal for simple use cases.
  • - *
  • {@link DemoData} — A POJO annotated with {@link org.apache.fesod.sheet.annotation.ExcelProperty} - * to map Excel columns to Java fields by header name.
  • - *
  • Fesod reads row-by-row in a streaming fashion, so memory usage stays low even for large files.
  • - *
- * - *

Expected Behavior

- *

When run against the bundled {@code demo.xlsx}, each row is logged as a JSON string:

- *
{@code
- * Read a row of data: {"string":"String0","date":"2025-01-01","doubleData":0.56}
- * Read a row of data: {"string":"String1","date":"2025-01-02","doubleData":0.56}
- * ...
- * }
- * - *

Related Examples

- *
    - *
  • {@link org.apache.fesod.sheet.examples.read.BasicReadExample} — Uses a custom {@code ReadListener} - * with batch-save logic for production scenarios.
  • - *
  • {@link org.apache.fesod.sheet.examples.quickstart.SimpleWriteExample} — The write counterpart.
  • - *
- * - * @see FesodSheet#read(String, Class, org.apache.fesod.sheet.read.listener.ReadListener) - * @see PageReadListener - * @see DemoData - */ -@Slf4j -public class SimpleReadExample { - - public static void main(String[] args) { - simpleRead(); - } - - /** - * Reads an Excel file in three simple steps. - * - *
    - *
  1. Define a data model — Create a POJO with {@code @ExcelProperty} annotations - * (see {@link DemoData}).
  2. - *
  3. Provide a listener — {@link PageReadListener} buffers rows and delivers them - * in batches via a lambda. You can also implement {@link org.apache.fesod.sheet.read.listener.ReadListener} - * directly for full control.
  4. - *
  5. Call the builder — {@code FesodSheet.read(...).sheet().doRead()} starts - * the streaming parse, invoking your listener for each page of data.
  6. - *
- * - *

Note: The file is read in a streaming fashion. Once {@code doRead()} returns, - * all rows have been processed and resources are automatically released.

- */ - public static void simpleRead() { - String fileName = ExampleFileUtil.getExamplePath("demo.xlsx"); - log.info("Reading file: {}", fileName); - - // Specify the class to read the data, then read the first sheet. - FesodSheet.read(fileName, DemoData.class, new PageReadListener(dataList -> { - for (DemoData demoData : dataList) { - log.info("Read a row of data: {}", JSON.toJSONString(demoData)); - } - })) - .sheet() - .doRead(); - - log.info("Successfully read file: {}", fileName); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/quickstart/SimpleWriteExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/quickstart/SimpleWriteExample.java deleted file mode 100644 index df016d909..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/quickstart/SimpleWriteExample.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.quickstart; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.quickstart.data.DemoData; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; - -/** - * The simplest way to write an Excel file with Apache Fesod. - * - *

Scenario

- *

You have a list of Java objects and want to export them to an Excel file ({@code .xlsx}). - * This is the recommended starting point for new users who need to generate Excel reports.

- * - *

Key Concepts

- *
    - *
  • {@link FesodSheet#write(String, Class)} — Creates a write builder bound to a file path and data class.
  • - *
  • {@link DemoData} — A POJO annotated with {@link org.apache.fesod.sheet.annotation.ExcelProperty} - * to define column headers. Fields annotated with {@link org.apache.fesod.sheet.annotation.ExcelIgnore} - * are excluded from the output.
  • - *
  • {@code .sheet("Template")} — Names the worksheet tab in the output file.
  • - *
  • {@code .doWrite(data)} — Terminal operation that writes all data and closes the file.
  • - *
- * - *

Expected Output

- *

Generates an Excel file with headers derived from {@code @ExcelProperty} annotations:

- *
- * | String Title | Date Title          | Number Title |
- * |------------- |---------------------|--------------|
- * | String0      | 2025-01-01 00:00:00 | 0.56         |
- * | String1      | 2025-01-01 00:00:00 | 0.56         |
- * | ...          | ...                 | ...          |
- * 
- * - *

Related Examples

- *
    - *
  • {@link org.apache.fesod.sheet.examples.write.StyleWriteExample} — Customize header and content styles.
  • - *
  • {@link org.apache.fesod.sheet.examples.write.MergeWriteExample} — Merge cells during write.
  • - *
  • {@link org.apache.fesod.sheet.examples.quickstart.SimpleReadExample} — The read counterpart.
  • - *
- * - * @see FesodSheet#write(String, Class) - * @see DemoData - */ -@Slf4j -public class SimpleWriteExample { - - public static void main(String[] args) { - simpleWrite(); - } - - /** - * Writes a list of {@link DemoData} objects to an Excel file in two simple steps. - * - *
    - *
  1. Define a data model — Create a POJO with {@code @ExcelProperty} annotations - * (see {@link DemoData}). The annotation value becomes the column header.
  2. - *
  3. Call the builder — {@code FesodSheet.write(fileName, DemoData.class).sheet("name").doWrite(list)} - * generates the file. The builder handles file creation, header writing, and resource cleanup.
  4. - *
- * - *

Output location: The file is written to the system temp directory. - * Check the log output for the exact path.

- */ - public static void simpleWrite() { - // Write to system temp directory for output files - String fileName = ExampleFileUtil.getTempPath("demo" + System.currentTimeMillis() + ".xlsx"); - - // Specify the class to write, then write to the first sheet named "Template" - FesodSheet.write(fileName, DemoData.class).sheet("Template").doWrite(data()); - log.info("Successfully wrote file: {}", fileName); - } - - private static List data() { - List list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - DemoData data = new DemoData(); - data.setString("String" + i); - data.setDate(new Date()); - data.setDoubleData(0.56); - list.add(data); - } - return list; - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/quickstart/data/DemoData.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/quickstart/data/DemoData.java deleted file mode 100644 index 2a2299d05..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/quickstart/data/DemoData.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.quickstart.data; - -import java.util.Date; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import org.apache.fesod.sheet.annotation.ExcelIgnore; -import org.apache.fesod.sheet.annotation.ExcelProperty; - -/** - * Data model for the quickstart examples, mapping Java fields to Excel columns. - * - *

Column Mapping

- *

Each field annotated with {@link ExcelProperty} maps to an Excel column by header name. - * The generated Excel file will have these columns:

- *
- * | String Title | Date Title          | Number Title |
- * |------------- |---------------------|--------------|
- * | (string)     | (date)              | (doubleData) |
- * 
- * - *

Annotations Used

- *
    - *
  • {@link ExcelProperty} — Maps a field to an Excel column by header name or index.
  • - *
  • {@link ExcelIgnore} — Excludes a field from both reading and writing. - * Useful for internal/transient fields like IDs or computed values.
  • - *
- * - *

Supported Field Types

- *

Fesod automatically converts between Excel cell types and common Java types: - * {@code String}, {@code Date}, {@code Double}, {@code Integer}, {@code BigDecimal}, etc. - * For custom conversions, see - * {@link org.apache.fesod.sheet.examples.read.data.ConverterData}.

- * - * @see ExcelProperty - * @see ExcelIgnore - */ -@Getter -@Setter -@EqualsAndHashCode -public class DemoData { - /** - * String Title - */ - @ExcelProperty("String Title") - private String string; - - /** - * Date Title - */ - @ExcelProperty("Date Title") - private Date date; - - /** - * Number Title - */ - @ExcelProperty("Number Title") - private Double doubleData; - - /** - * Ignore this field - */ - @ExcelIgnore - private String ignore; -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/BasicReadExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/BasicReadExample.java deleted file mode 100644 index 20c72071b..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/BasicReadExample.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read; - -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.read.data.DemoData; -import org.apache.fesod.sheet.examples.read.listeners.DemoDataListener; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; - -/** - * Demonstrates the standard pattern for reading Excel files with a custom {@link DemoDataListener}. - * - *

Scenario

- *

You need to read an Excel file and process rows in batches (e.g., inserting into a database - * every 100 rows). This is the production-recommended pattern for reading Excel files with Fesod.

- * - *

Key Concepts

- *
    - *
  • {@link DemoDataListener} — A custom {@link org.apache.fesod.sheet.read.listener.ReadListener} - * that implements batch caching and database persistence. See the listener class for - * the full lifecycle details.
  • - *
  • {@link DemoData} — POJO model class mapping Excel columns via {@code @ExcelProperty}.
  • - *
  • Unlike {@link org.apache.fesod.sheet.examples.quickstart.SimpleReadExample} which uses - * the convenience {@code PageReadListener}, this approach gives full control over - * the row processing lifecycle.
  • - *
- * - *

Listener Lifecycle

- *
- * File opened
- *     │
- *     ├─ invoke(data, context)       ← called for each data row
- *     │   └─ batch save every 100 rows
- *     │
- *     └─ doAfterAllAnalysed(context) ← called once after last row
- *         └─ final batch save
- * 
- * - *

Expected Behavior

- *

Each row is logged as JSON. Every 100 rows (or at end of file), a batch save is triggered.

- * - *

Related Examples

- *
    - *
  • {@link org.apache.fesod.sheet.examples.quickstart.SimpleReadExample} — Simpler lambda-based approach.
  • - *
  • {@link ConverterReadExample} — Read with data format conversion.
  • - *
  • {@link MultiSheetReadExample} — Read multiple sheets from one file.
  • - *
- * - * @see DemoDataListener - * @see org.apache.fesod.sheet.read.listener.ReadListener - */ -@Slf4j -public class BasicReadExample { - - public static void main(String[] args) { - basicRead(); - } - - /** - * Reads an Excel file using a custom {@link DemoDataListener}. - * - *

The listener handles row-by-row processing with batch persistence. - * A new listener instance is created per read operation to avoid shared state issues.

- * - *

Important: Never reuse a listener instance across multiple read operations - * or make it a Spring singleton — it holds mutable state (the cached data list).

- */ - public static void basicRead() { - String fileName = ExampleFileUtil.getExamplePath("demo.xlsx"); - log.info("Reading file: {}", fileName); - - // Specify the class to read the data, then read the first sheet. - FesodSheet.read(fileName, DemoData.class, new DemoDataListener()) - .sheet() - .doRead(); - - log.info("Successfully read file: {}", fileName); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/ConverterReadExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/ConverterReadExample.java deleted file mode 100644 index 4a7114c3a..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/ConverterReadExample.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read; - -import com.alibaba.fastjson2.JSON; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.read.data.ConverterData; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; -import org.apache.fesod.sheet.read.listener.PageReadListener; - -/** - * Demonstrates reading Excel files with data format converters. - * - *

Scenario

- *

Your Excel file contains dates and numbers in specific formats (e.g., "2025-01-01 12:30:00" - * or "56.00%"), and you want them read as formatted {@code String} values rather than raw types. - * Or you need a completely custom transformation for a column.

- * - *

Key Concepts

- *
    - *
  • {@link org.apache.fesod.sheet.annotation.format.DateTimeFormat} — Converts date cells - * to formatted strings using the specified pattern (e.g., {@code "yyyy-MM-dd HH:mm:ss"}).
  • - *
  • {@link org.apache.fesod.sheet.annotation.format.NumberFormat} — Converts number cells - * to formatted strings using {@link java.text.DecimalFormat} patterns (e.g., {@code "#.##%"}).
  • - *
  • {@link org.apache.fesod.sheet.examples.read.converters.CustomStringStringConverter} — - * A custom converter that prepends "Custom:" to string values, demonstrating - * the {@link org.apache.fesod.sheet.converters.Converter} interface.
  • - *
- * - *

Data Class Mapping ({@link ConverterData})

- *
- * Excel Cell           → Java Field (String)
- * ─────────────────────────────────────────
- * "Hello"              → "Custom:Hello"       (via CustomStringStringConverter)
- * 2025-01-01 12:30:00  → "2025-01-01 12:30:00" (via @DateTimeFormat)
- * 0.56                 → "56%"                (via @NumberFormat("#.##%"))
- * 
- * - *

Expected Behavior

- *

All fields in {@link ConverterData} are {@code String} type. Fesod applies the configured - * converter/format to transform the raw Excel cell value before setting the field.

- * - *

Related Examples

- *
    - *
  • {@link org.apache.fesod.sheet.examples.advanced.CustomConverterExample} — - * Register a custom converter at the builder level (applies to all matching fields).
  • - *
  • {@link BasicReadExample} — Read without converters (automatic type mapping).
  • - *
- * - * @see ConverterData - * @see org.apache.fesod.sheet.converters.Converter - * @see org.apache.fesod.sheet.annotation.format.DateTimeFormat - * @see org.apache.fesod.sheet.annotation.format.NumberFormat - */ -@Slf4j -public class ConverterReadExample { - - public static void main(String[] args) { - converterRead(); - } - - /** - * Reads an Excel file with converters and format annotations applied. - * - *

Uses {@link PageReadListener} for simplicity. The actual conversion happens - * transparently during parsing — by the time your listener receives the data, - * all fields are already converted according to their annotations.

- */ - public static void converterRead() { - String fileName = ExampleFileUtil.getExamplePath("demo.xlsx"); - log.info("Reading file with converters: {}", fileName); - - FesodSheet.read(fileName, ConverterData.class, new PageReadListener(dataList -> { - for (ConverterData data : dataList) { - log.info("Read a row of data with converter: {}", JSON.toJSONString(data)); - } - })) - .sheet() - .doRead(); - - log.info("Successfully read file: {}", fileName); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/ExceptionHandlingExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/ExceptionHandlingExample.java deleted file mode 100644 index 416240eef..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/ExceptionHandlingExample.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read; - -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.read.data.ExceptionDemoData; -import org.apache.fesod.sheet.examples.read.listeners.ExceptionListener; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; - -/** - * Demonstrates graceful error handling when reading Excel files with data conversion issues. - * - *

Scenario

- *

Your Excel file contains messy or inconsistent data — for example, a column expected to be - * a date contains plain text like "N/A". Instead of failing the entire read, you want to: - *

    - *
  • Log the problematic row and column
  • - *
  • Skip the bad row
  • - *
  • Continue processing the remaining rows
  • - *
- * - *

Key Concepts

- *
    - *
  • {@link org.apache.fesod.sheet.read.listener.ReadListener#onException(Exception, org.apache.fesod.sheet.context.AnalysisContext)} - * — Override this method to intercept conversion errors. If you don't rethrow, - * parsing continues to the next row.
  • - *
  • {@link org.apache.fesod.sheet.exception.ExcelDataConvertException} — Thrown when a cell value - * cannot be converted to the target Java type. Provides {@code getRowIndex()}, - * {@code getColumnIndex()}, and {@code getCellData()} for precise error reporting.
  • - *
  • {@link ExceptionDemoData} — Intentionally uses {@code Date} type for a string column - * to trigger conversion errors.
  • - *
- * - *

Error Handling Flow

- *
- * Row parsed
- *     │
- *     ├─ Conversion succeeds → invoke(data, context)
- *     │
- *     └─ Conversion fails → onException(ex, context)
- *         ├─ Log error, DON'T rethrow → skip row, continue parsing
- *         └─ Rethrow exception → stop parsing immediately
- * 
- * - *

Expected Behavior

- *

Rows with valid dates are processed normally. Rows with incompatible data are logged - * with their exact row/column position and skipped.

- * - *

Related Examples

- *
    - *
  • {@link BasicReadExample} — Read without error handling (default: exceptions propagate).
  • - *
- * - * @see org.apache.fesod.sheet.exception.ExcelDataConvertException - * @see ExceptionListener - */ -@Slf4j -public class ExceptionHandlingExample { - - public static void main(String[] args) { - exceptionRead(); - } - - /** - * Reads an Excel file with an {@link ExceptionListener} that catches and logs conversion errors. - * - *

The {@link ExceptionDemoData} model intentionally maps a string column to {@code Date}, - * causing {@link org.apache.fesod.sheet.exception.ExcelDataConvertException} to be thrown. - * The listener catches these errors, logs them, and lets parsing continue.

- */ - public static void exceptionRead() { - String fileName = ExampleFileUtil.getExamplePath("demo.xlsx"); - log.info("Reading file with exception handling: {}", fileName); - - FesodSheet.read(fileName, ExceptionDemoData.class, new ExceptionListener()) - .sheet() - .doRead(); - - log.info("Successfully read file: {}", fileName); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/IndexOrNameReadExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/IndexOrNameReadExample.java deleted file mode 100644 index c387c69ae..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/IndexOrNameReadExample.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read; - -import com.alibaba.fastjson2.JSON; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.read.data.IndexOrNameData; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; -import org.apache.fesod.sheet.read.listener.PageReadListener; - -/** - * Demonstrates reading Excel columns by positional index or header name. - * - *

Scenario

- *

Your Excel file may have columns in an unpredictable order, or you only need a subset - * of columns. Instead of relying on field declaration order, you can explicitly map fields - * to columns by index (0-based position) or by header name.

- * - *

Key Concepts

- *
    - *
  • {@code @ExcelProperty(index = 2)} — Forces the field to read from the 3rd column (0-based), - * regardless of header name or field order.
  • - *
  • {@code @ExcelProperty("String")} — Matches the column whose header text is "String". - * This is resilient to column reordering.
  • - *
  • Priority: {@code index} > {@code order} > default field declaration order. - * If both {@code index} and name are specified, {@code index} takes priority.
  • - *
- * - *

Mapping Example ({@link IndexOrNameData})

- *
- * Excel Layout:  | String | Date       | Number |
- * Column Index:  |   0    |     1      |    2   |
- *
- * IndexOrNameData.doubleData  ← Column index 2 ("Number")
- * IndexOrNameData.string      ← Header name "String" (Column 0)
- * IndexOrNameData.date        ← Header name "Date" (Column 1)
- * 
- * - *

When to Use

- *
    - *
  • Excel columns may be shuffled by users (use name matching).
  • - *
  • You need only specific columns from a wide spreadsheet (use index).
  • - *
  • Different Excel versions have different column orders (use name matching).
  • - *
- * - *

Related Examples

- *
    - *
  • {@link BasicReadExample} — Default column matching by field order.
  • - *
  • {@link NoModelReadExample} — Read without any model (raw map data).
  • - *
- * - * @see IndexOrNameData - * @see org.apache.fesod.sheet.annotation.ExcelProperty - */ -@Slf4j -public class IndexOrNameReadExample { - - public static void main(String[] args) { - indexOrNameRead(); - } - - /** - * Reads using {@link IndexOrNameData} which combines index-based and name-based column matching. - * - *

The {@code doubleData} field reads from column index 2, while {@code string} and - * {@code date} fields match by header name. This flexible approach handles varying - * column layouts gracefully.

- */ - public static void indexOrNameRead() { - String fileName = ExampleFileUtil.getExamplePath("demo.xlsx"); - log.info("Reading file with index/name mapping: {}", fileName); - - FesodSheet.read(fileName, IndexOrNameData.class, new PageReadListener(dataList -> { - for (IndexOrNameData data : dataList) { - log.info("Read a row of data with index or name: {}", JSON.toJSONString(data)); - } - })) - .sheet() - .doRead(); - - log.info("Successfully read file: {}", fileName); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/MultiSheetReadExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/MultiSheetReadExample.java deleted file mode 100644 index ed72dea4b..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/MultiSheetReadExample.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read; - -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.ExcelReader; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.read.data.DemoData; -import org.apache.fesod.sheet.examples.read.listeners.DemoDataListener; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; -import org.apache.fesod.sheet.read.metadata.ReadSheet; - -/** - * Demonstrates reading multiple sheets from a single Excel workbook. - * - *

Scenario

- *

Your Excel workbook contains multiple sheets (tabs), each with its own data. - * You need to read some or all of them, potentially with different data models - * or listeners for each sheet.

- * - *

Two Approaches

- * - *

Approach 1: Read All Sheets ({@code doReadAll()})

- *

Reads every sheet in the workbook using the same data model and listener. - * Simplest approach when all sheets share the same structure.

- *
{@code
- * FesodSheet.read(fileName, DemoData.class, new DemoDataListener()).doReadAll();
- * }
- * - *

Approach 2: Read Selected Sheets ({@code ExcelReader})

- *

Creates an {@link ExcelReader} and configures individual {@link ReadSheet} objects. - * Each sheet can have its own data model, listener, and configuration. - * The {@code ExcelReader} must be closed after use (use try-with-resources).

- *
{@code
- * try (ExcelReader reader = FesodSheet.read(fileName).build()) {
- *     ReadSheet sheet1 = FesodSheet.readSheet(0).head(TypeA.class).registerReadListener(listenerA).build();
- *     ReadSheet sheet2 = FesodSheet.readSheet(1).head(TypeB.class).registerReadListener(listenerB).build();
- *     reader.read(sheet1, sheet2);
- * }
- * }
- * - *

Expected Behavior

- *

Each sheet's rows are delivered to its respective listener in order. - * When using {@code doReadAll()}, all sheets share the same listener instance, - * so the listener receives rows from all sheets sequentially.

- * - *

Related Examples

- *
    - *
  • {@link BasicReadExample} — Single-sheet read.
  • - *
  • {@link NoModelReadExample} — Read without a data model.
  • - *
- * - * @see ExcelReader - * @see ReadSheet - * @see FesodSheet#readSheet(Integer) - */ -@Slf4j -public class MultiSheetReadExample { - - public static void main(String[] args) { - repeatedRead(); - } - - /** - * Demonstrates both approaches for reading multiple sheets. - * - *

Approach 1 uses {@code doReadAll()} for simplicity.
- * Approach 2 uses {@code ExcelReader} with individual {@code ReadSheet} configurations - * for full control over each sheet's data model and listener.

- * - *

Note: In Approach 2, the {@link ExcelReader} is wrapped in try-with-resources - * to ensure proper resource cleanup. Always close the reader after use.

- */ - public static void repeatedRead() { - String fileName = ExampleFileUtil.getExamplePath("demo.xlsx"); - log.info("Reading multiple sheets from file: {}", fileName); - - // 1. Read all sheets - FesodSheet.read(fileName, DemoData.class, new DemoDataListener()).doReadAll(); - log.info("Read all sheets completed"); - - // 2. Read specific sheets - try (ExcelReader excelReader = FesodSheet.read(fileName).build()) { - // Create ReadSheet objects for each sheet you want to read. - ReadSheet readSheet1 = FesodSheet.readSheet(0) - .head(DemoData.class) - .registerReadListener(new DemoDataListener()) - .build(); - ReadSheet readSheet2 = FesodSheet.readSheet(1) - .head(DemoData.class) - .registerReadListener(new DemoDataListener()) - .build(); - - // Read multiple sheets at once. - excelReader.read(readSheet1, readSheet2); - } - log.info("Successfully read file: {}", fileName); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/NoModelReadExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/NoModelReadExample.java deleted file mode 100644 index 81e393949..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/NoModelReadExample.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read; - -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.read.listeners.NoModelDataListener; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; - -/** - * Demonstrates reading an Excel file without defining a Java data model. - * - *

Scenario

- *

You don't know the Excel file's structure at compile time, or you want a quick way - * to inspect any Excel file without creating a POJO. Each row is returned as a - * {@code Map} where the key is the column index (0-based) - * and the value is the cell content as a string.

- * - *

Key Concepts

- *
    - *
  • Omit the data class parameter from {@code FesodSheet.read()} — Fesod will use - * {@code Map} as the default row type.
  • - *
  • {@link NoModelDataListener} extends - * {@link org.apache.fesod.sheet.event.AnalysisEventListener}{@code >} - * to receive raw map data.
  • - *
  • All cell values are converted to strings, regardless of the original Excel cell type.
  • - *
- * - *

Row Data Format

- *
- * Excel Row:  | Hello | 2025-01-01 | 0.56 |
- *                 ↓           ↓         ↓
- * Map:  {0: "Hello", 1: "2025-01-01", 2: "0.56"}
- * 
- * - *

When to Use

- *
    - *
  • Building generic Excel import tools that handle arbitrary file structures.
  • - *
  • Quick prototyping or debugging — inspect what's in a file.
  • - *
  • Schema-free processing where columns are dynamic.
  • - *
- * - *

Related Examples

- *
    - *
  • {@link BasicReadExample} — Type-safe read with a data model (recommended for production).
  • - *
  • {@link IndexOrNameReadExample} — Flexible column matching with index or name.
  • - *
- * - * @see NoModelDataListener - * @see org.apache.fesod.sheet.event.AnalysisEventListener - */ -@Slf4j -public class NoModelReadExample { - - public static void main(String[] args) { - noModelRead(); - } - - /** - * Reads an Excel file without specifying a data class. - * - *

When no class is provided to {@code FesodSheet.read()}, each row arrives - * as a {@code Map}. The {@link NoModelDataListener} processes - * these maps with the same batch-save pattern used in typed listeners.

- */ - public static void noModelRead() { - String fileName = ExampleFileUtil.getExamplePath("demo.xlsx"); - log.info("Reading file (no model): {}", fileName); - - // No need to specify a class, just use NoModelDataListener. - FesodSheet.read(fileName, new NoModelDataListener()).sheet().doRead(); - - log.info("Successfully read file: {}", fileName); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/converters/CustomStringStringConverter.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/converters/CustomStringStringConverter.java deleted file mode 100644 index 0a3bd5136..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/converters/CustomStringStringConverter.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read.converters; - -import org.apache.fesod.sheet.converters.Converter; -import org.apache.fesod.sheet.converters.ReadConverterContext; -import org.apache.fesod.sheet.converters.WriteConverterContext; -import org.apache.fesod.sheet.enums.CellDataTypeEnum; -import org.apache.fesod.sheet.metadata.data.WriteCellData; - -/** - * Custom converter that transforms string cell values by prepending a prefix. - * - *

Scenario

- *

You need custom transformation logic that goes beyond simple formatting — - * for example, adding prefixes, decrypting values, or looking up reference data. - * Implement the {@link Converter} interface to create a reusable converter.

- * - *

How It Works

- *
    - *
  • Read: Excel cell "Hello" → Java string "Custom:Hello"
  • - *
  • Write: Java string "Hello" → Excel cell "Hello" (passthrough)
  • - *
- * - *

Registration

- *

Converters can be registered in two ways:

- *
    - *
  1. Per-field: {@code @ExcelProperty(converter = CustomStringStringConverter.class)} - * on a specific field (see {@link org.apache.fesod.sheet.examples.read.data.ConverterData}).
  2. - *
  3. Global: {@code .registerConverter(new CustomStringStringConverter())} on the builder - * (see {@link org.apache.fesod.sheet.examples.advanced.CustomConverterExample}). - * Applies to all fields matching the Java type + Excel type key.
  4. - *
- * - *

Type Keys

- *

{@link #supportJavaTypeKey()} returns {@code String.class} and - * {@link #supportExcelTypeKey()} returns {@code CellDataTypeEnum.STRING}, - * meaning this converter handles String↔String conversions only.

- * - * @see Converter - * @see org.apache.fesod.sheet.annotation.ExcelProperty#converter() - */ -public class CustomStringStringConverter implements Converter { - - @Override - public Class supportJavaTypeKey() { - return String.class; - } - - @Override - public CellDataTypeEnum supportExcelTypeKey() { - return CellDataTypeEnum.STRING; - } - - @Override - public String convertToJavaData(ReadConverterContext context) { - return "Custom:" + context.getReadCellData().getStringValue(); - } - - @Override - public WriteCellData convertToExcelData(WriteConverterContext context) { - return new WriteCellData<>(context.getValue()); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/ConverterData.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/ConverterData.java deleted file mode 100644 index 95b00157b..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/ConverterData.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read.data; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import org.apache.fesod.sheet.annotation.ExcelProperty; -import org.apache.fesod.sheet.annotation.format.DateTimeFormat; -import org.apache.fesod.sheet.annotation.format.NumberFormat; -import org.apache.fesod.sheet.examples.read.converters.CustomStringStringConverter; - -/** - * Data model demonstrating three types of data conversion during Excel reading. - * - *

All fields in this class are {@code String} type, but Fesod applies converters - * and format annotations to transform the raw Excel cell values before setting them.

- * - *

Conversion Mapping

- *
- * Field      | Annotation / Converter                    | Excel Cell → Java Value
- * ───────────|───────────────────────────────────────────|────────────────────────
- * string     | @ExcelProperty(converter=Custom...)        | "Hello" → "Custom:Hello"
- * date       | @DateTimeFormat("yyyy-MM-dd HH:mm:ss")    | 2025-01-01 → "2025-01-01 00:00:00"
- * doubleData | @NumberFormat("#.##%")                     | 0.56 → "56%"
- * 
- * - *

Converter Types

- *
    - *
  • Custom converter ({@link CustomStringStringConverter}) — Implements - * {@link org.apache.fesod.sheet.converters.Converter} for full control over the - * transformation logic. Applied via {@code @ExcelProperty(converter = ...)}.
  • - *
  • Date format ({@code @DateTimeFormat}) — Uses {@link java.text.SimpleDateFormat} - * patterns to format date cells as strings.
  • - *
  • Number format ({@code @NumberFormat}) — Uses {@link java.text.DecimalFormat} - * patterns to format numeric cells as strings.
  • - *
- * - * @see CustomStringStringConverter - * @see org.apache.fesod.sheet.annotation.format.DateTimeFormat - * @see org.apache.fesod.sheet.annotation.format.NumberFormat - */ -@Getter -@Setter -@EqualsAndHashCode -public class ConverterData { - - /** - * Custom converter. - */ - @ExcelProperty(converter = CustomStringStringConverter.class) - private String string; - - /** - * Date format. - */ - @DateTimeFormat("yyyy-MM-dd HH:mm:ss") - private String date; - - /** - * Number format. - */ - @NumberFormat("#.##%") - private String doubleData; -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/DemoDAO.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/DemoDAO.java deleted file mode 100644 index c1ff4d942..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/DemoDAO.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read.data; - -import java.util.List; - -/** - * Mock Data Access Object (DAO) simulating database persistence for examples. - * - *

In production, replace the {@code save()} method body with actual database operations - * (e.g., JDBC batch insert, MyBatis, or JPA). The batch pattern used in - * {@link org.apache.fesod.sheet.examples.read.listeners.DemoDataListener} calls this - * DAO every 100 rows to balance memory usage and database round-trips.

- * - *

Example production implementation:

- *
{@code
- * public void save(List list) {
- *     // Using Spring JdbcTemplate batch insert
- *     jdbcTemplate.batchUpdate(
- *         "INSERT INTO demo (string, date, double_data) VALUES (?, ?, ?)",
- *         list, list.size(),
- *         (ps, data) -> {
- *             ps.setString(1, data.getString());
- *             ps.setDate(2, new java.sql.Date(data.getDate().getTime()));
- *             ps.setDouble(3, data.getDoubleData());
- *         });
- * }
- * }
- * - * @see org.apache.fesod.sheet.examples.read.listeners.DemoDataListener - */ -public class DemoDAO { - - public void save(List list) { - // In actual use, you can use batch insert here. - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/DemoData.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/DemoData.java deleted file mode 100644 index 2686d1a07..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/DemoData.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read.data; - -import java.util.Date; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import org.apache.fesod.sheet.annotation.ExcelIgnore; -import org.apache.fesod.sheet.annotation.ExcelProperty; - -/** - * Data model for the read examples, mapping Excel columns to Java fields. - * - *

This class demonstrates the standard pattern for Fesod data models: - * annotate fields with {@link ExcelProperty} to map them to Excel columns by header name. - * Use {@link ExcelIgnore} to exclude fields that should not participate in reading or writing.

- * - *

Column Mapping

- *
- * Excel Column:      | String Title | Date Title          | Number Title |
- * Java Field:        | string       | date                | doubleData   |
- * Java Type:         | String       | Date                | Double       |
- * 
- * - *

The {@code ignore} field is excluded from Excel operations via {@code @ExcelIgnore}, - * making it suitable for internal-only data like database IDs or computed values.

- * - * @see ExcelProperty - * @see ExcelIgnore - */ -@Getter -@Setter -@EqualsAndHashCode -public class DemoData { - /** - * String Title - */ - @ExcelProperty("String Title") - private String string; - - /** - * Date Title - */ - @ExcelProperty("Date Title") - private Date date; - - /** - * Number Title - */ - @ExcelProperty("Number Title") - private Double doubleData; - - /** - * Ignore this field - */ - @ExcelIgnore - private String ignore; -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/ExceptionDemoData.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/ExceptionDemoData.java deleted file mode 100644 index eca4fc289..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/ExceptionDemoData.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read.data; - -import java.util.Date; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -/** - * Data model intentionally designed to trigger conversion errors during reading. - * - *

This class maps all Excel data to a single {@code Date} field. When the Excel file - * contains string values (e.g., "String Title") that cannot be parsed as dates, - * Fesod throws an {@link org.apache.fesod.sheet.exception.ExcelDataConvertException}.

- * - *

Used by {@link org.apache.fesod.sheet.examples.read.ExceptionHandlingExample} to - * demonstrate the {@code onException()} callback in - * {@link org.apache.fesod.sheet.examples.read.listeners.ExceptionListener}.

- * - * @see org.apache.fesod.sheet.examples.read.ExceptionHandlingExample - * @see org.apache.fesod.sheet.exception.ExcelDataConvertException - */ -@Getter -@Setter -@EqualsAndHashCode -public class ExceptionDemoData { - /** - * Using a Date to receive a string will cause an error. - */ - private Date date; -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/IndexOrNameData.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/IndexOrNameData.java deleted file mode 100644 index 2bb596a7d..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/data/IndexOrNameData.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read.data; - -import java.util.Date; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import org.apache.fesod.sheet.annotation.ExcelProperty; - -/** - * Data model demonstrating mixed index-based and name-based column matching. - * - *

Mapping Strategy

- *
- * Field       | Annotation                  | Matches Column
- * ────────────|─────────────────────────────|───────────────
- * doubleData  | @ExcelProperty(index = 2)   | Column 3 (by position)
- * string      | @ExcelProperty("String")    | Header "String" (by name)
- * date        | @ExcelProperty("Date")      | Header "Date" (by name)
- * 
- * - *

Priority Rules

- *

When both {@code index} and name are specified on the same field, {@code index} wins. - * The full priority order is: {@code index} > {@code order} > field declaration order.

- * - *

Tip: Use index-based matching when the Excel column position is fixed and known. - * Use name-based matching when users might reorder columns but headers remain consistent.

- * - * @see org.apache.fesod.sheet.annotation.ExcelProperty - * @see org.apache.fesod.sheet.examples.read.IndexOrNameReadExample - */ -@Getter -@Setter -@EqualsAndHashCode -public class IndexOrNameData { - /** - * Force reading the third column. - */ - @ExcelProperty(index = 2) - private Double doubleData; - /** - * Match by name. - */ - @ExcelProperty("String") - private String string; - - @ExcelProperty("Date") - private Date date; -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/listeners/DemoDataListener.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/listeners/DemoDataListener.java deleted file mode 100644 index 046f6a9e6..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/listeners/DemoDataListener.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read.listeners; - -import com.alibaba.fastjson2.JSON; -import java.util.List; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.common.util.ListUtils; -import org.apache.fesod.sheet.context.AnalysisContext; -import org.apache.fesod.sheet.examples.read.data.DemoDAO; -import org.apache.fesod.sheet.examples.read.data.DemoData; -import org.apache.fesod.sheet.read.listener.ReadListener; - -/** - * Production-pattern listener demonstrating batch read-and-persist for Excel data. - * - *

Scenario

- *

Reading a large Excel file (thousands or millions of rows) and inserting the data - * into a database. Loading all rows into memory at once would cause an OutOfMemoryError. - * This listener accumulates rows in a small batch and persists every {@value #BATCH_COUNT} - * rows, then clears the cache.

- * - *

Lifecycle

- *
- * ┌───────────────────────────────────────────────────────────────────┐
- * │  invoke(data, context)  ← called once per data row              │
- * │    └─ add to cachedDataList                                    │
- * │    └─ if cache.size() >= 100 → saveData() → clear cache       │
- * ├───────────────────────────────────────────────────────────────────┤
- * │  doAfterAllAnalysed(context)  ← called once after last row      │
- * │    └─ saveData() for remaining rows in cache                   │
- * └───────────────────────────────────────────────────────────────────┘
- * 
- * - *

Thread Safety & Lifecycle

- *

IMPORTANT: This class must NOT be managed by Spring (or any IoC container) as a - * singleton. Create a new instance for each read operation because: - *

    - *
  • The {@code cachedDataList} is mutable state that must not be shared.
  • - *
  • Reusing a listener across files would mix data from different files.
  • - *
- * - *

Spring Integration

- *

If you need to inject Spring beans (e.g., a real DAO), use the constructor that - * accepts a {@link DemoDAO} parameter. Create the listener in your service method:

- *
{@code
- * @Service
- * public class ExcelService {
- *     @Autowired
- *     private DemoDAO demoDAO;
- *
- *     public void importExcel(String fileName) {
- *         // Create a NEW listener for each read, passing the Spring-managed DAO
- *         FesodSheet.read(fileName, DemoData.class, new DemoDataListener(demoDAO))
- *             .sheet().doRead();
- *     }
- * }
- * }
- * - * @see ReadListener - * @see org.apache.fesod.sheet.examples.read.BasicReadExample - */ -@Slf4j -public class DemoDataListener implements ReadListener { - - /** - * Store data in the database every 100 records. - */ - private static final int BATCH_COUNT = 100; - /** - * Cached data - */ - private List cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); - /** - * Mock DAO - */ - private DemoDAO demoDAO; - - public DemoDataListener() { - // This is a demo, so a new instance is created here. - demoDAO = new DemoDAO(); - } - - /** - * If Spring is used, please use this constructor. - * - * @param demoDAO - */ - public DemoDataListener(DemoDAO demoDAO) { - this.demoDAO = demoDAO; - } - - /** - * This method will be called for each data parsed. - * - * @param data one row value. - * @param context - */ - @Override - public void invoke(DemoData data, AnalysisContext context) { - log.info("Parsed one row of data: {}", JSON.toJSONString(data)); - cachedDataList.add(data); - if (cachedDataList.size() >= BATCH_COUNT) { - saveData(); - cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); - } - } - - /** - * This method will be called after all data has been parsed. - * - * @param context - */ - @Override - public void doAfterAllAnalysed(AnalysisContext context) { - saveData(); - log.info("All data has been parsed!"); - } - - /** - * Save data to database. - */ - private void saveData() { - log.info("{} records saved to database!", cachedDataList.size()); - demoDAO.save(cachedDataList); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/listeners/ExceptionListener.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/listeners/ExceptionListener.java deleted file mode 100644 index 9437bfc16..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/listeners/ExceptionListener.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read.listeners; - -import com.alibaba.fastjson2.JSON; -import java.util.List; -import java.util.Map; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.common.util.ListUtils; -import org.apache.fesod.sheet.context.AnalysisContext; -import org.apache.fesod.sheet.examples.read.data.ExceptionDemoData; -import org.apache.fesod.sheet.exception.ExcelDataConvertException; -import org.apache.fesod.sheet.metadata.data.ReadCellData; -import org.apache.fesod.sheet.read.listener.ReadListener; - -/** - * Listener that demonstrates graceful exception handling during Excel reading. - * - *

Scenario

- *

When reading an Excel file with inconsistent data (e.g., text in a date column), - * Fesod throws an {@link ExcelDataConvertException}. This listener catches those errors, - * logs diagnostic information, and allows parsing to continue for the remaining rows.

- * - *

Key Methods

- *
    - *
  • {@link #onException(Exception, AnalysisContext)} — Intercepts any exception during parsing. - * If the exception is an {@code ExcelDataConvertException}, logs the exact row, column, - * and cell value that caused the error. Not rethrowing the exception tells Fesod - * to skip this row and continue.
  • - *
  • {@link #invokeHead(Map, AnalysisContext)} — Called when the header row is parsed. - * Receives a map of column index → {@link ReadCellData} containing header cell information.
  • - *
  • {@link #invoke(ExceptionDemoData, AnalysisContext)} — Called for each successfully - * converted data row.
  • - *
  • {@link #doAfterAllAnalysed(AnalysisContext)} — Called after the last row. - * Persists any remaining cached data.
  • - *
- * - *

Error Handling Strategy

- *
- * onException() is called:
- *     ├─ ExcelDataConvertException → log row/column/value, continue
- *     └─ Other exception → log message, continue (or rethrow to stop)
- * 
- * - * @see ExcelDataConvertException - * @see org.apache.fesod.sheet.examples.read.ExceptionHandlingExample - */ -@Slf4j -public class ExceptionListener implements ReadListener { - - private static final int BATCH_COUNT = 100; - - private List cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); - - @Override - public void onException(Exception exception, AnalysisContext context) { - log.error("Parsing failed, but continue parsing the next line: {}", exception.getMessage()); - if (exception instanceof ExcelDataConvertException) { - ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception; - log.error( - "Parsing exception in row {}, column {}, data: {}", - excelDataConvertException.getRowIndex(), - excelDataConvertException.getColumnIndex(), - excelDataConvertException.getCellData()); - } - } - - @Override - public void invokeHead(Map> headMap, AnalysisContext context) { - log.info("Parsed a header row: {}", JSON.toJSONString(headMap)); - } - - @Override - public void invoke(ExceptionDemoData data, AnalysisContext context) { - log.info("Parsed a data row: {}", JSON.toJSONString(data)); - cachedDataList.add(data); - if (cachedDataList.size() >= BATCH_COUNT) { - saveData(); - cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); - } - } - - @Override - public void doAfterAllAnalysed(AnalysisContext context) { - saveData(); - log.info("All data parsing completed!"); - } - - private void saveData() { - log.info("{} records saved to database!", cachedDataList.size()); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/listeners/NoModelDataListener.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/listeners/NoModelDataListener.java deleted file mode 100644 index ef592c761..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/read/listeners/NoModelDataListener.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.read.listeners; - -import com.alibaba.fastjson2.JSON; -import java.util.List; -import java.util.Map; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.common.util.ListUtils; -import org.apache.fesod.sheet.context.AnalysisContext; -import org.apache.fesod.sheet.event.AnalysisEventListener; - -/** - * Listener for schema-free Excel reading without a data model. - * - *

Scenario

- *

When you don't have (or don't want) a POJO mapped to the Excel structure, - * this listener receives each row as a {@code Map} where: - *

    - *
  • Key = column index (0-based)
  • - *
  • Value = cell content as a string
  • - *
- * - *

Key Differences from Typed Listeners

- *
    - *
  • Extends {@link AnalysisEventListener}{@code >} instead of - * implementing {@code ReadListener}.
  • - *
  • No {@code @ExcelProperty} annotations needed — all columns are automatically included.
  • - *
  • All values arrive as strings, even if the Excel cell is numeric or date type.
  • - *
- * - *

When to Use

- *
    - *
  • Generic Excel import tools that accept any file layout.
  • - *
  • Quick data inspection / debugging.
  • - *
  • Dynamic column handling where structure is unknown at compile time.
  • - *
- * - * @see org.apache.fesod.sheet.examples.read.NoModelReadExample - * @see AnalysisEventListener - */ -@Slf4j -public class NoModelDataListener extends AnalysisEventListener> { - - /** - * Save to the database every 100 records. - */ - private static final int BATCH_COUNT = 100; - - private List> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); - - @Override - public void invoke(Map data, AnalysisContext context) { - log.info("Parsed a data row: {}", JSON.toJSONString(data)); - cachedDataList.add(data); - if (cachedDataList.size() >= BATCH_COUNT) { - saveData(); - cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); - } - } - - @Override - public void doAfterAllAnalysed(AnalysisContext context) { - saveData(); - log.info("All data parsing completed!"); - } - - /** - * Save data to the database. - */ - private void saveData() { - log.info("{} records, starting to save to the database!", cachedDataList.size()); - log.info("Data saved to the database successfully!"); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/util/ExampleDataGenerator.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/util/ExampleDataGenerator.java deleted file mode 100644 index 2d39fb977..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/util/ExampleDataGenerator.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.examples.util; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - -/** - * Utility class for generating sample data used across examples. - * - *

Provides convenient methods to create test data lists for demonstrating - * Fesod's features. In production, data would come from databases, APIs, or user input.

- */ -public class ExampleDataGenerator { - - /** - * Generates a list of strings. - * - * @param count number of strings to generate - * @return list of strings - */ - public static List generateStrings(int count) { - List list = new ArrayList<>(); - for (int i = 0; i < count; i++) { - list.add("Data " + i); - } - return list; - } - - /** - * Generates a list of dates. - * - * @param count number of dates to generate - * @return list of dates - */ - public static List generateDates(int count) { - List list = new ArrayList<>(); - long now = System.currentTimeMillis(); - for (int i = 0; i < count; i++) { - list.add(new Date(now + (long) i * 1000 * 60 * 60 * 24)); - } - return list; - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/util/ExampleFileUtil.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/util/ExampleFileUtil.java deleted file mode 100644 index 000f59274..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/util/ExampleFileUtil.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * 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.examples.util; - -import java.io.File; -import java.nio.file.Files; -import lombok.SneakyThrows; - -/** - * Utility class for locating example input files and generating output file paths. - * - *

File Locations

- *
    - *
  • Input files: Located in the classpath under {@code example/} directory - * (e.g., {@code src/main/resources/example/demo.xlsx}). - * Access via {@link #getExamplePath(String)}.
  • - *
  • Output files: Written to the system temp directory to avoid polluting - * the project workspace. Access via {@link #getTempPath(String)}.
  • - *
- * - *

Usage

- *
{@code
- * // Get path to an input example file
- * String input = ExampleFileUtil.getExamplePath("demo.xlsx");
- * String template = ExampleFileUtil.getExamplePath("templates/simple.xlsx");
- *
- * // Get path for an output file (in temp directory)
- * String output = ExampleFileUtil.getTempPath("result.xlsx");
- * }
- */ -public class ExampleFileUtil { - - public static final String EXAMPLE = "example"; - - public static String getPath() { - java.net.URL resource = ExampleFileUtil.class.getClassLoader().getResource(""); - if (resource == null) { - throw new IllegalStateException("Cannot find classpath root resource"); - } - return toFilePath(resource); - } - - /** - * Get the path to a file in the example resource directory. - * - * @param fileName the file name relative to the example directory (e.g., "demo.xlsx" or "templates/simple.xlsx") - * @return the full path to the file - */ - public static String getExamplePath(String fileName) { - java.net.URL resource = ExampleFileUtil.class.getClassLoader().getResource(EXAMPLE + "/" + fileName); - if (resource != null) { - return toFilePath(resource); - } - // Fallback to classpath root + example path - return getPath() + EXAMPLE + File.separator + fileName; - } - - /** - * Convert a resource URL to a file path, decoding percent-encoded characters. - *

- * {@link java.net.URL#getPath()} returns the encoded path (e.g. {@code %5C} for a backslash on Windows), - * which is not usable with {@link java.io.File}. {@link java.net.URL#toURI()} decodes it correctly. - * - * @param resource the resource URL to convert - * @return the absolute file path - */ - private static String toFilePath(java.net.URL resource) { - try { - return new File(resource.toURI()).getAbsolutePath(); - } catch (java.net.URISyntaxException e) { - throw new IllegalStateException("Invalid resource URL: " + resource, e); - } - } - - /** - * Get the path to write output files in the system temp directory. - * - * @param fileName the output file name - * @return the full path to the output file in temp directory - */ - @SneakyThrows - public static String getTempPath(String fileName) { - return Files.createTempDirectory("fesod-sheet-examples").toAbsolutePath() + File.separator + fileName; - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/DownloadData.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/DownloadData.java deleted file mode 100644 index aaca3b508..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/DownloadData.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.web; - -import java.util.Date; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -/** - * Data model for the web download example. - * - *

Represents a row in the downloaded Excel file. In production, this would - * typically be populated from a database query or service call.

- * - *

Headers are generated from field names by default ("string", "date", "doubleData"). - * Add {@code @ExcelProperty("Custom Header")} annotations for user-friendly column names.

- * - * @see org.apache.fesod.sheet.examples.web.WebExampleController#download(javax.servlet.http.HttpServletResponse) - */ -@Getter -@Setter -@EqualsAndHashCode -public class DownloadData { - private String string; - private Date date; - private Double doubleData; -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/FesodWebApplication.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/FesodWebApplication.java deleted file mode 100644 index beac35416..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/FesodWebApplication.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.web; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** - * Spring Boot application entry point for the web examples. - * - *

Start this application to run the web-based Excel download/upload examples. - * The {@link WebExampleController} provides the following endpoints:

- *
    - *
  • {@code GET /download} — Download an Excel file.
  • - *
  • {@code POST /upload} — Upload and parse an Excel file.
  • - *
- * - *

Note: This application requires Spring Boot and Servlet API dependencies. - * It is provided as a reference for integrating Fesod into web applications.

- * - * @see WebExampleController - */ -@SpringBootApplication -public class FesodWebApplication { - - public static void main(String[] args) { - SpringApplication.run(FesodWebApplication.class, args); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/UploadDAO.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/UploadDAO.java deleted file mode 100644 index 0853b3d76..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/UploadDAO.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.web; - -import java.util.List; -import org.springframework.stereotype.Repository; - -/** - * Mock DAO (Data Access Object) for web upload persistence. - * - *

In production, this would be a real Spring {@code @Repository} with database - * operations (e.g., JDBC batch insert, MyBatis mapper, or JPA repository). - * The {@link UploadDataListener} calls {@code save()} every 100 rows. - * - *

Spring lifecycle: This is a Spring-managed singleton bean ({@code @Repository}). - * It's safe as a singleton because it holds no mutable state — unlike the listener, - * which must be created new for each upload.

- * - * @see UploadDataListener - * @see org.apache.fesod.sheet.examples.web.WebExampleController - */ -@Repository -public class UploadDAO { - - public void save(List list) { - // In actual use, you can use batch insert here. - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/UploadData.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/UploadData.java deleted file mode 100644 index d6db498f3..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/UploadData.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.web; - -import java.util.Date; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; - -/** - * Data model for the web upload example. - * - *

Represents a row in the uploaded Excel file. Fesod automatically maps - * Excel columns to these fields during the upload read operation. - * Field types must be compatible with Excel cell types for automatic conversion.

- * - * @see org.apache.fesod.sheet.examples.web.UploadDataListener - * @see org.apache.fesod.sheet.examples.web.WebExampleController#upload(MultipartFile) - */ -@Getter -@Setter -@EqualsAndHashCode -public class UploadData { - private String string; - private Date date; - private Double doubleData; -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/UploadDataListener.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/UploadDataListener.java deleted file mode 100644 index 2f777b857..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/UploadDataListener.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.web; - -import com.alibaba.fastjson2.JSON; -import java.util.List; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.common.util.ListUtils; -import org.apache.fesod.sheet.context.AnalysisContext; -import org.apache.fesod.sheet.read.listener.ReadListener; - -/** - * Listener for processing uploaded Excel data in a web environment. - * - *

Scenario

- *

When a user uploads an Excel file via a web form, this listener processes the rows - * in batches and persists them using the injected {@link UploadDAO}.

- * - *

Design Pattern

- *

Follows the same batch-save pattern as {@link org.apache.fesod.sheet.examples.read.listeners.DemoDataListener}: - * caches up to {@value #BATCH_COUNT} rows, then flushes to the database.

- * - *

Spring Integration

- *

This listener is NOT a Spring bean. It accepts a Spring-managed {@link UploadDAO} - * via constructor injection. Create a new instance per upload request:

- *
{@code
- * // In WebExampleController
- * FesodSheet.read(file.getInputStream(), UploadData.class, new UploadDataListener(uploadDAO))
- *     .sheet().doRead();
- * }
- * - * @see org.apache.fesod.sheet.examples.web.WebExampleController#upload(MultipartFile) - * @see UploadDAO - */ -@Slf4j -public class UploadDataListener implements ReadListener { - - private static final int BATCH_COUNT = 100; - private List cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); - private UploadDAO uploadDAO; - - public UploadDataListener(UploadDAO uploadDAO) { - this.uploadDAO = uploadDAO; - } - - @Override - public void invoke(UploadData data, AnalysisContext context) { - log.info("Parsed a data row: {}", JSON.toJSONString(data)); - cachedDataList.add(data); - if (cachedDataList.size() >= BATCH_COUNT) { - saveData(); - cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); - } - } - - @Override - public void doAfterAllAnalysed(AnalysisContext context) { - saveData(); - log.info("All data parsing completed!"); - } - - private void saveData() { - log.info("{} records saved to database!", cachedDataList.size()); - uploadDAO.save(cachedDataList); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/WebExampleController.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/WebExampleController.java deleted file mode 100644 index efde67f63..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/web/WebExampleController.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.web; - -import java.io.IOException; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import javax.servlet.http.HttpServletResponse; -import org.apache.fesod.sheet.FesodSheet; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.multipart.MultipartFile; - -/** - * Spring MVC controller demonstrating Excel download and upload in a web application. - * - *

Scenario

- *

A typical enterprise application where users can: - *

    - *
  • Download — Export data as an Excel file via HTTP GET (browser download).
  • - *
  • Upload — Import data from an uploaded Excel file via HTTP POST (multipart form).
  • - *
- * - *

Download Flow ({@code GET /download})

- *
- * Browser GET /download
- *     │
- *     ├─ Set Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
- *     ├─ Set Content-Disposition: attachment;filename=test.xlsx
- *     └─ FesodSheet.write(response.getOutputStream(), ...).sheet().doWrite(data)
- *         └─ Excel bytes streamed directly to HTTP response (no temp file)
- * 
- * - *

Upload Flow ({@code POST /upload})

- *
- * Browser POST /upload (multipart/form-data)
- *     │
- *     └─ FesodSheet.read(file.getInputStream(), UploadData.class, listener).sheet().doRead()
- *         └─ UploadDataListener processes rows in batches → saves to database
- * 
- * - *

Key Implementation Details

- *
    - *
  • Streaming download: Writes directly to {@code response.getOutputStream()}, - * avoiding temporary files and enabling large exports.
  • - *
  • Filename encoding: Uses {@code URLEncoder} with UTF-8 for Chinese/special - * characters in the filename.
  • - *
  • Upload listener: Creates a new {@link UploadDataListener} per request with - * the injected {@link UploadDAO} (Spring-managed). The listener itself is NOT a bean.
  • - *
- * - *

curl Test Commands

- *
{@code
- * # Download
- * curl -o test.xlsx http://localhost:8080/download
- *
- * # Upload
- * curl -F "file=@test.xlsx" http://localhost:8080/upload
- * }
- * - *

Related Examples

- *
    - *
  • {@link org.apache.fesod.sheet.examples.write.BasicWriteExample} — Write to file.
  • - *
  • {@link org.apache.fesod.sheet.examples.read.BasicReadExample} — Read from file.
  • - *
- * - * @see UploadDataListener - * @see DownloadData - */ -@Controller -public class WebExampleController { - - @Autowired - private UploadDAO uploadDAO; - - /** - * Downloads an Excel file as an HTTP response. - * - *

Writes directly to the response output stream — no temporary file is created. - * The response headers are configured for browser download with a UTF-8 encoded filename.

- * - *

Important: Set {@code Content-Type} and {@code Content-Disposition} headers - * BEFORE writing to the output stream. Once bytes are written, headers cannot be modified.

- * - * @param response the HTTP servlet response - * @throws IOException if writing to the output stream fails - */ - @GetMapping("download") - public void download(HttpServletResponse response) throws IOException { - response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); - response.setCharacterEncoding("utf-8"); - String fileName = URLEncoder.encode("test", "UTF-8").replaceAll("\\+", "%20"); - response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); - - FesodSheet.write(response.getOutputStream(), DownloadData.class) - .sheet("Template") - .doWrite(data()); - } - - /** - * Uploads and parses an Excel file from a multipart form submission. - * - *

Uses {@code file.getInputStream()} to read the uploaded file directly from - * the multipart data, avoiding extra disk I/O. The {@link UploadDataListener} - * processes rows in batches and persists via the injected {@link UploadDAO}.

- * - * @param file the uploaded multipart file - * @return "success" on completion - * @throws IOException if reading the input stream fails - */ - @PostMapping("upload") - @ResponseBody - public String upload(MultipartFile file) throws IOException { - FesodSheet.read(file.getInputStream(), UploadData.class, new UploadDataListener(uploadDAO)) - .sheet() - .doRead(); - return "success"; - } - - private List data() { - List list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - DownloadData data = new DownloadData(); - data.setString("String" + i); - data.setDate(new Date()); - data.setDoubleData(0.56); - list.add(data); - } - return list; - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/BasicWriteExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/BasicWriteExample.java deleted file mode 100644 index 8c17e15a5..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/BasicWriteExample.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.write; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; -import org.apache.fesod.sheet.examples.write.data.DemoData; - -/** - * Demonstrates the standard pattern for writing data to an Excel file. - * - *

Scenario

- *

You have a list of Java objects (e.g., query results from a database) and want to - * export them to an Excel file with proper column headers. This is the most common - * write use case.

- * - *

Key Concepts

- *
    - *
  • {@link FesodSheet#write(String, Class)} — Creates a write builder. The class parameter - * defines the column headers (from {@code @ExcelProperty} annotations) and data types.
  • - *
  • {@code .sheet("Template")} — Creates a worksheet with the given tab name.
  • - *
  • {@code .doWrite(data)} — Terminal operation: writes all rows and closes the file. - * Handles header generation, type conversion, and resource cleanup automatically.
  • - *
- * - *

Expected Output

- *

An Excel file with one sheet named "Template" containing:

- *
- * | String Title | Date Title          | Number Title |
- * |--------------|---------------------|--------------|
- * | String0      | 2025-01-01 00:00:00 | 0.56         |
- * | String1      | 2025-01-01 00:00:00 | 0.56         |
- * | ...          | ...                 | ...          |
- * | String9      | 2025-01-01 00:00:00 | 0.56         |
- * 
- * - *

Related Examples

- *
    - *
  • {@link StyleWriteExample} — Add custom header/content styles (colors, fonts).
  • - *
  • {@link MergeWriteExample} — Merge cells during write.
  • - *
  • {@link ImageWriteExample} — Export images to Excel cells.
  • - *
  • {@link org.apache.fesod.sheet.examples.advanced.LargeFileWriteExample} - * — Write 100K+ rows with memory optimization.
  • - *
- * - * @see FesodSheet#write(String, Class) - * @see DemoData - */ -@Slf4j -public class BasicWriteExample { - - public static void main(String[] args) { - basicWrite(); - } - - /** - * Writes 10 rows of demo data to an Excel file. - * - *

The output file is created in the system temp directory. - * Check the log output for the exact file path.

- */ - public static void basicWrite() { - String fileName = ExampleFileUtil.getTempPath("basicWrite" + System.currentTimeMillis() + ".xlsx"); - - // Specify the class to write, then write to the first sheet. - FesodSheet.write(fileName, DemoData.class).sheet("Template").doWrite(data()); - log.info("Successfully wrote file: {}", fileName); - } - - private static List data() { - List list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - DemoData data = new DemoData(); - data.setString("String" + i); - data.setDate(new Date()); - data.setDoubleData(0.56); - list.add(data); - } - return list; - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/ImageWriteExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/ImageWriteExample.java deleted file mode 100644 index 436d30079..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/ImageWriteExample.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.write; - -import java.io.File; -import java.io.InputStream; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.enums.CellDataTypeEnum; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; -import org.apache.fesod.sheet.examples.write.data.ImageDemoData; -import org.apache.fesod.sheet.metadata.data.ImageData; -import org.apache.fesod.sheet.metadata.data.WriteCellData; -import org.apache.fesod.sheet.util.FileUtils; - -/** - * Demonstrates exporting images to Excel cells using five different source types. - * - *

Scenario

- *

You need to generate an Excel report containing images — for example, product photos - * in a catalog, user avatars in a report, or QR codes in an inventory sheet.

- * - *

Five Image Source Types

- *
- * Type          | Field Type          | Use Case
- * ──────────────|─────────────────────|──────────────────────────────────────────
- * File          | File                | Local file on disk
- * InputStream   | InputStream         | Classpath resource, servlet upload, etc.
- * String path   | String              | File path (requires StringImageConverter)
- * byte[]        | byte[]              | Pre-loaded binary data, generated images
- * URL           | URL                 | Remote image (downloaded at write time)
- * 
- * - *

Advanced: Multiple Images per Cell ({@link WriteCellData})

- *

Using {@code WriteCellData} you can:

- *
    - *
  • Add multiple images to a single cell
  • - *
  • Combine text with images in the same cell
  • - *
  • Control image positioning with margins (top, right, bottom, left)
  • - *
  • Span images across adjacent cells using {@code relativeLastColumnIndex}
  • - *
- * - *

Memory Considerations

- *

Warning: All images are loaded into memory during write. For large volumes:

- *
    - *
  • Upload images to cloud storage (e.g., AWS S3) and reference by URL.
  • - *
  • Compress images before embedding.
  • - *
  • Consider writing fewer images per batch.
  • - *
- * - *

Expected Output

- *

An Excel file with one row containing 6 columns, each showing the same image - * loaded from a different source. The last column contains two images with text, - * spanning into the adjacent cell.

- * - *

Related Examples

- *
    - *
  • {@link BasicWriteExample} — Simple data write.
  • - *
  • {@link StyleWriteExample} — Style customization.
  • - *
- * - * @see ImageDemoData - * @see WriteCellData - * @see ImageData - */ -@Slf4j -public class ImageWriteExample { - - public static void main(String[] args) throws Exception { - imageWrite(); - } - - /** - * Writes images to Excel using all five source types plus advanced multi-image positioning. - * - *

The method demonstrates: - *

    - *
  1. Setting up five different image sources (File, InputStream, String, byte[], URL).
  2. - *
  3. Creating a {@link WriteCellData} with text + two images at custom positions.
  4. - *
  5. Using {@code relativeLastColumnIndex} to span an image across cells.
  6. - *
- * - *

Troubleshooting: If image resources are inaccessible, XLSX format may error with - * "SXSSFWorkbook - Failed to dispose sheet". In that case, try XLS format instead.

- * - * @throws Exception if file operations fail - */ - public static void imageWrite() throws Exception { - String fileName = ExampleFileUtil.getTempPath("imageWrite" + System.currentTimeMillis() + ".xlsx"); - - // Note: All images will be loaded into memory. For large volumes, consider: - // 1. Upload images to cloud storage (e.g., https://www.aliyun.com/product/oss) and use URLs - // 2. Use image compression tools like: https://github.com/coobird/thumbnailator - - String imagePath = ExampleFileUtil.getPath() + "example/sample-data" + File.separator + "img.jpg"; - try (InputStream inputStream = FileUtils.openInputStream(new File(imagePath))) { - List list = new ArrayList<>(); - ImageDemoData imageDemoData = new ImageDemoData(); - list.add(imageDemoData); - - // Five types of image export - in practice, choose only one method - imageDemoData.setByteArray(FileUtils.readFileToByteArray(new File(imagePath))); - imageDemoData.setFile(new File(imagePath)); - imageDemoData.setString(imagePath); - imageDemoData.setInputStream(inputStream); - imageDemoData.setUrl(new URL("https://poi.apache.org/images/project-header.png")); - - // Advanced example demonstrating: - // - Adding text to the cell in addition to images - // - Adding 2 images to the same cell - // - First image aligned to the left - // - Second image aligned to the right and spanning into adjacent cells - WriteCellData writeCellData = new WriteCellData<>(); - imageDemoData.setWriteCellDataFile(writeCellData); - // Can be set to EMPTY if no additional data is needed - writeCellData.setType(CellDataTypeEnum.STRING); - writeCellData.setStringValue("Additional text content"); - - // Can add multiple images to a single cell - List imageDataList = new ArrayList<>(); - ImageData imageData = new ImageData(); - imageDataList.add(imageData); - writeCellData.setImageDataList(imageDataList); - // Set image as binary data - imageData.setImage(FileUtils.readFileToByteArray(new File(imagePath))); - // Set image type - imageData.setImageType(ImageData.ImageType.PICTURE_TYPE_PNG); - // Top, Right, Bottom, Left margins - // Similar to CSS margin - // Note: Setting values too large (exceeding cell size) may cause repair prompts when opening. - // No perfect solution found yet. - imageData.setTop(5); - imageData.setRight(40); - imageData.setBottom(5); - imageData.setLeft(5); - - // Add second image - imageData = new ImageData(); - imageDataList.add(imageData); - writeCellData.setImageDataList(imageDataList); - imageData.setImage(FileUtils.readFileToByteArray(new File(imagePath))); - imageData.setImageType(ImageData.ImageType.PICTURE_TYPE_PNG); - imageData.setTop(5); - imageData.setRight(5); - imageData.setBottom(5); - imageData.setLeft(50); - // Position the image to span from current cell to the cell on its right - // Starting point is relative to current cell (0 - can be omitted) - imageData.setRelativeFirstRowIndex(0); - imageData.setRelativeFirstColumnIndex(0); - imageData.setRelativeLastRowIndex(0); - // The first 3 can be omitted. This one must be set - the ending position - // needs to move one column to the right relative to the current cell - // This means the image will cover the current cell and the next cell to its right - imageData.setRelativeLastColumnIndex(1); - - // Write data - FesodSheet.write(fileName, ImageDemoData.class).sheet().doWrite(list); - log.info("Successfully wrote image file: {}", fileName); - // If image resources are inaccessible, XLSX format may error: SXSSFWorkbook - Failed to dispose sheet - // Consider declaring as XLS format in such cases: - // FesodSheet.write(fileName, ImageDemoData.class).excelType(ExcelTypeEnum.XLS).sheet().doWrite(list); - } - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/MergeWriteExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/MergeWriteExample.java deleted file mode 100644 index b80ab8916..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/MergeWriteExample.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.write; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; -import org.apache.fesod.sheet.examples.write.data.DemoMergeData; -import org.apache.fesod.sheet.write.merge.LoopMergeStrategy; - -/** - * Demonstrates cell merging strategies when writing Excel files. - * - *

Scenario

- *

You need to create an Excel report where certain cells are merged — for example, - * merging repeated category names in the first column, or creating summary rows. - * Fesod supports two approaches: annotation-based and strategy-based merging.

- * - *

Approach 1: Annotation-Based ({@code @ContentLoopMerge})

- *

Annotate a field in the data class with {@code @ContentLoopMerge(eachRow = N)} - * to automatically merge every N rows in that column. See {@link DemoMergeData}.

- *
- * Result (eachRow = 2):
- * | String Title | Date Title          | Number Title |
- * |--------------|---------------------|--------------|
- * | String0      | 2025-01-01 00:00:00 | 0.56         |
- * | (merged)     | 2025-01-01 00:00:00 | 0.56         |
- * | String1      | 2025-01-01 00:00:00 | 0.56         |
- * | (merged)     | 2025-01-01 00:00:00 | 0.56         |
- * 
- * - *

Approach 2: Strategy-Based ({@link LoopMergeStrategy})

- *

Register a {@code LoopMergeStrategy(eachRow, columnIndex)} as a write handler. - * More flexible — can be configured at runtime and applied to any column.

- *
{@code
- * // Merge every 2 rows in column 0
- * LoopMergeStrategy strategy = new LoopMergeStrategy(2, 0);
- * FesodSheet.write(fileName, DemoMergeData.class)
- *     .registerWriteHandler(strategy)
- *     .sheet().doWrite(data);
- * }
- * - *

When to Use Which

- *
    - *
  • Annotation — Simple, fixed merge patterns baked into the data class.
  • - *
  • Strategy — Dynamic merging, multiple merge rules, or merging based on data content.
  • - *
- * - *

Related Examples

- *
    - *
  • {@link StyleWriteExample} — Style customization.
  • - *
  • {@link BasicWriteExample} — Simple write without merging.
  • - *
- * - * @see org.apache.fesod.sheet.annotation.write.style.ContentLoopMerge - * @see LoopMergeStrategy - * @see DemoMergeData - */ -@Slf4j -public class MergeWriteExample { - - public static void main(String[] args) { - mergeWrite(); - } - - /** - * Demonstrates both annotation-based and strategy-based cell merging. - * - *

Writes two separate files: - *

    - *
  1. Annotation merge — Uses {@code @ContentLoopMerge(eachRow = 2)} on the - * {@code string} field of {@link DemoMergeData}.
  2. - *
  3. Strategy merge — Registers a {@link LoopMergeStrategy} to merge every - * 2 rows in column 0.
  4. - *
- * Both produce the same visual result but via different mechanisms.

- */ - public static void mergeWrite() { - String fileName = ExampleFileUtil.getTempPath("mergeWrite" + System.currentTimeMillis() + ".xlsx"); - - // Method 1: Use annotations (see DemoMergeData) - FesodSheet.write(fileName, DemoMergeData.class) - .sheet("Annotation Merge") - .doWrite(data()); - log.info("Successfully wrote file: {}", fileName); - - // Method 2: Use a merge strategy - fileName = ExampleFileUtil.getTempPath("mergeWriteStrategy" + System.currentTimeMillis() + ".xlsx"); - // Merge every 2 rows in the 0th column. - LoopMergeStrategy loopMergeStrategy = new LoopMergeStrategy(2, 0); - FesodSheet.write(fileName, DemoMergeData.class) - .registerWriteHandler(loopMergeStrategy) - .sheet("Strategy Merge") - .doWrite(data()); - log.info("Successfully wrote file: {}", fileName); - } - - private static List data() { - List list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - DemoMergeData data = new DemoMergeData(); - data.setString("String" + (i / 2)); // Same string for merged rows - data.setDate(new Date()); - data.setDoubleData(0.56); - list.add(data); - } - return list; - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/StyleWriteExample.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/StyleWriteExample.java deleted file mode 100644 index cd4113687..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/StyleWriteExample.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.write; - -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.util.ExampleFileUtil; -import org.apache.fesod.sheet.examples.write.data.DemoStyleData; - -/** - * Demonstrates how to customize header and content styles in Excel output. - * - *

Scenario

- *

You're generating an Excel report that needs branded colors, custom font sizes, - * or specific cell formatting to match corporate style guides.

- * - *

Key Concepts

- *
    - *
  • Class-level annotations — Apply default styles to all columns: - *
      - *
    • {@code @HeadStyle} / {@code @HeadFontStyle} — Header row background color and font.
    • - *
    • {@code @ContentStyle} / {@code @ContentFontStyle} — Data row background color and font.
    • - *
    - *
  • - *
  • Field-level annotations — Override class-level styles for specific columns. - * In the example, the "String Title" column has distinct colors and a larger font - * than the other columns.
  • - *
  • Color values — Use Excel's indexed color system (0-63). Common values: - * 10 = dark green, 14 = dark teal, 17 = light yellow, 40 = light blue. - * See {@link org.apache.poi.ss.usermodel.IndexedColors} for the full palette.
  • - *
- * - *

Style Hierarchy

- *
- * Field-level @HeadStyle / @ContentStyle
- *     │ (if present, overrides class-level)
- *     ↓
- * Class-level @HeadStyle / @ContentStyle
- *     │ (if present, overrides Fesod default)
- *     ↓
- * Fesod default styles
- * 
- * - *

Expected Output

- *

An Excel file where: - *

    - *
  • Header row: dark green background (color 10), 20pt font for all columns, - * except "String Title" which has dark teal (14) and 30pt font.
  • - *
  • Content rows: light yellow background (color 17), 20pt font for all columns, - * except "String Title" which has light blue (40) and 30pt font.
  • - *
- * - *

Related Examples

- *
    - *
  • {@link BasicWriteExample} — Write with default styles.
  • - *
  • {@link MergeWriteExample} — Combine merging with styles.
  • - *
  • {@link org.apache.fesod.sheet.examples.write.handlers.CustomCellWriteHandler} - * — Programmatic style customization via handlers.
  • - *
- * - * @see DemoStyleData - * @see org.apache.fesod.sheet.annotation.write.style.HeadStyle - * @see org.apache.fesod.sheet.annotation.write.style.ContentStyle - */ -@Slf4j -public class StyleWriteExample { - - public static void main(String[] args) { - styleWrite(); - } - - /** - * Writes an Excel file with custom header and content styles. - * - *

Styles are defined entirely through annotations on {@link DemoStyleData}. - * No programmatic style code is needed — Fesod reads the annotations and applies - * them automatically during write.

- */ - public static void styleWrite() { - String fileName = ExampleFileUtil.getTempPath("styleWrite" + System.currentTimeMillis() + ".xlsx"); - - FesodSheet.write(fileName, DemoStyleData.class).sheet("Template").doWrite(data()); - log.info("Successfully wrote file: {}", fileName); - } - - private static List data() { - List list = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - DemoStyleData data = new DemoStyleData(); - data.setString("String" + i); - data.setDate(new Date()); - data.setDoubleData(0.56); - list.add(data); - } - return list; - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/data/DemoData.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/data/DemoData.java deleted file mode 100644 index c609e9462..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/data/DemoData.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.write.data; - -import java.util.Date; -import lombok.Data; -import org.apache.fesod.sheet.annotation.ExcelIgnore; -import org.apache.fesod.sheet.annotation.ExcelProperty; - -/** - * Data model for the write examples, mapping Java fields to Excel columns. - * - *

Identical structure to the read examples' DemoData, but uses Lombok's - * {@code @Data} for brevity (generates getters, setters, equals, hashCode, toString). - * The {@link ExcelProperty} annotations define column headers in the output file, - * while {@link ExcelIgnore} excludes the {@code ignore} field from the Excel output.

- * - *

Generated Excel Headers

- *
- * | String Title | Date Title | Number Title |
- * 
- * - * @see ExcelProperty - * @see ExcelIgnore - */ -@Data -public class DemoData { - /** - * String Title - */ - @ExcelProperty("String Title") - private String string; - - /** - * Date Title - */ - @ExcelProperty("Date Title") - private Date date; - - /** - * Number Title - */ - @ExcelProperty("Number Title") - private Double doubleData; - - /** - * Ignore this field - */ - @ExcelIgnore - private String ignore; -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/data/DemoMergeData.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/data/DemoMergeData.java deleted file mode 100644 index 5e2eed077..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/data/DemoMergeData.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.write.data; - -import java.util.Date; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import org.apache.fesod.sheet.annotation.ExcelProperty; -import org.apache.fesod.sheet.annotation.write.style.ContentLoopMerge; - -/** - * Data model demonstrating annotation-based cell merging. - * - *

The {@code @ContentLoopMerge(eachRow = 2)} annotation on the {@code string} field - * tells Fesod to merge every 2 consecutive rows in that column. This is useful for - * category grouping in reports.

- * - *

Merge Effect

- *
- * Row 1: | String0 | 2025-01-01 | 0.56 |  ← merged with row 2
- * Row 2: | (merged)| 2025-01-01 | 0.56 |
- * Row 3: | String1 | 2025-01-01 | 0.56 |  ← merged with row 4
- * Row 4: | (merged)| 2025-01-01 | 0.56 |
- * 
- * - *

For runtime-configurable merging, use {@link org.apache.fesod.sheet.write.merge.LoopMergeStrategy} - * instead (see {@link org.apache.fesod.sheet.examples.write.MergeWriteExample}).

- * - * @see ContentLoopMerge - * @see org.apache.fesod.sheet.write.merge.LoopMergeStrategy - */ -@Getter -@Setter -@EqualsAndHashCode -public class DemoMergeData { - /** - * Merge cells every 2 rows in this column. - */ - @ContentLoopMerge(eachRow = 2) - @ExcelProperty("String Title") - private String string; - - @ExcelProperty("Date Title") - private Date date; - - @ExcelProperty("Number Title") - private Double doubleData; -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/data/DemoStyleData.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/data/DemoStyleData.java deleted file mode 100644 index 720532800..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/data/DemoStyleData.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.write.data; - -import java.util.Date; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import org.apache.fesod.sheet.annotation.ExcelProperty; -import org.apache.fesod.sheet.annotation.write.style.ContentFontStyle; -import org.apache.fesod.sheet.annotation.write.style.ContentStyle; -import org.apache.fesod.sheet.annotation.write.style.HeadFontStyle; -import org.apache.fesod.sheet.annotation.write.style.HeadStyle; -import org.apache.fesod.sheet.enums.poi.FillPatternTypeEnum; - -/** - * Data model demonstrating annotation-based style customization. - * - *

Class-Level Styles (Default for All Columns)

- *
    - *
  • Header: Solid fill, color 10 (dark green), font size 20pt
  • - *
  • Content: Solid fill, color 17 (light yellow), font size 20pt
  • - *
- * - *

Field-Level Overrides ("String Title" Column Only)

- *
    - *
  • Header: Solid fill, color 14 (dark teal), font size 30pt
  • - *
  • Content: Solid fill, color 40 (light blue), font size 30pt
  • - *
- * - *

Style Annotations Reference

- *
    - *
  • {@link HeadStyle} / {@link ContentStyle} — Cell background fill pattern and color. - * Use {@code fillPatternType = SOLID_FOREGROUND} with {@code fillForegroundColor} for - * solid background colors.
  • - *
  • {@link HeadFontStyle} / {@link ContentFontStyle} — Font properties like size, - * bold, italic, color, and font name.
  • - *
  • Field-level annotations override class-level annotations for that specific column.
  • - *
- * - * @see HeadStyle - * @see HeadFontStyle - * @see ContentStyle - * @see ContentFontStyle - * @see org.apache.fesod.sheet.examples.write.StyleWriteExample - */ -@Getter -@Setter -@EqualsAndHashCode -@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 10) -@HeadFontStyle(fontHeightInPoints = 20) -@ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 17) -@ContentFontStyle(fontHeightInPoints = 20) -public class DemoStyleData { - @HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 14) - @HeadFontStyle(fontHeightInPoints = 30) - @ContentStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 40) - @ContentFontStyle(fontHeightInPoints = 30) - @ExcelProperty("String Title") - private String string; - - @ExcelProperty("Date Title") - private Date date; - - @ExcelProperty("Number Title") - private Double doubleData; -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/data/ImageDemoData.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/data/ImageDemoData.java deleted file mode 100644 index d86f96ce9..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/data/ImageDemoData.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.write.data; - -import java.io.File; -import java.io.InputStream; -import java.net.URL; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import org.apache.fesod.sheet.annotation.ExcelProperty; -import org.apache.fesod.sheet.annotation.write.style.ColumnWidth; -import org.apache.fesod.sheet.annotation.write.style.ContentRowHeight; -import org.apache.fesod.sheet.converters.string.StringImageConverter; -import org.apache.fesod.sheet.metadata.data.WriteCellData; - -/** - * Data model demonstrating five ways to export images to Excel cells. - * - *

Image Source Types

- *

Each field represents a different way to provide image data to Fesod:

- *
- * Field             | Type                  | Description
- * ───────────────────|───────────────────────|────────────────────────────────────────
- * file              | File                  | Local file reference
- * inputStream       | InputStream           | Stream from any source
- * string            | String                | File path (requires StringImageConverter)
- * byteArray         | byte[]                | Raw image bytes
- * url               | URL                   | Remote image URL
- * writeCellDataFile | WriteCellData<Void>   | Advanced: multiple images + text in one cell
- * 
- * - *

Layout Annotations

- *
    - *
  • {@code @ContentRowHeight(100)} — Sets row height to 100 points for image visibility.
  • - *
  • {@code @ColumnWidth(100 / 8)} — Sets column width (in characters, ~12.5) for image cells.
  • - *
- * - *

Memory Warning

- *

All images are loaded into memory. For large volumes, consider: - *

    - *
  • Uploading to cloud storage and using URL references.
  • - *
  • Compressing images before export.
  • - *
- * - * @see org.apache.fesod.sheet.examples.write.ImageWriteExample - * @see StringImageConverter - * @see WriteCellData - */ -@Getter -@Setter -@EqualsAndHashCode -@ContentRowHeight(100) -@ColumnWidth(100 / 8) -public class ImageDemoData { - private File file; - private InputStream inputStream; - /** - * If string type, a converter must be specified. - */ - @ExcelProperty(converter = StringImageConverter.class) - private String string; - - private byte[] byteArray; - /** - * Export by URL. - */ - private URL url; - - /** - * Export by file and set the export position. - */ - private WriteCellData writeCellDataFile; -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/handlers/CommentWriteHandler.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/handlers/CommentWriteHandler.java deleted file mode 100644 index 9c578c5f7..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/handlers/CommentWriteHandler.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.write.handlers; - -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.common.util.BooleanUtils; -import org.apache.fesod.sheet.write.handler.RowWriteHandler; -import org.apache.fesod.sheet.write.handler.context.RowWriteHandlerContext; -import org.apache.poi.ss.usermodel.Comment; -import org.apache.poi.ss.usermodel.Drawing; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.xssf.usermodel.XSSFClientAnchor; -import org.apache.poi.xssf.usermodel.XSSFRichTextString; - -/** - * Custom {@link RowWriteHandler} that adds an Excel comment (note) to a header cell. - * - *

Scenario

- *

You want to add hover-able comments/notes to specific cells — for example, adding - * instructions or descriptions to column headers so end-users understand each column.

- * - *

How It Works

- *
    - *
  1. Implements {@link RowWriteHandler#afterRowDispose(RowWriteHandlerContext)}, - * which is called after each row is written.
  2. - *
  3. Checks if the row is a header row via {@code context.getHead()}.
  4. - *
  5. Creates a drawing patriarch on the sheet and adds a comment anchored - * to cell B1 (row 0, column 1).
  6. - *
- * - *

Result

- *

The second column header cell will show a small red triangle indicator. - * Hovering over it displays "Created a comment!".

- * - *

Registration

- *
{@code
- * FesodSheet.write(fileName, DemoData.class)
- *     .registerWriteHandler(new CommentWriteHandler())
- *     .sheet().doWrite(data);
- * }
- * - *

Note: This handler uses Apache POI's XSSF-specific classes ({@code XSSFClientAnchor}, - * {@code XSSFRichTextString}), so it only works with {@code .xlsx} format.

- * - * @see RowWriteHandler - * @see org.apache.poi.ss.usermodel.Comment - */ -@Slf4j -public class CommentWriteHandler implements RowWriteHandler { - - @Override - public void afterRowDispose(RowWriteHandlerContext context) { - if (BooleanUtils.isTrue(context.getHead())) { - Sheet sheet = context.getWriteSheetHolder().getSheet(); - Drawing drawingPatriarch = sheet.createDrawingPatriarch(); - // Create a comment in the first row, second column. - Comment comment = - drawingPatriarch.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, (short) 1, 0, (short) 2, 1)); - comment.setString(new XSSFRichTextString("Created a comment!")); - sheet.getRow(0).getCell(1).setCellComment(comment); - } - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/handlers/CustomCellWriteHandler.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/handlers/CustomCellWriteHandler.java deleted file mode 100644 index 8a73caf25..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/handlers/CustomCellWriteHandler.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.write.handlers; - -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.common.util.BooleanUtils; -import org.apache.fesod.sheet.write.handler.CellWriteHandler; -import org.apache.fesod.sheet.write.handler.context.CellWriteHandlerContext; -import org.apache.poi.common.usermodel.HyperlinkType; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.Hyperlink; - -/** - * Custom {@link CellWriteHandler} that adds a hyperlink to the first header cell. - * - *

Scenario

- *

You want to customize individual cells after they are written — for example, - * adding hyperlinks, conditional formatting, or cell validation. The {@code CellWriteHandler} - * gives you access to the Apache POI {@link Cell} object for low-level customization.

- * - *

How It Works

- *
    - *
  1. Implements {@link CellWriteHandler#afterCellDispose(CellWriteHandlerContext)}, - * which is called after each cell (both header and content cells).
  2. - *
  3. Checks if the cell is a header cell ({@code context.getHead()}) in the first - * column ({@code cell.getColumnIndex() == 0}).
  4. - *
  5. Creates a URL hyperlink pointing to the Fesod GitHub repository and attaches - * it to the cell.
  6. - *
- * - *

Result

- *

The first column header cell becomes a clickable hyperlink to - * {@code https://github.com/apache/fesod}.

- * - *

Registration

- *
{@code
- * FesodSheet.write(fileName, DemoData.class)
- *     .registerWriteHandler(new CustomCellWriteHandler())
- *     .sheet().doWrite(data);
- * }
- * - *

Handler Execution Order

- *

Fesod calls write handlers in registration order. If multiple handlers modify - * the same cell, later handlers can override earlier ones.

- * - * @see CellWriteHandler - * @see org.apache.poi.ss.usermodel.Hyperlink - */ -@Slf4j -public class CustomCellWriteHandler implements CellWriteHandler { - - @Override - public void afterCellDispose(CellWriteHandlerContext context) { - Cell cell = context.getCell(); - log.info("Row {}, Column {} write completed.", cell.getRowIndex(), cell.getColumnIndex()); - if (BooleanUtils.isTrue(context.getHead()) && cell.getColumnIndex() == 0) { - CreationHelper createHelper = - context.getWriteSheetHolder().getSheet().getWorkbook().getCreationHelper(); - Hyperlink hyperlink = createHelper.createHyperlink(HyperlinkType.URL); - hyperlink.setAddress("https://github.com/apache/fesod"); - cell.setHyperlink(hyperlink); - } - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/handlers/CustomSheetWriteHandler.java b/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/handlers/CustomSheetWriteHandler.java deleted file mode 100644 index 58c2a9f9d..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/java/org/apache/fesod/sheet/examples/write/handlers/CustomSheetWriteHandler.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * 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. - */ - -/* - * This file is part of the Apache Fesod (Incubating) project, which was derived from Alibaba EasyExcel. - * - * Copyright (C) 2018-2024 Alibaba Group Holding Ltd. - */ - -package org.apache.fesod.sheet.examples.write.handlers; - -import lombok.extern.slf4j.Slf4j; -import org.apache.fesod.sheet.write.handler.SheetWriteHandler; -import org.apache.fesod.sheet.write.handler.context.SheetWriteHandlerContext; -import org.apache.poi.ss.usermodel.DataValidation; -import org.apache.poi.ss.usermodel.DataValidationConstraint; -import org.apache.poi.ss.usermodel.DataValidationHelper; -import org.apache.poi.ss.util.CellRangeAddressList; - -/** - * Custom {@link SheetWriteHandler} that adds a dropdown validation list to a sheet. - * - *

Scenario

- *

You want to add data validation, conditional formatting, or other sheet-level - * customizations when a worksheet is first created. The {@code SheetWriteHandler} - * provides a hook into the sheet creation lifecycle.

- * - *

How It Works

- *
    - *
  1. Implements {@link SheetWriteHandler#afterSheetCreate(SheetWriteHandlerContext)}, - * called immediately after a new sheet is created.
  2. - *
  3. Creates a data validation constraint with explicit list values - * ({@code "Test1", "Test2"}).
  4. - *
  5. Applies the constraint to cells A2:A3 (rows 1-2, column 0).
  6. - *
- * - *

Result

- *

Cells A2 and A3 will show a dropdown arrow. Clicking it reveals the options - * "Test1" and "Test2". Entering other values triggers a validation error.

- * - *

Registration

- *
{@code
- * FesodSheet.write(fileName, DemoData.class)
- *     .registerWriteHandler(new CustomSheetWriteHandler())
- *     .sheet().doWrite(data);
- * }
- * - *

Other Use Cases for SheetWriteHandler

- *
    - *
  • Setting print areas or page breaks
  • - *
  • Freezing panes (freeze rows/columns)
  • - *
  • Adding auto-filters
  • - *
  • Setting sheet protection
  • - *
- * - * @see SheetWriteHandler - * @see org.apache.poi.ss.usermodel.DataValidation - */ -@Slf4j -public class CustomSheetWriteHandler implements SheetWriteHandler { - - @Override - public void afterSheetCreate(SheetWriteHandlerContext context) { - log.info("Sheet {} write successful.", context.getWriteSheetHolder().getSheetNo()); - - // Add a dropdown list to the first column of the second and third rows. - CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 2, 0, 0); - DataValidationHelper helper = context.getWriteSheetHolder().getSheet().getDataValidationHelper(); - DataValidationConstraint constraint = helper.createExplicitListConstraint(new String[] {"Test1", "Test2"}); - DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList); - context.getWriteSheetHolder().getSheet().addValidationData(dataValidation); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/main/resources/application.properties b/fesod-examples/fesod-sheet-examples/src/main/resources/application.properties deleted file mode 100644 index 9afc34590..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/resources/application.properties +++ /dev/null @@ -1,20 +0,0 @@ -# -# 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. -# - -server.port=8080 diff --git a/fesod-examples/fesod-sheet-examples/src/main/resources/example/demo.xlsx b/fesod-examples/fesod-sheet-examples/src/main/resources/example/demo.xlsx deleted file mode 100644 index 89e43a71d..000000000 Binary files a/fesod-examples/fesod-sheet-examples/src/main/resources/example/demo.xlsx and /dev/null differ diff --git a/fesod-examples/fesod-sheet-examples/src/main/resources/example/sample-data/img.jpg b/fesod-examples/fesod-sheet-examples/src/main/resources/example/sample-data/img.jpg deleted file mode 100644 index 953f39f34..000000000 Binary files a/fesod-examples/fesod-sheet-examples/src/main/resources/example/sample-data/img.jpg and /dev/null differ diff --git a/fesod-examples/fesod-sheet-examples/src/main/resources/example/templates/list.xlsx b/fesod-examples/fesod-sheet-examples/src/main/resources/example/templates/list.xlsx deleted file mode 100644 index d1075eb05..000000000 Binary files a/fesod-examples/fesod-sheet-examples/src/main/resources/example/templates/list.xlsx and /dev/null differ diff --git a/fesod-examples/fesod-sheet-examples/src/main/resources/example/templates/simple.xlsx b/fesod-examples/fesod-sheet-examples/src/main/resources/example/templates/simple.xlsx deleted file mode 100644 index 610014d61..000000000 Binary files a/fesod-examples/fesod-sheet-examples/src/main/resources/example/templates/simple.xlsx and /dev/null differ diff --git a/fesod-examples/fesod-sheet-examples/src/main/resources/logback.xml b/fesod-examples/fesod-sheet-examples/src/main/resources/logback.xml deleted file mode 100644 index b18f5687b..000000000 --- a/fesod-examples/fesod-sheet-examples/src/main/resources/logback.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - utf8 - - - - - - - - - - diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/ExampleTestBase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/ExampleTestBase.java deleted file mode 100644 index d633a4af9..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/ExampleTestBase.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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.examples; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.file.Path; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.usermodel.WorkbookFactory; - -/** - * Base class for Fesod example integration tests. - * - *

Provides common utilities for verifying Excel file output, following the patterns established - * by Apache Flink's {@code ExampleOutputTestBase} and {@code AbstractTestBase}. - * - *

Key utilities: - *

    - *
  • {@link #assertValidExcelFile(File)} — verifies a file is a readable Excel workbook
  • - *
  • {@link #assertValidExcelFile(File, int)} — additionally verifies minimum row count
  • - *
  • {@link #getTempOutputPath(Path, String)} — generates a temp file path within a directory
  • - *
- */ -public abstract class ExampleTestBase { - - /** - * Assert that the given file exists, is non-empty, and is a valid Excel workbook that - * Apache POI can open. - * - * @param file the Excel file to validate - */ - protected static void assertValidExcelFile(File file) { - assertNotNull(file, "File reference must not be null"); - assertTrue(file.exists(), "File should exist: " + file.getAbsolutePath()); - assertTrue(file.length() > 0, "File should not be empty: " + file.getAbsolutePath()); - - try (FileInputStream fis = new FileInputStream(file); - Workbook workbook = WorkbookFactory.create(fis)) { - assertNotNull(workbook, "Workbook should be readable"); - assertTrue(workbook.getNumberOfSheets() > 0, "Workbook should have at least one sheet"); - } catch (IOException e) { - fail("File should be a valid Excel workbook: " + file.getAbsolutePath() + ", error: " + e.getMessage()); - } - } - - /** - * Assert that the given file is a valid Excel workbook with at least the specified number of - * data rows (excluding header). - * - * @param file the Excel file to validate - * @param minDataRows the minimum number of data rows expected (excluding header row) - */ - protected static void assertValidExcelFile(File file, int minDataRows) { - assertValidExcelFile(file); - - try (FileInputStream fis = new FileInputStream(file); - Workbook workbook = WorkbookFactory.create(fis)) { - int totalRows = workbook.getSheetAt(0).getPhysicalNumberOfRows(); - // totalRows includes header row, so data rows = totalRows - 1 - assertTrue( - totalRows > minDataRows, - "Expected at least " + minDataRows + " data rows (plus header), but found " + totalRows - + " total rows in: " + file.getAbsolutePath()); - } catch (IOException e) { - fail("Failed to read workbook for row count verification: " + e.getMessage()); - } - } - - /** - * Assert that the given file is a valid Excel workbook with at least the specified number of - * columns, scanning for the first non-empty row to determine the column count. - * - * @param file the Excel file to validate - * @param minColumns the minimum number of columns expected - */ - protected static void assertValidExcelFileColumns(File file, int minColumns) { - int totalColumns = 0; - assertValidExcelFile(file); - - try (FileInputStream fis = new FileInputStream(file); - Workbook workbook = WorkbookFactory.create(fis)) { - Sheet sheet = workbook.getSheetAt(0); - // find which row is not empty - for (int i = 0; i <= sheet.getLastRowNum(); i++) { - Row row = sheet.getRow(i); - if (row != null && row.getPhysicalNumberOfCells() > 0) { - totalColumns = row.getLastCellNum(); - break; - } - } - assertTrue( - totalColumns >= minColumns, - "Expected at least " + minColumns + " columns, but found " + totalColumns - + " total columns in the first data row of: " + file.getAbsolutePath()); - } catch (IOException e) { - fail("Failed to read workbook for column count verification: " + e.getMessage()); - } - } - - /** - * Generate a temp output file path within the given directory. - * - * @param tempDir the temporary directory (typically from {@code @TempDir}) - * @param fileName the desired filename - * @return the absolute path as a String - */ - protected static String getTempOutputPath(Path tempDir, String fileName) { - return tempDir.resolve(fileName).toAbsolutePath().toString(); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/advanced/CustomConverterExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/advanced/CustomConverterExampleITCase.java deleted file mode 100644 index 1d4304699..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/advanced/CustomConverterExampleITCase.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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.examples.advanced; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.junit.jupiter.api.Test; - -/** - * Test for {@link CustomConverterExample}. - * - *

Verifies the custom-converter round-trip: writes an Excel file with a - * {@code CustomStringStringConverter} that transforms string values, then reads them back - * using the same converter. - */ -class CustomConverterExampleITCase extends ExampleTestBase { - - @Test - void testCustomConverterRoundTrip() { - assertDoesNotThrow(() -> CustomConverterExample.main(new String[] {})); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/advanced/LargeFileWriteExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/advanced/LargeFileWriteExampleITCase.java deleted file mode 100644 index bc2e74376..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/advanced/LargeFileWriteExampleITCase.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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.examples.advanced; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.junit.jupiter.api.Test; - -/** - * Test for {@link LargeFileWriteExample}. - * - *

Verifies the large-file write example which writes 100,000 rows in batches using - * {@code SXSSFWorkbook} with compressed temporary files to reduce disk usage. - * - *

Note: This test may take several seconds due to the volume of data. - */ -class LargeFileWriteExampleITCase extends ExampleTestBase { - - @Test - void testCompressedTemporaryFile() { - assertDoesNotThrow(LargeFileWriteExample::compressedTemporaryFile); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/advanced/PasswordProtectionExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/advanced/PasswordProtectionExampleITCase.java deleted file mode 100644 index 1f02c52eb..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/advanced/PasswordProtectionExampleITCase.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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.examples.advanced; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertTrue; -import java.io.File; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.apache.fesod.sheet.examples.write.data.DemoData; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -/** - * Test for {@link PasswordProtectionExample}. - * - *

Verifies the full password-protection round-trip: writes a password-protected Excel file, - * then reads it back with the same password. Also validates the protected file is a readable - * workbook via a controlled write to {@code @TempDir}. - */ -class PasswordProtectionExampleITCase extends ExampleTestBase { - - @Test - void testPasswordRoundTrip() { - assertDoesNotThrow(() -> PasswordProtectionExample.main(new String[] {})); - } - - @Test - void testPasswordProtectedFileIsValid(@TempDir Path tempDir) { - String fileName = getTempOutputPath(tempDir, "password.xlsx"); - String password = "test123"; - - List data = new ArrayList<>(); - for (int i = 0; i < 5; i++) { - DemoData d = new DemoData(); - d.setString("String" + i); - d.setDate(new Date()); - d.setDoubleData(0.56); - data.add(d); - } - - FesodSheet.write(fileName) - .password(password) - .head(DemoData.class) - .sheet("Test") - .doWrite(data); - - // Password-protected files cannot be opened without the password by POI WorkbookFactory, - // so we only verify the file exists and has a non-trivial size. - File file = new File(fileName); - assertTrue(file.exists(), "Password-protected file should exist"); - assertTrue(file.length() > 0, "Password-protected file should not be empty"); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/fill/FillBasicExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/fill/FillBasicExampleITCase.java deleted file mode 100644 index f279d36bb..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/fill/FillBasicExampleITCase.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.examples.fill; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.junit.jupiter.api.Test; - -/** - * Test for {@link FillBasicExample}. - * - *

Verifies the simple-fill example which fills data into an Excel template ({@code simple.xlsx}) - * using both object-based and map-based approaches. - */ -class FillBasicExampleITCase extends ExampleTestBase { - - @Test - void testSimpleFill() { - assertDoesNotThrow(FillBasicExample::simpleFill); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/fill/FillComplexExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/fill/FillComplexExampleITCase.java deleted file mode 100644 index 77c965dbd..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/fill/FillComplexExampleITCase.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.examples.fill; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.junit.jupiter.api.Test; - -/** - * Test for {@link FillComplexExample}. - * - *

Verifies the list-fill example which fills a list of {@code FillData} rows into - * a template ({@code list.xlsx}). Tests both single-pass and multi-pass fill methods. - */ -class FillComplexExampleITCase extends ExampleTestBase { - - @Test - void testListFill() { - assertDoesNotThrow(FillComplexExample::listFill); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/quickstart/SimpleReadExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/quickstart/SimpleReadExampleITCase.java deleted file mode 100644 index 61b3dbe17..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/quickstart/SimpleReadExampleITCase.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.examples.quickstart; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.junit.jupiter.api.Test; - -/** - * Test for {@link SimpleReadExample}. - * - *

Verifies that the quickstart read example can successfully read data from the bundled - * {@code demo.xlsx} resource without throwing any exceptions. - */ -class SimpleReadExampleITCase extends ExampleTestBase { - - @Test - void testSimpleRead() { - assertDoesNotThrow(SimpleReadExample::simpleRead); - } - - @Test - void testMain() { - assertDoesNotThrow(() -> SimpleReadExample.main(new String[] {})); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/quickstart/SimpleWriteExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/quickstart/SimpleWriteExampleITCase.java deleted file mode 100644 index c0f4374c5..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/quickstart/SimpleWriteExampleITCase.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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.examples.quickstart; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.junit.jupiter.api.Test; - -/** - * Test for {@link SimpleWriteExample}. - * - *

Verifies that the quickstart write example can produce an Excel file. The example writes - * 10 rows of {@code DemoData} to a temp file via {@code ExampleFileUtil.getTempPath()}. - */ -class SimpleWriteExampleITCase extends ExampleTestBase { - - @Test - void testSimpleWrite() { - assertDoesNotThrow(SimpleWriteExample::simpleWrite); - } - - @Test - void testMain() { - assertDoesNotThrow(() -> SimpleWriteExample.main(new String[] {})); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/ConverterReadExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/ConverterReadExampleITCase.java deleted file mode 100644 index 42fcc9eb7..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/ConverterReadExampleITCase.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.examples.read; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.junit.jupiter.api.Test; - -/** - * Test for {@link ConverterReadExample}. - * - *

Verifies that the converter read example can read {@code demo.xlsx} with a custom - * {@code CustomStringStringConverter} applied during the read process. - */ -class ConverterReadExampleITCase extends ExampleTestBase { - - @Test - void testConverterRead() { - assertDoesNotThrow(ConverterReadExample::converterRead); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/ExceptionHandlingExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/ExceptionHandlingExampleITCase.java deleted file mode 100644 index 9cdc41b79..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/ExceptionHandlingExampleITCase.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.examples.read; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.junit.jupiter.api.Test; - -/** - * Test for {@link ExceptionHandlingExample}. - * - *

Verifies that the exception handling read example processes all rows from {@code demo.xlsx}, - * demonstrating proper error handling within the listener callback. - */ -class ExceptionHandlingExampleITCase extends ExampleTestBase { - - @Test - void testExceptionRead() { - assertDoesNotThrow(ExceptionHandlingExample::exceptionRead); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/IndexOrNameReadExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/IndexOrNameReadExampleITCase.java deleted file mode 100644 index d3bc3e95a..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/IndexOrNameReadExampleITCase.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.examples.read; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.junit.jupiter.api.Test; - -/** - * Test for {@link IndexOrNameReadExample}. - * - *

Verifies reading Excel columns by index or name annotation from {@code demo.xlsx}. - */ -class IndexOrNameReadExampleITCase extends ExampleTestBase { - - @Test - void testIndexOrNameRead() { - assertDoesNotThrow(IndexOrNameReadExample::indexOrNameRead); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/MultiSheetReadExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/MultiSheetReadExampleITCase.java deleted file mode 100644 index bb575204b..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/MultiSheetReadExampleITCase.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.examples.read; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.junit.jupiter.api.Test; - -/** - * Test for {@link MultiSheetReadExample}. - * - *

Verifies that the multi-sheet read example correctly reads the same file multiple times - * using different listeners, demonstrating sheet-level repeated read capability. - */ -class MultiSheetReadExampleITCase extends ExampleTestBase { - - @Test - void testMultiSheetRead() { - assertDoesNotThrow(MultiSheetReadExample::repeatedRead); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/NoModelReadExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/NoModelReadExampleITCase.java deleted file mode 100644 index 51d7b04a5..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/read/NoModelReadExampleITCase.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.examples.read; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.junit.jupiter.api.Test; - -/** - * Test for {@link NoModelReadExample}. - * - *

Verifies that the no-model read example can read {@code demo.xlsx} without a pre-defined - * data class, using {@code Map} to receive each row's data. - */ -class NoModelReadExampleITCase extends ExampleTestBase { - - @Test - void testNoModelRead() { - assertDoesNotThrow(NoModelReadExample::noModelRead); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/web/FesodWebApplicationITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/web/FesodWebApplicationITCase.java deleted file mode 100644 index e34e14139..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/web/FesodWebApplicationITCase.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * 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.examples.web; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -/** - * Integration test that verifies FesodWebApplication starts successfully. - */ -@SpringBootTest(classes = FesodWebApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -class FesodWebApplicationITCase { - - @Test - void contextLoads() { - // If the application context fails to start, this test will fail. - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/write/BasicWriteExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/write/BasicWriteExampleITCase.java deleted file mode 100644 index 6d2ecdf4e..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/write/BasicWriteExampleITCase.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.examples.write; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import java.io.File; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import org.apache.fesod.sheet.FesodSheet; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.apache.fesod.sheet.examples.write.data.DemoData; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; - -/** - * Test for {@link BasicWriteExample}. - * - *

Verifies: (1) the example completes without exception, and (2) a separate controlled write - * to a {@code @TempDir} produces a valid Excel workbook with the expected number of data rows. - */ -class BasicWriteExampleITCase extends ExampleTestBase { - - @Test - void testBasicWrite() { - assertDoesNotThrow(BasicWriteExample::basicWrite); - } - - @Test - void testWriteProducesValidExcel(@TempDir Path tempDir) { - String fileName = getTempOutputPath(tempDir, "basicWrite.xlsx"); - List data = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - DemoData d = new DemoData(); - d.setString("String" + i); - d.setDate(new Date()); - d.setDoubleData(0.56); - data.add(d); - } - FesodSheet.write(fileName, DemoData.class).sheet("Template").doWrite(data); - - assertValidExcelFile(new File(fileName), 10); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/write/MergeWriteExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/write/MergeWriteExampleITCase.java deleted file mode 100644 index 94103ea75..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/write/MergeWriteExampleITCase.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.examples.write; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.junit.jupiter.api.Test; - -/** - * Test for {@link MergeWriteExample}. - * - *

Verifies both merge strategies: (1) annotation-based merge via {@code @ContentLoopMerge} - * and (2) programmatic merge via {@code LoopMergeStrategy}. Each strategy writes a separate file. - */ -class MergeWriteExampleITCase extends ExampleTestBase { - - @Test - void testMergeWrite() { - assertDoesNotThrow(MergeWriteExample::mergeWrite); - } -} diff --git a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/write/StyleWriteExampleITCase.java b/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/write/StyleWriteExampleITCase.java deleted file mode 100644 index 12d97d987..000000000 --- a/fesod-examples/fesod-sheet-examples/src/test/java/org/apache/fesod/sheet/examples/write/StyleWriteExampleITCase.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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.examples.write; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import org.apache.fesod.sheet.examples.ExampleTestBase; -import org.junit.jupiter.api.Test; - -/** - * Test for {@link StyleWriteExample}. - * - *

Verifies that the style-write example can produce an Excel file with annotation-based - * cell styles ({@code @ContentStyle}, {@code @HeadStyle}) applied to a {@code DemoStyleData} model. - */ -class StyleWriteExampleITCase extends ExampleTestBase { - - @Test - void testStyleWrite() { - assertDoesNotThrow(StyleWriteExample::styleWrite); - } -} diff --git a/fesod-examples/pom.xml b/fesod-examples/pom.xml deleted file mode 100644 index 4a7fcca4c..000000000 --- a/fesod-examples/pom.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - 4.0.0 - - org.apache.fesod - fesod-parent - ${revision} - - - fesod-examples - pom - Fesod Examples - - - UTF-8 - true - true - - - fesod-sheet-examples - - diff --git a/pom.xml b/pom.xml index c4bcff65f..8e62bb954 100644 --- a/pom.xml +++ b/pom.xml @@ -76,7 +76,6 @@ fesod-bom fesod-common fesod-shaded - fesod-examples fesod-sheet