From 8ebbd1e063a2262cd4c398d47fd4101d2e2cb9d4 Mon Sep 17 00:00:00 2001 From: Kimi Liu <839536@qq.com> Date: Tue, 4 Jun 2024 17:24:57 +0800 Subject: [PATCH 01/16] v8.0.1 --- .../extra/image/gif/AnimatedGifEncoder.java | 25 +++++++++------ bus-tracer/pom.xml | 1 - .../dubbo/com.alibaba.dubbo.rpc.Filter | 2 -- ...xz.bus.tracer.backend.TraceBackendProvider | 1 - .../META-INF/tracer/tracer.default.properties | 32 ------------------- 5 files changed, 15 insertions(+), 46 deletions(-) delete mode 100755 bus-tracer/src/main/resources/META-INF/dubbo/com.alibaba.dubbo.rpc.Filter delete mode 100755 bus-tracer/src/main/resources/META-INF/services/org.miaixz.bus.tracer.backend.TraceBackendProvider delete mode 100644 bus-tracer/src/main/resources/META-INF/tracer/tracer.default.properties diff --git a/bus-extra/src/main/java/org/miaixz/bus/extra/image/gif/AnimatedGifEncoder.java b/bus-extra/src/main/java/org/miaixz/bus/extra/image/gif/AnimatedGifEncoder.java index a75fc95027..8ecc69e3b2 100755 --- a/bus-extra/src/main/java/org/miaixz/bus/extra/image/gif/AnimatedGifEncoder.java +++ b/bus-extra/src/main/java/org/miaixz/bus/extra/image/gif/AnimatedGifEncoder.java @@ -9,10 +9,8 @@ import java.io.OutputStream; /** - * Class AnimatedGifEncoder - Encodes a GIF file consisting of one or - * more frames. + * Gif编码压缩 *
- * Example: * AnimatedGifEncoder e = new AnimatedGifEncoder(); * e.start(outputFileName); * e.setDelay(1000); // 1 frame per sec @@ -20,25 +18,32 @@ * e.addFrame(image2); * e.finish(); *- * No copyright asserted on the source code of this class. May be used - * for any purpose, however, refer to the Unisys LZW patent for restrictions - * on use of the associated LZWEncoder class. Please forward any corrections - * to questions at fmsware.com. */ - public class AnimatedGifEncoder { - protected int width; // image size + /** + * 图片帧的宽度 + */ + protected int width; + /** + * 图片帧的高度 + */ protected int height; protected Color transparent = null; // transparent color if given protected boolean transparentExactMatch = false; // transparent color will be found by looking for the closest color // or for the exact color if transparentExactMatch == true protected Color background = null; // background color if given protected int transIndex; // transparent index in color table - protected int repeat = -1; // no repeat + /** + * 重复设置,0表示无限重复 + */ + protected int repeat = -1; protected int delay = 0; // frame delay (hundredths) protected boolean started = false; // ready to output frames protected OutputStream out; + /** + * 当前帧 + */ protected BufferedImage image; // current frame protected byte[] pixels; // BGR byte array from frame protected byte[] indexedPixels; // converted frame indexed to palette diff --git a/bus-tracer/pom.xml b/bus-tracer/pom.xml index bfa876aa07..4f5cff259c 100755 --- a/bus-tracer/pom.xml +++ b/bus-tracer/pom.xml @@ -43,7 +43,6 @@
- * response.setHeader("Content-Disposition", excelWriter.getDisposition("test.xlsx", Charset.CHARSET_UTF_8)); + * response.setHeader("Content-Disposition", excelWriter.getDisposition("test.xlsx", Charset.UTF_8)); ** * @param fileName 文件名,如果文件名没有扩展名,会自动按照生成Excel类型补齐扩展名,如果提供空,使用随机UUID @@ -609,4 +609,5 @@ public T clearHeaderAlias() { this.headerAlias = null; return (T) this; } + } diff --git a/bus-office/src/main/java/org/miaixz/bus/office/excel/ExcelDate.java b/bus-office/src/main/java/org/miaixz/bus/office/excel/ExcelDate.java deleted file mode 100644 index 25c5645ade..0000000000 --- a/bus-office/src/main/java/org/miaixz/bus/office/excel/ExcelDate.java +++ /dev/null @@ -1,102 +0,0 @@ -/********************************************************************************* - * * - * The MIT License (MIT) * - * * - * Copyright (c) 2015-2024 miaixz.org and other contributors. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy * - * of this software and associated documentation files (the "Software"), to deal * - * in the Software without restriction, including without limitation the rights * - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included in * - * all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * - * THE SOFTWARE. * - * * - ********************************************************************************/ -package org.miaixz.bus.office.excel; - -import org.apache.poi.ss.formula.ConditionalFormattingEvaluator; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.ExcelNumberFormat; -import org.miaixz.bus.core.xyz.ArrayKit; -import org.miaixz.bus.core.xyz.StringKit; - -/** - * Excel中日期判断、读取、处理等补充工具类 - * - * @author Kimi Liu - * @since Java 17+ - */ -public class ExcelDate { - - /** - * 某些特殊的自定义日期格式 - */ - private static final int[] customFormats = new int[]{28, 30, 31, 32, 33, 55, 56, 57, 58}; - - /** - * 是否日期格式 - * - * @param cell 单元格 - * @return 是否日期格式 - */ - public static boolean isDateFormat(final Cell cell) { - return isDateFormat(cell, null); - } - - /** - * 判断是否日期格式 - * - * @param cell 单元格 - * @param cfEvaluator {@link ConditionalFormattingEvaluator} - * @return 是否日期格式 - */ - public static boolean isDateFormat(final Cell cell, final ConditionalFormattingEvaluator cfEvaluator) { - final ExcelNumberFormat nf = ExcelNumberFormat.from(cell, cfEvaluator); - return isDateFormat(nf); - } - - /** - * 判断是否日期格式 - * - * @param numFmt {@link ExcelNumberFormat} - * @return 是否日期格式 - */ - public static boolean isDateFormat(final ExcelNumberFormat numFmt) { - return isDateFormat(numFmt.getIdx(), numFmt.getFormat()); - } - - /** - * 判断日期格式 - * - * @param formatIndex 格式索引,一般用于内建格式 - * @param formatString 格式字符串 - * @return 是否为日期格式 - */ - public static boolean isDateFormat(final int formatIndex, final String formatString) { - if (ArrayKit.contains(customFormats, formatIndex)) { - return true; - } - - // 自定义格式判断 - if (StringKit.isNotEmpty(formatString) && - StringKit.containsAny(formatString, "周", "星期", "aa")) { - // aa -> 周一 - // aaa -> 星期一 - return true; - } - - return org.apache.poi.ss.usermodel.DateUtil.isADateFormat(formatIndex, formatString); - } - -} diff --git a/bus-office/src/main/java/org/miaixz/bus/office/excel/ExcelFileKit.java b/bus-office/src/main/java/org/miaixz/bus/office/excel/ExcelFileKit.java deleted file mode 100644 index 0b89889104..0000000000 --- a/bus-office/src/main/java/org/miaixz/bus/office/excel/ExcelFileKit.java +++ /dev/null @@ -1,105 +0,0 @@ -/********************************************************************************* - * * - * The MIT License (MIT) * - * * - * Copyright (c) 2015-2024 miaixz.org and other contributors. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy * - * of this software and associated documentation files (the "Software"), to deal * - * in the Software without restriction, including without limitation the rights * - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included in * - * all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * - * THE SOFTWARE. * - * * - ********************************************************************************/ -package org.miaixz.bus.office.excel; - -import org.apache.poi.poifs.filesystem.FileMagic; -import org.miaixz.bus.core.lang.exception.InternalException; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; - -/** - * Excel文件工具类 - * - * @author Kimi Liu - * @since Java 17+ - */ -public class ExcelFileKit { - - /** - * 是否为XLS格式的Excel文件(HSSF) - * XLS文件主要用于Excel 97~2003创建 - * 此方法会自动调用{@link InputStream#reset()}方法 - * - * @param in excel输入流 - * @return 是否为XLS格式的Excel文件(HSSF) - */ - public static boolean isXls(final InputStream in) { - return FileMagic.OLE2 == getFileMagic(in); - } - - /** - * 是否为XLSX格式的Excel文件(XSSF) - * XLSX文件主要用于Excel 2007+创建 - * 此方法会自动调用{@link InputStream#reset()}方法 - * - * @param in excel输入流 - * @return 是否为XLSX格式的Excel文件(XSSF) - */ - public static boolean isXlsx(final InputStream in) { - return FileMagic.OOXML == getFileMagic(in); - } - - /** - * 是否为XLSX格式的Excel文件(XSSF) - * XLSX文件主要用于Excel 2007+创建 - * - * @param file excel文件 - * @return 是否为XLSX格式的Excel文件(XSSF) - */ - public static boolean isXlsx(final File file) { - try { - return FileMagic.valueOf(file) == FileMagic.OOXML; - } catch (final IOException e) { - throw new InternalException(e); - } - } - - /** - * {@link java.io.PushbackInputStream} - * PushbackInputStream的markSupported()为false,并不支持mark和reset - * 如果强转成PushbackInputStream在调用FileMagic.valueOf(inputStream)时会报错 - * {@link FileMagic} - * 报错内容:getFileMagic() only operates on streams which support mark(int) - * 此处修改成 final InputStream in = FileMagic.prepareToCheckMagic(in) - * - * @param in {@link InputStream} - * kefan.qu - */ - private static FileMagic getFileMagic(InputStream in) { - final FileMagic magic; - in = FileMagic.prepareToCheckMagic(in); - try { - magic = FileMagic.valueOf(in); - } catch (final IOException e) { - throw new InternalException(e); - } - - return magic; - } - -} diff --git a/bus-office/src/main/java/org/miaixz/bus/office/excel/ExcelKit.java b/bus-office/src/main/java/org/miaixz/bus/office/excel/ExcelKit.java index 617bb39f73..d8d1a051f1 100644 --- a/bus-office/src/main/java/org/miaixz/bus/office/excel/ExcelKit.java +++ b/bus-office/src/main/java/org/miaixz/bus/office/excel/ExcelKit.java @@ -29,9 +29,7 @@ import org.miaixz.bus.core.xyz.FileKit; import org.miaixz.bus.core.xyz.IoKit; import org.miaixz.bus.core.xyz.ObjectKit; -import org.miaixz.bus.office.Registry; -import org.miaixz.bus.office.excel.cell.CellLocation; -import org.miaixz.bus.office.excel.cell.CellLocationKit; +import org.miaixz.bus.office.Builder; import org.miaixz.bus.office.excel.sax.ExcelSax; import org.miaixz.bus.office.excel.sax.ExcelSaxReader; import org.miaixz.bus.office.excel.sax.handler.RowHandler; @@ -87,7 +85,7 @@ public static void readBySax(final String path, final String idOrRid, final RowH * @param rowHandler 行处理器 */ public static void readBySax(final File file, final int rid, final RowHandler rowHandler) { - final ExcelSaxReader> reader = ExcelSax.createSaxReader(ExcelFileKit.isXlsx(file), rowHandler); + final ExcelSaxReader> reader = ExcelSax.createSaxReader(Builder.isXlsx(file), rowHandler); reader.read(file, rid); } @@ -99,7 +97,7 @@ public static void readBySax(final File file, final int rid, final RowHandler ro * @param rowHandler 行处理器 */ public static void readBySax(final File file, final String idOrRidOrSheetName, final RowHandler rowHandler) { - final ExcelSaxReader> reader = ExcelSax.createSaxReader(ExcelFileKit.isXlsx(file), rowHandler); + final ExcelSaxReader> reader = ExcelSax.createSaxReader(Builder.isXlsx(file), rowHandler); reader.read(file, idOrRidOrSheetName); } @@ -112,7 +110,7 @@ public static void readBySax(final File file, final String idOrRidOrSheetName, f */ public static void readBySax(InputStream in, final int rid, final RowHandler rowHandler) { in = IoKit.toMarkSupport(in); - final ExcelSaxReader> reader = ExcelSax.createSaxReader(ExcelFileKit.isXlsx(in), rowHandler); + final ExcelSaxReader> reader = ExcelSax.createSaxReader(Builder.isXlsx(in), rowHandler); reader.read(in, rid); } @@ -125,7 +123,7 @@ public static void readBySax(InputStream in, final int rid, final RowHandler row */ public static void readBySax(InputStream in, final String idOrRidOrSheetName, final RowHandler rowHandler) { in = IoKit.toMarkSupport(in); - final ExcelSaxReader> reader = ExcelSax.createSaxReader(ExcelFileKit.isXlsx(in), rowHandler); + final ExcelSaxReader> reader = ExcelSax.createSaxReader(Builder.isXlsx(in), rowHandler); reader.read(in, idOrRidOrSheetName); } @@ -162,7 +160,7 @@ public static ExcelReader getReader(final String bookFilePath, final int sheetIn try { return new ExcelReader(bookFilePath, sheetIndex); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -177,7 +175,7 @@ public static ExcelReader getReader(final String bookFilePath, final String shee try { return new ExcelReader(bookFilePath, sheetName); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -192,7 +190,7 @@ public static ExcelReader getReader(final File bookFile, final int sheetIndex) { try { return new ExcelReader(bookFile, sheetIndex); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -207,7 +205,7 @@ public static ExcelReader getReader(final File bookFile, final String sheetName) try { return new ExcelReader(bookFile, sheetName); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -234,7 +232,7 @@ public static ExcelReader getReader(final InputStream bookStream, final int shee try { return new ExcelReader(bookStream, sheetIndex); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -250,7 +248,7 @@ public static ExcelReader getReader(final InputStream bookStream, final String s try { return new ExcelReader(bookStream, sheetName); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -265,7 +263,7 @@ public static ExcelWriter getWriter() { try { return new ExcelWriter(); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -281,7 +279,7 @@ public static ExcelWriter getWriter(final boolean isXlsx) { try { return new ExcelWriter(isXlsx); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -295,7 +293,7 @@ public static ExcelWriter getWriter(final String destFilePath) { try { return new ExcelWriter(destFilePath); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -309,7 +307,7 @@ public static ExcelWriter getWriterWithSheet(final String sheetName) { try { return new ExcelWriter((File) null, sheetName); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -323,7 +321,7 @@ public static ExcelWriter getWriter(final File destFile) { try { return new ExcelWriter(destFile); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -338,7 +336,7 @@ public static ExcelWriter getWriter(final String destFilePath, final String shee try { return new ExcelWriter(destFilePath, sheetName); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -353,7 +351,7 @@ public static ExcelWriter getWriter(final File destFile, final String sheetName) try { return new ExcelWriter(destFile, sheetName); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -368,7 +366,7 @@ public static BigExcelWriter getBigWriter() { try { return new BigExcelWriter(); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -384,7 +382,7 @@ public static BigExcelWriter getBigWriter(final int rowAccessWindowSize) { try { return new BigExcelWriter(rowAccessWindowSize); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -398,7 +396,7 @@ public static BigExcelWriter getBigWriter(final String destFilePath) { try { return new BigExcelWriter(destFilePath); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -412,7 +410,7 @@ public static BigExcelWriter getBigWriter(final File destFile) { try { return new BigExcelWriter(destFile); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -427,7 +425,7 @@ public static BigExcelWriter getBigWriter(final String destFilePath, final Strin try { return new BigExcelWriter(destFilePath, sheetName); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } @@ -442,39 +440,8 @@ public static BigExcelWriter getBigWriter(final File destFile, final String shee try { return new BigExcelWriter(destFile, sheetName); } catch (final NoClassDefFoundError e) { - throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Registry.NO_POI_ERROR_MSG); + throw new DependencyException(ObjectKit.defaultIfNull(e.getCause(), e), Builder.NO_POI_ERROR_MSG); } } - /** - * 将Sheet列号变为列名 - * - * @param index 列号, 从0开始 - * @return 0-A; 1-B...26-AA - */ - public static String indexToColName(final int index) { - return CellLocationKit.indexToColName(index); - } - - /** - * 根据表元的列名转换为列号 - * - * @param colName 列名, 从A开始 - * @return A1-0; B1-1...AA1-26 - */ - public static int colNameToIndex(final String colName) { - return CellLocationKit.colNameToIndex(colName); - } - - /** - * 将Excel中地址标识符(例如A11,B5)等转换为行列表示 - * 例如:A11 - x:0,y:10,B5-x:1,y:4 - * - * @param locationRef 单元格地址标识符,例如A11,B5 - * @return 坐标点,x表示行,从0开始,y表示列,从0开始 - */ - public static CellLocation toLocation(final String locationRef) { - return CellLocationKit.toLocation(locationRef); - } - } diff --git a/bus-office/src/main/java/org/miaixz/bus/office/excel/ExcelPicKit.java b/bus-office/src/main/java/org/miaixz/bus/office/excel/ExcelPicKit.java deleted file mode 100644 index 80e513aa4b..0000000000 --- a/bus-office/src/main/java/org/miaixz/bus/office/excel/ExcelPicKit.java +++ /dev/null @@ -1,126 +0,0 @@ -/********************************************************************************* - * * - * The MIT License (MIT) * - * * - * Copyright (c) 2015-2024 miaixz.org and other contributors. * - * * - * Permission is hereby granted, free of charge, to any person obtaining a copy * - * of this software and associated documentation files (the "Software"), to deal * - * in the Software without restriction, including without limitation the rights * - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * - * copies of the Software, and to permit persons to whom the Software is * - * furnished to do so, subject to the following conditions: * - * * - * The above copyright notice and this permission notice shall be included in * - * all copies or substantial portions of the Software. * - * * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * - * THE SOFTWARE. * - * * - ********************************************************************************/ -package org.miaixz.bus.office.excel; - -import org.apache.poi.hssf.usermodel.*; -import org.apache.poi.ooxml.POIXMLDocumentPart; -import org.apache.poi.ss.usermodel.PictureData; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.xssf.usermodel.*; -import org.miaixz.bus.core.center.map.multi.ListValueMap; -import org.miaixz.bus.core.lang.Assert; -import org.miaixz.bus.core.xyz.CollKit; -import org.miaixz.bus.core.xyz.StringKit; -import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; - -import java.util.List; - -/** - * Excel图片工具类 - * - * @author Kimi Liu - * @since Java 17+ - */ -public class ExcelPicKit { - - /** - * 获取工作簿指定sheet中图片列表 - * - * @param workbook 工作簿{@link Workbook} - * @param sheetIndex sheet的索引 - * @return 图片映射,键格式:行_列,值:{@link PictureData} - */ - public static ListValueMap
@@ -733,7 +709,6 @@ public ExcelWriter write(final Iterable> data) { /** * 写出数据,本方法只是将数据写入Workbook中的Sheet,并不写出到文件 * 写出的起始行为当前行号,可使用{@link #getCurrentRow()}方法调用,根据写出的的行数,当前行号自动增加 - * 样式为默认样式,可使用{@link #getCellStyle()}方法调用后自定义默认样式 * *
* data中元素支持的类型有: @@ -764,7 +739,6 @@ public ExcelWriter write(final Iterable> data, final boolean isWriteKeyAsHead) /** * 写出数据,本方法只是将数据写入Workbook中的Sheet,并不写出到文件 * 写出的起始行为当前行号,可使用{@link #getCurrentRow()}方法调用,根据写出的的行数,当前行号自动增加 - * 样式为默认样式,可使用{@link #getCellStyle()}方法调用后自定义默认样式 * data中元素支持的类型有: * *
@@ -805,7 +779,6 @@ public ExcelWriter write(final Iterable> data, final Comparator
* 此方法的逻辑是:将一行数据写出到当前行,遇到已存在的单元格跳过,不存在的创建并赋值。
@@ -978,7 +946,7 @@ public ExcelWriter writeRow(final Object rowBean, final boolean isWriteKeyAsHead
} else if (rowBean instanceof Hyperlink) {
// Hyperlink当成一个值
return writeRow(ListKit.of(rowBean), isWriteKeyAsHead);
- } else if (BeanKit.isWritableBean(rowBean.getClass())) {
+ } else if (BeanKit.isReadableBean(rowBean.getClass())) {
if (MapKit.isEmpty(this.headerAlias)) {
rowMap = BeanKit.beanToMap(rowBean, new LinkedHashMap<>(), false, false);
} else {
@@ -1044,7 +1012,6 @@ public ExcelWriter writeRow(final Map, ?> rowMap, final boolean isWriteKeyAsHe
* 写出一行数据
* 本方法只是将数据写入Workbook中的Sheet,并不写出到文件
* 写出的起始行为当前行号,可使用{@link #getCurrentRow()}方法调用,根据写出的的行数,当前行号自动+1
- * 样式为默认样式,可使用{@link #getCellStyle()}方法调用后自定义默认样式
*
* @param rowData 一行的数据
* @return this
@@ -1059,7 +1026,6 @@ public ExcelWriter writeRow(final Iterable> rowData) {
* 从第1列开始按列写入数据(index 从0开始)
* 本方法只是将数据写入Workbook中的Sheet,并不写出到文件
* 写出的起始行为当前行号,可使用{@link #getCurrentRow()}方法调用,根据写出的的行数,当前行号自动+1
- * 样式为默认样式,可使用{@link #getCellStyle()}方法调用后自定义默认样式
*
* @param colMap 一列的数据
* @param isWriteKeyAsHead 是否将Map的Key作为表头输出,如果为True第一行为表头,紧接着为values
@@ -1073,7 +1039,6 @@ public ExcelWriter writeCol(final Map, ? extends Iterable>> colMap, final bo
* 从指定列开始按列写入数据(index 从0开始)
* 本方法只是将数据写入Workbook中的Sheet,并不写出到文件
* 写出的起始行为当前行号,可使用{@link #getCurrentRow()}方法调用,根据写出的的行数,当前行号自动+1
- * 样式为默认样式,可使用{@link #getCellStyle()}方法调用后自定义默认样式
*
* @param colMap 一列的数据
* @param startColIndex 起始的列号,从0开始
@@ -1096,7 +1061,6 @@ public ExcelWriter writeCol(final Map, ? extends Iterable>> colMap, int star
* 为第一列写入数据
* 本方法只是将数据写入Workbook中的Sheet,并不写出到文件
* 写出的起始行为当前行号,可使用{@link #getCurrentRow()}方法调用,根据写出的的行数,当前行号自动+1
- * 样式为默认样式,可使用{@link #getCellStyle()}方法调用后自定义默认样式
*
* @param headerVal 表头名称,如果为null则不写入
* @param colData 需要写入的列数据
@@ -1111,7 +1075,6 @@ public ExcelWriter writeCol(final Object headerVal, final Iterable> colData, f
* 为第指定列写入数据
* 本方法只是将数据写入Workbook中的Sheet,并不写出到文件
* 写出的起始行为当前行号,可使用{@link #getCurrentRow()}方法调用,根据写出的的行数,当前行号自动+1
- * 样式为默认样式,可使用{@link #getCellStyle()}方法调用后自定义默认样式
*
* @param headerVal 表头名称,如果为null则不写入
* @param colIndex 列index
@@ -1144,8 +1107,8 @@ public ExcelWriter writeCol(final Object headerVal, final int colIndex, final It
* @return this
*/
public ExcelWriter writeCellValue(final String locationRef, final Object value) {
- final CellLocation cellLocation = ExcelKit.toLocation(locationRef);
- return writeCellValue(cellLocation.getX(), cellLocation.getY(), value);
+ final CellReference cellReference = new CellReference(locationRef);
+ return writeCellValue(cellReference.getCol(), cellReference.getRow(), value);
}
/**
@@ -1179,8 +1142,6 @@ public ExcelWriter writeCellValue(final int x, final int y, final Object value,
* 设置某个单元格的样式
* 此方法用于多个单元格共享样式的情况
* 可以调用{@link #getOrCreateCellStyle(int, int)} 方法创建或取得一个样式对象。
- *
- *
* 需要注意的是,共享样式会共享同一个{@link CellStyle},一个单元格样式改变,全部改变。
*
* @param style 单元格样式
@@ -1188,16 +1149,14 @@ public ExcelWriter writeCellValue(final int x, final int y, final Object value,
* @return this
*/
public ExcelWriter setStyle(final CellStyle style, final String locationRef) {
- final CellLocation cellLocation = ExcelKit.toLocation(locationRef);
- return setStyle(style, cellLocation.getX(), cellLocation.getY());
+ final CellReference cellReference = new CellReference(locationRef);
+ return setStyle(style, cellReference.getCol(), cellReference.getRow());
}
/**
* 设置某个单元格的样式
* 此方法用于多个单元格共享样式的情况
* 可以调用{@link #getOrCreateCellStyle(int, int)} 方法创建或取得一个样式对象。
- *
- *
* 需要注意的是,共享样式会共享同一个{@link CellStyle},一个单元格样式改变,全部改变。
*
* @param style 单元格样式
@@ -1226,7 +1185,6 @@ public ExcelWriter setRowStyle(final int y, final CellStyle style) {
/**
* 对数据行整行加自定义样式 仅对数据单元格设置 write后调用
- *
* {@link ExcelWriter#setRowStyle(int, org.apache.poi.ss.usermodel.CellStyle)}
* 这个方法加的样式会使整行没有数据的单元格也有样式
* 特别是加背景色时很不美观 且有数据的单元格样式会被StyleSet中的样式覆盖掉
@@ -1237,7 +1195,7 @@ public ExcelWriter setRowStyle(final int y, final CellStyle style) {
*/
public ExcelWriter setRowStyleIfHasData(final int y, final CellStyle style) {
if (y < 0) {
- throw new IllegalArgumentException("Invalid row number (" + y + Symbol.PARENTHESE_RIGHT);
+ throw new IllegalArgumentException("Invalid row number (" + y + ")");
}
final int columnCount = this.getColumnCount();
for (int i = 0; i < columnCount; i++) {
@@ -1260,7 +1218,6 @@ public ExcelWriter setColumnStyle(final int x, final CellStyle style) {
/**
* 设置整个列的样式 仅对数据单元格设置 write后调用
- *
* {@link ExcelWriter#setColumnStyle(int, org.apache.poi.ss.usermodel.CellStyle)}
* 这个方法加的样式会使整列没有数据的单元格也有样式
* 特别是加背景色时很不美观 且有数据的单元格样式会被StyleSet中的样式覆盖掉
diff --git a/bus-office/src/main/java/org/miaixz/bus/office/excel/RowKit.java b/bus-office/src/main/java/org/miaixz/bus/office/excel/RowKit.java
index 25e58892a5..9d21647dc0 100644
--- a/bus-office/src/main/java/org/miaixz/bus/office/excel/RowKit.java
+++ b/bus-office/src/main/java/org/miaixz/bus/office/excel/RowKit.java
@@ -34,6 +34,7 @@
import org.miaixz.bus.core.xyz.StringKit;
import org.miaixz.bus.office.excel.cell.CellEditor;
import org.miaixz.bus.office.excel.cell.CellKit;
+import org.miaixz.bus.office.excel.style.StyleSet;
import java.util.ArrayList;
import java.util.List;
@@ -219,4 +220,5 @@ public static void removeRow(final Row row) {
}
}
}
+
}
diff --git a/bus-office/src/main/java/org/miaixz/bus/office/excel/cell/CellKit.java b/bus-office/src/main/java/org/miaixz/bus/office/excel/cell/CellKit.java
index 4ba9430d4a..7ec908fedb 100644
--- a/bus-office/src/main/java/org/miaixz/bus/office/excel/cell/CellKit.java
+++ b/bus-office/src/main/java/org/miaixz/bus/office/excel/cell/CellKit.java
@@ -27,16 +27,15 @@
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.ss.util.CellReference;
import org.apache.poi.ss.util.RegionUtil;
import org.apache.poi.ss.util.SheetUtil;
-import org.miaixz.bus.core.lang.Normal;
import org.miaixz.bus.core.xyz.ObjectKit;
-import org.miaixz.bus.office.excel.ExcelKit;
-import org.miaixz.bus.office.excel.StyleSet;
+import org.miaixz.bus.core.xyz.StringKit;
import org.miaixz.bus.office.excel.cell.editors.TrimEditor;
import org.miaixz.bus.office.excel.cell.setters.CellSetterFactory;
-import org.miaixz.bus.office.excel.cell.values.ErrorCellValue;
-import org.miaixz.bus.office.excel.cell.values.NumericCellValue;
+import org.miaixz.bus.office.excel.cell.values.CompositeCellValue;
+import org.miaixz.bus.office.excel.style.StyleSet;
/**
* Excel表格中单元格工具类
@@ -102,46 +101,8 @@ public static Object getCellValue(final Cell cell, final CellType cellType, fina
* @param cellEditor 单元格值编辑器。可以通过此编辑器对单元格值做自定义操作
* @return 值,类型可能为:Date、Double、Boolean、String
*/
- public static Object getCellValue(Cell cell, CellType cellType, final CellEditor cellEditor) {
- if (null == cell) {
- return null;
- }
- if (cell instanceof NullCell) {
- return null == cellEditor ? null : cellEditor.edit(cell, null);
- }
- if (null == cellType) {
- cellType = cell.getCellType();
- }
-
- // 尝试获取合并单元格,如果是合并单元格,则重新获取单元格类型
- final Cell mergedCell = getMergedRegionCell(cell);
- if (mergedCell != cell) {
- cell = mergedCell;
- cellType = cell.getCellType();
- }
-
- final Object value;
- switch (cellType) {
- case NUMERIC:
- value = new NumericCellValue(cell).getValue();
- break;
- case BOOLEAN:
- value = cell.getBooleanCellValue();
- break;
- case FORMULA:
- value = getCellValue(cell, cell.getCachedFormulaResultType(), cellEditor);
- break;
- case BLANK:
- value = Normal.EMPTY;
- break;
- case ERROR:
- value = new ErrorCellValue(cell).getValue();
- break;
- default:
- value = cell.getStringCellValue();
- }
-
- return null == cellEditor ? value : cellEditor.edit(cell, value);
+ public static Object getCellValue(final Cell cell, final CellType cellType, final CellEditor cellEditor) {
+ return CompositeCellValue.of(cell, cellType, cellEditor).getValue();
}
/**
@@ -160,11 +121,12 @@ public static void setCellValue(final Cell cell, final Object value, final Style
return;
}
+ CellStyle cellStyle = null;
if (null != styleSet) {
- cell.setCellStyle(styleSet.getStyleByValueType(value, isHeader));
+ cellStyle = styleSet.getStyleFor(new CellReference(cell), value, isHeader);
}
- setCellValue(cell, value, cellEditor);
+ setCellValue(cell, value, cellStyle, cellEditor);
}
/**
@@ -262,51 +224,6 @@ public static Cell getOrCreateCell(final Row row, final int cellIndex) {
return cell;
}
- /**
- * 获取合并单元格{@link CellRangeAddress},如果不是返回null
- *
- * @param sheet {@link Sheet}
- * @param locationRef 单元格地址标识符,例如A11,B5
- * @return {@link CellRangeAddress}
- */
- public static CellRangeAddress getCellRangeAddress(final Sheet sheet, final String locationRef) {
- final CellLocation cellLocation = ExcelKit.toLocation(locationRef);
- return getCellRangeAddress(sheet, cellLocation.getX(), cellLocation.getY());
- }
-
- /**
- * 获取合并单元格{@link CellRangeAddress},如果不是返回null
- *
- * @param cell {@link Cell}
- * @return {@link CellRangeAddress}
- */
- public static CellRangeAddress getCellRangeAddress(final Cell cell) {
- return getCellRangeAddress(cell.getSheet(), cell.getColumnIndex(), cell.getRowIndex());
- }
-
- /**
- * 获取合并单元格{@link CellRangeAddress},如果不是返回null
- *
- * @param sheet {@link Sheet}
- * @param x 列号,从0开始
- * @param y 行号,从0开始
- * @return {@link CellRangeAddress}
- */
- public static CellRangeAddress getCellRangeAddress(final Sheet sheet, final int x, final int y) {
- if (sheet != null) {
- final int sheetMergeCount = sheet.getNumMergedRegions();
- CellRangeAddress ca;
- for (int i = 0; i < sheetMergeCount; i++) {
- ca = sheet.getMergedRegion(i);
- if (y >= ca.getFirstRow() && y <= ca.getLastRow()
- && x >= ca.getFirstColumn() && x <= ca.getLastColumn()) {
- return ca;
- }
- }
- }
- return null;
- }
-
/**
* 判断指定的单元格是否是合并单元格
*
@@ -315,8 +232,8 @@ public static CellRangeAddress getCellRangeAddress(final Sheet sheet, final int
* @return 是否是合并单元格
*/
public static boolean isMergedRegion(final Sheet sheet, final String locationRef) {
- final CellLocation cellLocation = ExcelKit.toLocation(locationRef);
- return isMergedRegion(sheet, cellLocation.getX(), cellLocation.getY());
+ final CellReference cellReference = new CellReference(locationRef);
+ return isMergedRegion(sheet, cellReference.getCol(), cellReference.getRow());
}
/**
@@ -353,36 +270,23 @@ public static boolean isMergedRegion(final Sheet sheet, final int x, final int y
/**
* 合并单元格,可以根据设置的值来合并行和列
*
- * @param sheet 表对象
- * @param firstRow 起始行,0开始
- * @param lastRow 结束行,0开始
- * @param firstColumn 起始列,0开始
- * @param lastColumn 结束列,0开始
+ * @param sheet 表对象
+ * @param cellRangeAddress 合并单元格范围,定义了起始行列和结束行列
* @return 合并后的单元格号
*/
- public static int mergingCells(final Sheet sheet, final int firstRow, final int lastRow, final int firstColumn, final int lastColumn) {
- return mergingCells(sheet, firstRow, lastRow, firstColumn, lastColumn, null);
+ public static int mergingCells(final Sheet sheet, final CellRangeAddress cellRangeAddress) {
+ return mergingCells(sheet, cellRangeAddress, null);
}
/**
* 合并单元格,可以根据设置的值来合并行和列
*
- * @param sheet 表对象
- * @param firstRow 起始行,0开始
- * @param lastRow 结束行,0开始
- * @param firstColumn 起始列,0开始
- * @param lastColumn 结束列,0开始
- * @param cellStyle 单元格样式,只提取边框样式,null表示无样式
+ * @param sheet 表对象
+ * @param cellRangeAddress 合并单元格范围,定义了起始行列和结束行列
+ * @param cellStyle 单元格样式,只提取边框样式,null表示无样式
* @return 合并后的单元格号
*/
- public static int mergingCells(final Sheet sheet, final int firstRow, final int lastRow, final int firstColumn, final int lastColumn, final CellStyle cellStyle) {
- final CellRangeAddress cellRangeAddress = new CellRangeAddress(//
- firstRow, // first row (0-based)
- lastRow, // last row (0-based)
- firstColumn, // first column (0-based)
- lastColumn // last column (0-based)
- );
-
+ public static int mergingCells(final Sheet sheet, final CellRangeAddress cellRangeAddress, final CellStyle cellStyle) {
setMergeCellStyle(cellStyle, cellRangeAddress, sheet);
return sheet.addMergedRegion(cellRangeAddress);
}
@@ -396,8 +300,8 @@ public static int mergingCells(final Sheet sheet, final int firstRow, final int
* @return 合并单元格的值
*/
public static Object getMergedRegionValue(final Sheet sheet, final String locationRef) {
- final CellLocation cellLocation = ExcelKit.toLocation(locationRef);
- return getMergedRegionValue(sheet, cellLocation.getX(), cellLocation.getY());
+ final CellReference cellReference = new CellReference(locationRef);
+ return getMergedRegionValue(sheet, cellReference.getCol(), cellReference.getRow());
}
/**
@@ -479,7 +383,6 @@ public static void setComment(final Cell cell, final String commentText, final S
}
final Comment comment = sheet.createDrawingPatriarch().createCellComment(anchor);
- // https://stackoverflow.com/questions/28169011/using-sxssfapache-poi-and-adding-comment-does-not-generate-proper-excel-file
// 修正在XSSFCell中未设置地址导致错位问题
comment.setAddress(cell.getAddress());
comment.setString(factory.createRichTextString(commentText));
@@ -527,4 +430,179 @@ private static void setMergeCellStyle(final CellStyle cellStyle, final CellRange
}
}
+ /**
+ * 根据字符串表示法创建一个CellRangeAddress对象
+ * 该方法提供了一种通过直接使用字符串引用来创建CellRangeAddress对象的便捷方式
+ * 字符串引用应符合Excel中单元格范围的常规表示法,如"B1" 或 "A1:B2"。
+ *
+ * @param ref 代表单元格范围的字符串,格式为"A1:B2"。
+ * @return 根据给定字符串创建的CellRangeAddress对象。
+ * @see CellRangeAddress#valueOf(String)
+ */
+ public static CellRangeAddress of(final String ref) {
+ return CellRangeAddress.valueOf(ref);
+ }
+
+ /**
+ * 根据给定的行和列索引创建一个CellRangeAddress对象
+ * 这个方法提供了一种简洁的方式,来表示一个Excel表格中特定的区域,由起始行和列以及结束行和列定义。
+ *
+ * @param firstRow 起始行的索引,从0开始计数。
+ * @param lastRow 结束行的索引,从0开始计数,必须大于firstRow。
+ * @param firstCol 起始列的索引,从0开始计数。
+ * @param lastCol 结束列的索引,从0开始计数,必须大于firstCol。
+ * @return 返回一个新的CellRangeAddress对象,表示由参数定义的区域。
+ */
+ public static CellRangeAddress of(final int firstRow, final int lastRow, final int firstCol, final int lastCol) {
+ return new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
+ }
+
+ /**
+ * 根据给定的行和列索引创建一个单行的CellRangeAddress对象,从首列开始。
+ * 这个方法提供了一种简洁的方式,来表示一个Excel表格中特定的区域,由起始行和列以及结束行和列定义。
+ *
+ * @param row 行的索引,从0开始计数。
+ * @param lastCol 结束列的索引,从0开始计数,必须大于firstCol。
+ * @return 返回一个新的CellRangeAddress对象,表示由参数定义的区域。
+ */
+ public static CellRangeAddress ofSingleRow(final int row, final int lastCol) {
+ return ofSingleRow(row, 0, lastCol);
+ }
+
+ /**
+ * 根据给定的行和列索引创建一个单行的CellRangeAddress对象
+ * 这个方法提供了一种简洁的方式,来表示一个Excel表格中特定的区域,由起始行和列以及结束行和列定义。
+ *
+ * @param row 行的索引,从0开始计数。
+ * @param firstCol 起始列的索引,从0开始计数。
+ * @param lastCol 结束列的索引,从0开始计数,必须大于firstCol。
+ * @return 返回一个新的CellRangeAddress对象,表示由参数定义的区域。
+ */
+ public static CellRangeAddress ofSingleRow(final int row, final int firstCol, final int lastCol) {
+ return of(row, row, firstCol, lastCol);
+ }
+
+ /**
+ * 根据给定的行和列索引创建一个单列CellRangeAddress对象,从首行开始。
+ * 这个方法提供了一种简洁的方式,来表示一个Excel表格中特定的区域,由起始行和列以及结束行和列定义。
+ *
+ * @param lastRow 结束行的索引,从0开始计数,必须大于firstRow。
+ * @param col 列的索引,从0开始计数。
+ * @return 返回一个新的CellRangeAddress对象,表示由参数定义的区域。
+ */
+ public static CellRangeAddress ofSingleColumn(final int lastRow, final int col) {
+ return ofSingleColumn(0, lastRow, col);
+ }
+
+ /**
+ * 根据给定的行和列索引创建一个单列CellRangeAddress对象。
+ * 这个方法提供了一种简洁的方式,来表示一个Excel表格中特定的区域,由起始行和列以及结束行和列定义。
+ *
+ * @param firstRow 起始行的索引,从0开始计数。
+ * @param lastRow 结束行的索引,从0开始计数,必须大于firstRow。
+ * @param col 列的索引,从0开始计数。
+ * @return 返回一个新的CellRangeAddress对象,表示由参数定义的区域。
+ */
+ public static CellRangeAddress ofSingleColumn(final int firstRow, final int lastRow, final int col) {
+ return of(firstRow, lastRow, col, col);
+ }
+
+ /**
+ * 获取合并单元格{@link CellRangeAddress},如果不是返回null
+ *
+ * @param sheet {@link Sheet}
+ * @param locationRef 单元格地址标识符,例如A11,B5
+ * @return {@link CellRangeAddress}
+ */
+ public static CellRangeAddress getCellRangeAddress(final Sheet sheet, final String locationRef) {
+ final CellReference cellReference = new CellReference(locationRef);
+ return getCellRangeAddress(sheet, cellReference.getCol(), cellReference.getRow());
+ }
+
+ /**
+ * 获取合并单元格{@link CellRangeAddress},如果不是返回null
+ *
+ * @param cell {@link Cell}
+ * @return {@link CellRangeAddress}
+ */
+ public static CellRangeAddress getCellRangeAddress(final Cell cell) {
+ return getCellRangeAddress(cell.getSheet(), cell.getColumnIndex(), cell.getRowIndex());
+ }
+
+ /**
+ * 获取合并单元格{@link CellRangeAddress},如果不是返回null
+ *
+ * @param sheet {@link Sheet}
+ * @param x 列号,从0开始
+ * @param y 行号,从0开始
+ * @return {@link CellRangeAddress}
+ */
+ public static CellRangeAddress getCellRangeAddress(final Sheet sheet, final int x, final int y) {
+ if (sheet != null) {
+ final int sheetMergeCount = sheet.getNumMergedRegions();
+ CellRangeAddress ca;
+ for (int i = 0; i < sheetMergeCount; i++) {
+ ca = sheet.getMergedRegion(i);
+ if (y >= ca.getFirstRow() && y <= ca.getLastRow()
+ && x >= ca.getFirstColumn() && x <= ca.getLastColumn()) {
+ return ca;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * 将Sheet列号变为列名
+ *
+ * @param index 列号, 从0开始
+ * @return 0-A; 1-B...26-AA
+ */
+ public static String indexToColName(int index) {
+ if (index < 0) {
+ return null;
+ }
+ final StringBuilder colName = StringKit.builder();
+ do {
+ if (colName.length() > 0) {
+ index--;
+ }
+ final int remainder = index % 26;
+ colName.append((char) (remainder + 'A'));
+ index = (index - remainder) / 26;
+ } while (index > 0);
+ return colName.reverse().toString();
+ }
+
+ /**
+ * 根据表元的列名转换为列号
+ *
+ * @param colName 列名, 从A开始
+ * @return A1-0; B1-1...AA1-26
+ */
+ public static int colNameToIndex(final String colName) {
+ final int length = colName.length();
+ char c;
+ int index = -1;
+ for (int i = 0; i < length; i++) {
+ c = Character.toUpperCase(colName.charAt(i));
+ if (Character.isDigit(c)) {
+ break;// 确定指定的char值是否为数字
+ }
+ index = (index + 1) * 26 + (int) c - 'A';
+ }
+ return index;
+ }
+
+ /**
+ * 将Excel中地址标识符(例如A11,B5)等转换为行列表示
+ * 例如:A11 - col:0,row:10,B5-col:1,row:4
+ *
+ * @param locationRef 单元格地址标识符,例如A11,B5
+ * @return 坐标点
+ */
+ public static CellReference toCellReference(final String locationRef) {
+ return new CellReference(locationRef);
+ }
+
}
diff --git a/bus-office/src/main/java/org/miaixz/bus/office/excel/cell/CellLocationKit.java b/bus-office/src/main/java/org/miaixz/bus/office/excel/cell/CellLocationKit.java
deleted file mode 100644
index 9df0e32aeb..0000000000
--- a/bus-office/src/main/java/org/miaixz/bus/office/excel/cell/CellLocationKit.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*********************************************************************************
- * *
- * The MIT License (MIT) *
- * *
- * Copyright (c) 2015-2024 miaixz.org and other contributors. *
- * *
- * Permission is hereby granted, free of charge, to any person obtaining a copy *
- * of this software and associated documentation files (the "Software"), to deal *
- * in the Software without restriction, including without limitation the rights *
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
- * copies of the Software, and to permit persons to whom the Software is *
- * furnished to do so, subject to the following conditions: *
- * *
- * The above copyright notice and this permission notice shall be included in *
- * all copies or substantial portions of the Software. *
- * *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN *
- * THE SOFTWARE. *
- * *
- ********************************************************************************/
-package org.miaixz.bus.office.excel.cell;
-
-import org.miaixz.bus.core.xyz.PatternKit;
-import org.miaixz.bus.core.xyz.StringKit;
-
-/**
- * 单元格位置工具类,提供包括行号转行名称、列号转列名称等功能。
- *
- * @author Kimi Liu
- * @since Java 17+
- */
-public class CellLocationKit {
-
- /**
- * 将Sheet列号变为列名
- *
- * @param index 列号, 从0开始
- * @return 0-A; 1-B...26-AA
- */
- public static String indexToColName(int index) {
- if (index < 0) {
- return null;
- }
- final StringBuilder colName = StringKit.builder();
- do {
- if (colName.length() > 0) {
- index--;
- }
- final int remainder = index % 26;
- colName.append((char) (remainder + 'A'));
- index = (index - remainder) / 26;
- } while (index > 0);
- return colName.reverse().toString();
- }
-
- /**
- * 根据表元的列名转换为列号
- *
- * @param colName 列名, 从A开始
- * @return A1-0; B1-1...AA1-26
- */
- public static int colNameToIndex(final String colName) {
- final int length = colName.length();
- char c;
- int index = -1;
- for (int i = 0; i < length; i++) {
- c = Character.toUpperCase(colName.charAt(i));
- if (Character.isDigit(c)) {
- break;// 确定指定的char值是否为数字
- }
- index = (index + 1) * 26 + (int) c - 'A';
- }
- return index;
- }
-
- /**
- * 将Excel中地址标识符(例如A11,B5)等转换为行列表示
- * 例如:A11 - x:0,y:10,B5-x:1,y:4
- *
- * @param locationRef 单元格地址标识符,例如A11,B5
- * @return 坐标点,x表示行,从0开始,y表示列,从0开始
- */
- public static CellLocation toLocation(final String locationRef) {
- final int x = colNameToIndex(locationRef);
- final int y = PatternKit.getFirstNumber(locationRef) - 1;
- return new CellLocation(x, y);
- }
-
-}
diff --git a/bus-office/src/main/java/org/miaixz/bus/office/excel/cell/values/CompositeCellValue.java b/bus-office/src/main/java/org/miaixz/bus/office/excel/cell/values/CompositeCellValue.java
new file mode 100644
index 0000000000..0fafc79566
--- /dev/null
+++ b/bus-office/src/main/java/org/miaixz/bus/office/excel/cell/values/CompositeCellValue.java
@@ -0,0 +1,120 @@
+/*********************************************************************************
+ * *
+ * The MIT License (MIT) *
+ * *
+ * Copyright (c) 2015-2024 miaixz.org and other contributors. *
+ * *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy *
+ * of this software and associated documentation files (the "Software"), to deal *
+ * in the Software without restriction, including without limitation the rights *
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
+ * copies of the Software, and to permit persons to whom the Software is *
+ * furnished to do so, subject to the following conditions: *
+ * *
+ * The above copyright notice and this permission notice shall be included in *
+ * all copies or substantial portions of the Software. *
+ * *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN *
+ * THE SOFTWARE. *
+ * *
+ ********************************************************************************/
+package org.miaixz.bus.office.excel.cell.values;
+
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellType;
+import org.miaixz.bus.core.lang.Normal;
+import org.miaixz.bus.office.excel.cell.CellEditor;
+import org.miaixz.bus.office.excel.cell.CellKit;
+import org.miaixz.bus.office.excel.cell.CellValue;
+import org.miaixz.bus.office.excel.cell.NullCell;
+
+/**
+ * 复合单元格值,用于根据单元格类型读取不同的值
+ *
+ * @author Kimi Liu
+ * @since Java 17+
+ */
+public class CompositeCellValue implements CellValue