Copilot commented on code in PR #616: URL: https://github.com/apache/fesod/pull/616#discussion_r2388310770
########## fesod-spring-boot-starter/src/main/java/org/apache/fesod/spring/boot/autoconfigure/FesodProperties.java: ########## @@ -0,0 +1,249 @@ +/* + * 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.spring.boot.autoconfigure; + +import java.util.Locale; +import org.apache.fesod.excel.enums.CacheLocationEnum; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Root configuration properties for Fesod Spring Boot starter. + * <p> + * All properties are bound under the prefix {@code fesod}. + * Example (application.yml): + * <pre> + * fesod: + * global: + * auto-trim: true + * locale: en_US + * reader: + * ignore-empty-row: true + * writer: + * in-memory: true + * </pre> + */ +@ConfigurationProperties(prefix = "fesod") +public class FesodProperties { + + /** Global shared configuration applied to both reading and writing. */ + private Global global = new Global(); + /** Reader specific configuration. */ + private Reader reader = new Reader(); + /** Writer specific configuration. */ + private Writer writer = new Writer(); + + public Global getGlobal() { + return global; + } + + public void setGlobal(Global global) { + this.global = global; + } + + public Reader getReader() { + return reader; + } + + public void setReader(Reader reader) { + this.reader = reader; + } + + public Writer getWriter() { + return writer; + } + + public void setWriter(Writer writer) { + this.writer = writer; + } + + /** + * Global configuration options that affect both reading and writing operations. + */ + public static class Global { + /** + * Whether to automatically trim leading and trailing whitespace from cell string values. + */ + private Boolean autoTrim; + /** + * Whether to automatically remove invisible / special control characters (strip) from cell values. + */ + private Boolean autoStrip; + /** + * Whether to interpret dates using the 1904 date windowing (common in older Mac Excel files). + */ + private Boolean use1904Windowing; + /** + * Whether numeric values which are large or small should be written using scientific notation. + */ + private Boolean useScientificFormat; + /** + * The default locale to use for formatting and parsing (e.g. number, date patterns). If not set, JVM default is used. + */ + private Locale locale; + /** + * Where to cache temporary file based data structures when writing / reading large workbooks. + */ + private CacheLocationEnum filedCacheLocation; + + public Boolean getAutoTrim() { + return autoTrim; + } + + public void setAutoTrim(Boolean autoTrim) { + this.autoTrim = autoTrim; + } + + public Boolean getAutoStrip() { + return autoStrip; + } + + public void setAutoStrip(Boolean autoStrip) { + this.autoStrip = autoStrip; + } + + public Boolean getUse1904Windowing() { + return use1904Windowing; + } + + public void setUse1904Windowing(Boolean use1904Windowing) { + this.use1904Windowing = use1904Windowing; + } + + public Boolean getUseScientificFormat() { + return useScientificFormat; + } + + public void setUseScientificFormat(Boolean useScientificFormat) { + this.useScientificFormat = useScientificFormat; + } + + public Locale getLocale() { + return locale; + } + + public void setLocale(Locale locale) { + this.locale = locale; + } + + public CacheLocationEnum getFiledCacheLocation() { + return filedCacheLocation; + } + + public void setFiledCacheLocation(CacheLocationEnum filedCacheLocation) { + this.filedCacheLocation = filedCacheLocation; + } Review Comment: The getter and setter method names should be 'getFileCacheLocation' and 'setFileCacheLocation' to match the corrected property name. ########## fesod-spring-boot-starter/src/main/java/org/apache/fesod/spring/boot/FesodTemplate.java: ########## @@ -0,0 +1,201 @@ +/* + * 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.spring.boot; + +import java.io.File; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import org.apache.fesod.excel.FastExcelFactory; +import org.apache.fesod.excel.metadata.AbstractParameterBuilder; +import org.apache.fesod.excel.read.builder.AbstractExcelReaderParameterBuilder; +import org.apache.fesod.excel.read.builder.ExcelReaderBuilder; +import org.apache.fesod.excel.read.listener.ReadListener; +import org.apache.fesod.excel.write.builder.ExcelWriterBuilder; +import org.apache.fesod.spring.boot.autoconfigure.FesodProperties; +import org.apache.fesod.spring.boot.autoconfigure.FesodReaderBuilderCustomizer; +import org.apache.fesod.spring.boot.autoconfigure.FesodWriterBuilderCustomizer; + +/** + * Convenience facade that exposes the {@link FastExcelFactory} builders as Spring beans + * with sensible defaults driven by {@link FesodProperties}. + */ +public class FesodTemplate { + + private final FesodProperties properties; + private final List<FesodWriterBuilderCustomizer> writerCustomizers; + private final List<FesodReaderBuilderCustomizer> readerCustomizers; + + public FesodTemplate( + FesodProperties properties, + List<FesodWriterBuilderCustomizer> writerCustomizers, + List<FesodReaderBuilderCustomizer> readerCustomizers) { + this.properties = properties != null ? properties : new FesodProperties(); + this.writerCustomizers = writerCustomizers == null ? Collections.emptyList() : writerCustomizers; + this.readerCustomizers = readerCustomizers == null ? Collections.emptyList() : readerCustomizers; + } + + public ExcelWriterBuilder writer() { + return customizeWriter(FastExcelFactory.write()); + } + + public ExcelWriterBuilder writer(File file) { + return customizeWriter(FastExcelFactory.write(file)); + } + + public ExcelWriterBuilder writer(File file, Class<?> head) { + return customizeWriter(FastExcelFactory.write(file, head)); + } + + public ExcelWriterBuilder writer(String pathName) { + return customizeWriter(FastExcelFactory.write(pathName)); + } + + public ExcelWriterBuilder writer(String pathName, Class<?> head) { + return customizeWriter(FastExcelFactory.write(pathName, head)); + } + + public ExcelWriterBuilder writer(OutputStream outputStream) { + return customizeWriter(FastExcelFactory.write(outputStream)); + } + + public ExcelWriterBuilder writer(OutputStream outputStream, Class<?> head) { + return customizeWriter(FastExcelFactory.write(outputStream, head)); + } + + public ExcelReaderBuilder reader() { + return customizeReader(FastExcelFactory.read()); + } + + public ExcelReaderBuilder reader(File file) { + return customizeReader(FastExcelFactory.read(file)); + } + + public ExcelReaderBuilder reader(File file, ReadListener<?> readListener) { + return customizeReader(FastExcelFactory.read(file, readListener)); + } + + public ExcelReaderBuilder reader(File file, Class<?> head, ReadListener<?> readListener) { + return customizeReader(FastExcelFactory.read(file, head, readListener)); + } + + public ExcelReaderBuilder reader(String pathName) { + return customizeReader(FastExcelFactory.read(pathName)); + } + + public ExcelReaderBuilder reader(String pathName, ReadListener<?> readListener) { + return customizeReader(FastExcelFactory.read(pathName, readListener)); + } + + public ExcelReaderBuilder reader(String pathName, Class<?> head, ReadListener<?> readListener) { + return customizeReader(FastExcelFactory.read(pathName, head, readListener)); + } + + public ExcelReaderBuilder reader(InputStream inputStream) { + return customizeReader(FastExcelFactory.read(inputStream)); + } + + public ExcelReaderBuilder reader(InputStream inputStream, ReadListener<?> readListener) { + return customizeReader(FastExcelFactory.read(inputStream, readListener)); + } + + public ExcelReaderBuilder reader(InputStream inputStream, Class<?> head, ReadListener<?> readListener) { + return customizeReader(FastExcelFactory.read(inputStream, head, readListener)); + } + + private ExcelWriterBuilder customizeWriter(ExcelWriterBuilder builder) { + applyGlobal(builder); + applyWriterDefaults(builder); + writerCustomizers.forEach(customizer -> customizer.customize(builder)); + return builder; + } + + private ExcelReaderBuilder customizeReader(ExcelReaderBuilder builder) { + applyGlobal(builder); + applyReaderDefaults(builder); + readerCustomizers.forEach(customizer -> customizer.customize(builder)); + return builder; + } + + private void applyGlobal(AbstractParameterBuilder<?, ?> builder) { + FesodProperties.Global global = properties.getGlobal(); + if (global == null) { + return; + } + if (global.getAutoTrim() != null) { + builder.autoTrim(global.getAutoTrim()); + } + if (global.getAutoStrip() != null) { + builder.autoStrip(global.getAutoStrip()); + } + if (global.getUse1904Windowing() != null) { + builder.use1904windowing(global.getUse1904Windowing()); + } + Locale locale = global.getLocale(); + if (locale != null) { + builder.locale(locale); + } + if (global.getUseScientificFormat() != null && builder instanceof AbstractExcelReaderParameterBuilder) { + AbstractExcelReaderParameterBuilder<?, ?> readerBuilder = + (AbstractExcelReaderParameterBuilder<?, ?>) builder; + readerBuilder.useScientificFormat(global.getUseScientificFormat()); + } + if (global.getFiledCacheLocation() != null) { + builder.filedCacheLocation(global.getFiledCacheLocation()); Review Comment: The method call should use the corrected spelling 'getFileCacheLocation()' instead of 'getFiledCacheLocation()'. ```suggestion if (global.getFileCacheLocation() != null) { builder.fileCacheLocation(global.getFileCacheLocation()); ``` ########## README.md: ########## @@ -80,6 +80,75 @@ dependencies { } ``` +### Spring Boot Starter + +For Spring Boot 2.7.x or 3.x applications you can depend on the starter to get auto-configuration, a preconfigured `FesodTemplate` bean, and property binding out of the box. The starter keeps its Spring Boot dependencies in `provided` scope, so your application controls the exact Boot version it runs with. + +```xml +<dependency> + <groupId>org.apache.fesod</groupId> + <artifactId>fesod-spring-boot-starter</artifactId> + <version>version</version> +</dependency> +``` + +Inject the template anywhere in your application to obtain reader and writer builders: + +```java +@Service +public class ReportService { + + private final FesodTemplate fesodTemplate; + + public ReportService(FesodTemplate fesodTemplate) { + this.fesodTemplate = fesodTemplate; + } + + public void exportReport(OutputStream out, Class<?> head, Collection<?> rows) { + fesodTemplate.writer(out, head) + .sheet("report") + .doWrite(rows); + } +} +``` + +> ℹ️ When using Spring Boot 3.x, make sure your project targets Java 17 or newer, as required by Spring Boot 3. + +Starter behaviour can be tuned through standard Spring configuration properties (`application.yml` shown, `application.properties` also supported): + +```yaml +fesod: + global: + auto-trim: true + locale: zh-CN + reader: + ignore-empty-row: true + auto-close-stream: true + writer: + in-memory: false + write-excel-on-exception: true +``` + +By default (without explicit configuration) the starter keeps the same defaults as core Fesod: + +| Property | Default | Description | +| --- | --- | --- | +| `fesod.global.auto-trim` | `true` | Trim leading/trailing whitespace for sheet names and cell values | +| `fesod.global.auto-strip` | `false` | Strip non-printable characters only when enabled | +| `fesod.global.use1904-windowing` | `false` | Use the 1900 Excel date system | +| `fesod.global.use-scientific-format` | `false` | Reader-specific toggle for scientific number formatting | +| `fesod.global.locale` | JVM default locale | Drives number/date formatting | +| `fesod.global.filed-cache-location` | `THREAD_LOCAL` | Metadata cache strategy | Review Comment: The property name in the documentation should be 'file-cache-location' instead of 'filed-cache-location' to match the corrected spelling. ```suggestion | `fesod.global.file-cache-location` | `THREAD_LOCAL` | Metadata cache strategy | ``` ########## fesod-spring-boot-starter/src/main/java/org/apache/fesod/spring/boot/autoconfigure/FesodProperties.java: ########## @@ -0,0 +1,249 @@ +/* + * 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.spring.boot.autoconfigure; + +import java.util.Locale; +import org.apache.fesod.excel.enums.CacheLocationEnum; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Root configuration properties for Fesod Spring Boot starter. + * <p> + * All properties are bound under the prefix {@code fesod}. + * Example (application.yml): + * <pre> + * fesod: + * global: + * auto-trim: true + * locale: en_US + * reader: + * ignore-empty-row: true + * writer: + * in-memory: true + * </pre> + */ +@ConfigurationProperties(prefix = "fesod") +public class FesodProperties { + + /** Global shared configuration applied to both reading and writing. */ + private Global global = new Global(); + /** Reader specific configuration. */ + private Reader reader = new Reader(); + /** Writer specific configuration. */ + private Writer writer = new Writer(); + + public Global getGlobal() { + return global; + } + + public void setGlobal(Global global) { + this.global = global; + } + + public Reader getReader() { + return reader; + } + + public void setReader(Reader reader) { + this.reader = reader; + } + + public Writer getWriter() { + return writer; + } + + public void setWriter(Writer writer) { + this.writer = writer; + } + + /** + * Global configuration options that affect both reading and writing operations. + */ + public static class Global { + /** + * Whether to automatically trim leading and trailing whitespace from cell string values. + */ + private Boolean autoTrim; + /** + * Whether to automatically remove invisible / special control characters (strip) from cell values. + */ + private Boolean autoStrip; + /** + * Whether to interpret dates using the 1904 date windowing (common in older Mac Excel files). + */ + private Boolean use1904Windowing; + /** + * Whether numeric values which are large or small should be written using scientific notation. + */ + private Boolean useScientificFormat; + /** + * The default locale to use for formatting and parsing (e.g. number, date patterns). If not set, JVM default is used. + */ + private Locale locale; + /** + * Where to cache temporary file based data structures when writing / reading large workbooks. + */ + private CacheLocationEnum filedCacheLocation; Review Comment: The property name 'filedCacheLocation' appears to be misspelled. It should be 'fileCacheLocation' (without the 'd'). -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
