From 6b4c3b1e4d138fd2b3e8f5e474a886d74e139540 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 3 Jun 2024 12:23:47 +0800 Subject: [PATCH] fix code --- .../dromara/hutool/poi/excel/ExcelBase.java | 30 ++-- .../dromara/hutool/poi/excel/ExcelUtil.java | 36 ---- .../dromara/hutool/poi/excel/ExcelWriter.java | 33 ++-- .../hutool/poi/excel/cell/CellLocation.java | 99 ----------- .../hutool/poi/excel/cell/CellRangeUtil.java | 156 ++++++++++++++++++ ...cationUtil.java => CellReferenceUtil.java} | 16 +- .../hutool/poi/excel/cell/CellUtil.java | 91 ++-------- .../poi/excel/reader/AbstractSheetReader.java | 6 +- .../hutool/poi/excel/style/StyleSet.java | 19 +++ .../hutool/poi/excel/ExcelUtilTest.java | 47 +++--- .../poi/excel/writer/BigExcelWriteTest.java | 11 +- .../poi/excel/writer/ExcelWriteTest.java | 19 ++- .../poi/excel/writer/Issue2221Test.java | 7 +- 13 files changed, 272 insertions(+), 298 deletions(-) delete mode 100644 hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellLocation.java create mode 100644 hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellRangeUtil.java rename hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/{CellLocationUtil.java => CellReferenceUtil.java} (78%) create mode 100644 hutool-poi/src/main/java/org/dromara/hutool/poi/excel/style/StyleSet.java diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelBase.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelBase.java index efcea6f87..0a81bb25c 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelBase.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelBase.java @@ -12,20 +12,20 @@ package org.dromara.hutool.poi.excel; +import org.apache.poi.common.usermodel.HyperlinkType; import org.apache.poi.ss.usermodel.*; +import org.apache.poi.ss.util.CellReference; +import org.apache.poi.xssf.streaming.SXSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.dromara.hutool.core.data.id.IdUtil; import org.dromara.hutool.core.io.IoUtil; import org.dromara.hutool.core.lang.Assert; import org.dromara.hutool.core.net.url.UrlEncoder; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.util.CharsetUtil; -import org.dromara.hutool.poi.excel.cell.CellLocation; import org.dromara.hutool.poi.excel.cell.CellUtil; import org.dromara.hutool.poi.excel.style.StyleUtil; -import org.apache.poi.common.usermodel.HyperlinkType; -import org.apache.poi.xssf.streaming.SXSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFSheet; -import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.Closeable; import java.io.File; @@ -229,8 +229,8 @@ public class ExcelBase> implements Closeable { * @since 5.1.4 */ public Cell getCell(final String locationRef) { - final CellLocation cellLocation = ExcelUtil.toLocation(locationRef); - return getCell(cellLocation.getX(), cellLocation.getY()); + final CellReference cellReference = new CellReference(locationRef); + return getCell(cellReference.getCol(), cellReference.getRow()); } /** @@ -253,8 +253,8 @@ public class ExcelBase> implements Closeable { * @since 5.1.4 */ public Cell getOrCreateCell(final String locationRef) { - final CellLocation cellLocation = ExcelUtil.toLocation(locationRef); - return getOrCreateCell(cellLocation.getX(), cellLocation.getY()); + final CellReference cellReference = new CellReference(locationRef); + return getOrCreateCell(cellReference.getCol(), cellReference.getRow()); } /** @@ -278,8 +278,8 @@ public class ExcelBase> implements Closeable { * @since 5.1.4 */ public Cell getCell(final String locationRef, final boolean isCreateIfNotExist) { - final CellLocation cellLocation = ExcelUtil.toLocation(locationRef); - return getCell(cellLocation.getX(), cellLocation.getY(), isCreateIfNotExist); + final CellReference cellReference = new CellReference(locationRef); + return getCell(cellReference.getCol(), cellReference.getRow(), isCreateIfNotExist); } /** @@ -319,8 +319,8 @@ public class ExcelBase> implements Closeable { * @since 5.1.4 */ public CellStyle getOrCreateCellStyle(final String locationRef) { - final CellLocation cellLocation = ExcelUtil.toLocation(locationRef); - return getOrCreateCellStyle(cellLocation.getX(), cellLocation.getY()); + final CellReference cellReference = new CellReference(locationRef); + return getOrCreateCellStyle(cellReference.getCol(), cellReference.getRow()); } /** @@ -344,8 +344,8 @@ public class ExcelBase> implements Closeable { * @since 5.1.4 */ public CellStyle createCellStyle(final String locationRef) { - final CellLocation cellLocation = ExcelUtil.toLocation(locationRef); - return createCellStyle(cellLocation.getX(), cellLocation.getY()); + final CellReference cellReference = new CellReference(locationRef); + return createCellStyle(cellReference.getCol(), cellReference.getRow()); } /** diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelUtil.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelUtil.java index 8c35d07ce..94e07c12f 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelUtil.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelUtil.java @@ -17,8 +17,6 @@ import org.dromara.hutool.core.io.IoUtil; import org.dromara.hutool.core.io.file.FileUtil; import org.dromara.hutool.core.util.ObjUtil; import org.dromara.hutool.poi.PoiChecker; -import org.dromara.hutool.poi.excel.cell.CellLocation; -import org.dromara.hutool.poi.excel.cell.CellLocationUtil; import org.dromara.hutool.poi.excel.sax.ExcelSaxReader; import org.dromara.hutool.poi.excel.sax.ExcelSaxUtil; import org.dromara.hutool.poi.excel.sax.handler.RowHandler; @@ -454,38 +452,4 @@ public class ExcelUtil { throw new DependencyException(ObjUtil.defaultIfNull(e.getCause(), e), PoiChecker.NO_POI_ERROR_MSG); } } - - /** - * 将Sheet列号变为列名 - * - * @param index 列号, 从0开始 - * @return 0-》A; 1-》B...26-》AA - * @since 4.1.20 - */ - public static String indexToColName(final int index) { - return CellLocationUtil.indexToColName(index); - } - - /** - * 根据表元的列名转换为列号 - * - * @param colName 列名, 从A开始 - * @return A1-》0; B1-》1...AA1-》26 - * @since 4.1.20 - */ - public static int colNameToIndex(final String colName) { - return CellLocationUtil.colNameToIndex(colName); - } - - /** - * 将Excel中地址标识符(例如A11,B5)等转换为行列表示
- * 例如:A11 -》 x:0,y:10,B5-》x:1,y:4 - * - * @param locationRef 单元格地址标识符,例如A11,B5 - * @return 坐标点,x表示行,从0开始,y表示列,从0开始 - * @since 5.1.4 - */ - public static CellLocation toLocation(final String locationRef) { - return CellLocationUtil.toLocation(locationRef); - } } diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelWriter.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelWriter.java index d198e82cb..f2157a462 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelWriter.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelWriter.java @@ -16,6 +16,7 @@ import org.apache.poi.common.usermodel.Hyperlink; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddressList; +import org.apache.poi.ss.util.CellReference; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.usermodel.XSSFDataValidation; import org.apache.poi.xssf.usermodel.XSSFSheet; @@ -34,7 +35,7 @@ import org.dromara.hutool.core.map.multi.Table; import org.dromara.hutool.core.reflect.FieldUtil; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.poi.excel.cell.CellEditor; -import org.dromara.hutool.poi.excel.cell.CellLocation; +import org.dromara.hutool.poi.excel.cell.CellRangeUtil; import org.dromara.hutool.poi.excel.cell.CellUtil; import org.dromara.hutool.poi.excel.style.Align; @@ -681,7 +682,7 @@ public class ExcelWriter extends ExcelBase { Assert.isFalse(this.isClosed, "ExcelWriter has been closed!"); final int rowIndex = this.currentRow.get(); - merge(rowIndex, rowIndex, 0, lastColumn, content, isSetHeaderStyle); + merge(CellRangeUtil.ofSingleRow(rowIndex, lastColumn), content, isSetHeaderStyle); // 设置内容后跳到下一行 if (null != content) { @@ -694,16 +695,13 @@ public class ExcelWriter extends ExcelBase { * 合并某行的单元格,并写入对象到单元格
* 样式为默认标题样式,可使用{@link #getHeadCellStyle()}方法调用后自定义默认样式 * - * @param firstRow 起始行,0开始 - * @param lastRow 结束行,0开始 - * @param firstColumn 起始列,0开始 - * @param lastColumn 结束列,0开始 + * @param cellRangeAddress 合并单元格范围,定义了起始行列和结束行列 * @param content 合并单元格后的内容 * @param isSetHeaderStyle 是否为合并后的单元格设置默认标题样式,只提取边框样式 * @return this * @since 4.0.10 */ - public ExcelWriter merge(final int firstRow, final int lastRow, final int firstColumn, final int lastColumn, final Object content, final boolean isSetHeaderStyle) { + public ExcelWriter merge(final CellRangeAddress cellRangeAddress, final Object content, final boolean isSetHeaderStyle) { Assert.isFalse(this.isClosed, "ExcelWriter has been closed!"); CellStyle style = null; @@ -711,30 +709,27 @@ public class ExcelWriter extends ExcelBase { style = styleSet.getStyleByValueType(content, isSetHeaderStyle); } - return merge(firstRow, lastRow, firstColumn, lastColumn, content, style); + return merge(cellRangeAddress, content, style); } /** * 合并单元格,并写入对象到单元格,使用指定的样式
* 指定样式传入null,则不使用任何样式 * - * @param firstRow 起始行,0开始 - * @param lastRow 结束行,0开始 - * @param firstColumn 起始列,0开始 - * @param lastColumn 结束列,0开始 + * @param cellRangeAddress 合并单元格范围,定义了起始行列和结束行列 * @param content 合并单元格后的内容 * @param cellStyle 合并后单元格使用的样式,可以为null * @return this * @since 5.6.5 */ - public ExcelWriter merge(final int firstRow, final int lastRow, final int firstColumn, final int lastColumn, final Object content, final CellStyle cellStyle) { + public ExcelWriter merge(final CellRangeAddress cellRangeAddress, final Object content, final CellStyle cellStyle) { Assert.isFalse(this.isClosed, "ExcelWriter has been closed!"); - CellUtil.mergingCells(this.getSheet(), firstRow, lastRow, firstColumn, lastColumn, cellStyle); + CellUtil.mergingCells(this.getSheet(), cellRangeAddress, cellStyle); // 设置内容 if (null != content) { - final Cell cell = getOrCreateCell(firstColumn, firstRow); + final Cell cell = getOrCreateCell(cellRangeAddress.getFirstColumn(), cellRangeAddress.getFirstRow()); CellUtil.setCellValue(cell, content, cellStyle, this.cellEditor); } return this; @@ -1198,8 +1193,8 @@ public class ExcelWriter extends ExcelBase { * @since 5.1.4 */ public ExcelWriter writeCellValue(final String locationRef, final Object value) { - final CellLocation cellLocation = ExcelUtil.toLocation(locationRef); - return writeCellValue(cellLocation.getX(), cellLocation.getY(), value); + final CellReference cellReference = new CellReference(locationRef); + return writeCellValue(cellReference.getCol(), cellReference.getRow(), value); } /** @@ -1247,8 +1242,8 @@ public class ExcelWriter extends ExcelBase { * @since 5.1.4 */ public ExcelWriter setStyle(final CellStyle style, final String locationRef) { - final CellLocation cellLocation = ExcelUtil.toLocation(locationRef); - return setStyle(style, cellLocation.getX(), cellLocation.getY()); + final CellReference cellReference = new CellReference(locationRef); + return setStyle(style, cellReference.getCol(), cellReference.getRow()); } /** diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellLocation.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellLocation.java deleted file mode 100644 index b26c9c2e8..000000000 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellLocation.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2023 looly(loolly@aliyun.com) - * Hutool is licensed under Mulan PSL v2. - * You can use this software according to the terms and conditions of the Mulan PSL v2. - * You may obtain a copy of Mulan PSL v2 at: - * https://license.coscl.org.cn/MulanPSL2 - * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, - * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, - * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. - * See the Mulan PSL v2 for more details. - */ - -package org.dromara.hutool.poi.excel.cell; - -import java.io.Serializable; -import java.util.Objects; - -/** - * 单元格位置 - * - * @author Looly - * @since 5.1.4 - */ -public class CellLocation implements Serializable { - private static final long serialVersionUID = 1L; - - private int x; - private int y; - - /** - * 构造 - * - * @param x 列号,从0开始 - * @param y 行号,从0开始 - */ - public CellLocation(final int x, final int y) { - this.x = x; - this.y = y; - } - - /** - * 获取x(列)号 - * - * @return x(列)号 - */ - public int getX() { - return x; - } - - /** - * 设置x(列)号 - * - * @param x x(列)号 - */ - public void setX(final int x) { - this.x = x; - } - - /** - * 获取y(行)号 - * @return y(行)号 - */ - public int getY() { - return y; - } - - /** - * 设置y(行)号 - * @param y y(行)号 - */ - public void setY(final int y) { - this.y = y; - } - - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - final CellLocation that = (CellLocation) o; - return x == that.x && y == that.y; - } - - @Override - public int hashCode() { - return Objects.hash(x, y); - } - - @Override - public String toString() { - return "CellLocation{" + - "x=" + x + - ", y=" + y + - '}'; - } -} diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellRangeUtil.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellRangeUtil.java new file mode 100644 index 000000000..3821a51fc --- /dev/null +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellRangeUtil.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2024. looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * https://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.poi.excel.cell; + +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.ss.util.CellReference; + +/** + * {@link CellRangeAddress} 工具类
+ * {@link CellRangeAddress} 表示表格的一个区域,通过定义起始行和列,以及结束行和列,圈定范围,如设置合并单元格等。 + * + * @author Looly + * @since 6.0.0 + */ +public class CellRangeUtil { + + /** + * 根据字符串表示法创建一个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); + } + + // region ----- getCellRangeAddress + /** + * 获取合并单元格{@link CellRangeAddress},如果不是返回null + * + * @param sheet {@link Sheet} + * @param locationRef 单元格地址标识符,例如A11,B5 + * @return {@link CellRangeAddress} + * @since 5.8.0 + */ + 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} + * @since 5.8.0 + */ + 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} + * @since 5.8.0 + */ + 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; + } + // endregion +} diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellLocationUtil.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellReferenceUtil.java similarity index 78% rename from hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellLocationUtil.java rename to hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellReferenceUtil.java index 50f22a00d..02231db17 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellLocationUtil.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellReferenceUtil.java @@ -12,16 +12,16 @@ package org.dromara.hutool.poi.excel.cell; -import org.dromara.hutool.core.regex.ReUtil; +import org.apache.poi.ss.util.CellReference; import org.dromara.hutool.core.text.StrUtil; /** - * 单元格位置工具类,提供包括行号转行名称、列号转列名称等功能。 + * 单元格位置{@link CellReference}工具类,提供包括行号转行名称、列号转列名称等功能。 * * @author looly * @since 6.0.0 */ -public class CellLocationUtil { +public class CellReferenceUtil { /** * 将Sheet列号变为列名 * @@ -66,14 +66,12 @@ public class CellLocationUtil { /** * 将Excel中地址标识符(例如A11,B5)等转换为行列表示
- * 例如:A11 -》 x:0,y:10,B5-》x:1,y:4 + * 例如:A11 -》 col:0,row:10,B5-》col:1,row:4 * * @param locationRef 单元格地址标识符,例如A11,B5 - * @return 坐标点,x表示行,从0开始,y表示列,从0开始 + * @return 坐标点 */ - public static CellLocation toLocation(final String locationRef) { - final int x = colNameToIndex(locationRef); - final int y = ReUtil.getFirstNumber(locationRef) - 1; - return new CellLocation(x, y); + public static CellReference toCellReference(final String locationRef) { + return new CellReference(locationRef); } } diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellUtil.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellUtil.java index d17e73993..1b3221326 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellUtil.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/cell/CellUtil.java @@ -12,18 +12,18 @@ package org.dromara.hutool.poi.excel.cell; +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.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.util.ObjUtil; -import org.dromara.hutool.poi.excel.ExcelUtil; import org.dromara.hutool.poi.excel.StyleSet; import org.dromara.hutool.poi.excel.cell.editors.TrimEditor; import org.dromara.hutool.poi.excel.cell.setters.CellSetterFactory; import org.dromara.hutool.poi.excel.cell.values.ErrorCellValue; import org.dromara.hutool.poi.excel.cell.values.NumericCellValue; -import org.apache.poi.ss.usermodel.*; -import org.apache.poi.ss.util.CellRangeAddress; -import org.apache.poi.ss.util.RegionUtil; -import org.apache.poi.ss.util.SheetUtil; /** * Excel表格中单元格工具类 @@ -261,56 +261,6 @@ public class CellUtil { } // endregion - // region ----- getCellRangeAddress - /** - * 获取合并单元格{@link CellRangeAddress},如果不是返回null - * - * @param sheet {@link Sheet} - * @param locationRef 单元格地址标识符,例如A11,B5 - * @return {@link CellRangeAddress} - * @since 5.8.0 - */ - public static CellRangeAddress getCellRangeAddress(final Sheet sheet, final String locationRef) { - final CellLocation cellLocation = ExcelUtil.toLocation(locationRef); - return getCellRangeAddress(sheet, cellLocation.getX(), cellLocation.getY()); - } - - /** - * 获取合并单元格{@link CellRangeAddress},如果不是返回null - * - * @param cell {@link Cell} - * @return {@link CellRangeAddress} - * @since 5.8.0 - */ - 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} - * @since 5.8.0 - */ - 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; - } - // endregion - // region ----- merging 合并单元格 /** * 判断指定的单元格是否是合并单元格 @@ -321,8 +271,8 @@ public class CellUtil { * @since 5.1.5 */ public static boolean isMergedRegion(final Sheet sheet, final String locationRef) { - final CellLocation cellLocation = ExcelUtil.toLocation(locationRef); - return isMergedRegion(sheet, cellLocation.getX(), cellLocation.getY()); + final CellReference cellReference = new CellReference(locationRef); + return isMergedRegion(sheet, cellReference.getCol(), cellReference.getRow()); } /** @@ -361,35 +311,22 @@ public class CellUtil { * 合并单元格,可以根据设置的值来合并行和列 * * @param sheet 表对象 - * @param firstRow 起始行,0开始 - * @param lastRow 结束行,0开始 - * @param firstColumn 起始列,0开始 - * @param lastColumn 结束列,0开始 + * @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 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); } @@ -404,8 +341,8 @@ public class CellUtil { * @since 5.1.5 */ public static Object getMergedRegionValue(final Sheet sheet, final String locationRef) { - final CellLocation cellLocation = ExcelUtil.toLocation(locationRef); - return getMergedRegionValue(sheet, cellLocation.getX(), cellLocation.getY()); + final CellReference cellReference = new CellReference(locationRef); + return getMergedRegionValue(sheet, cellReference.getCol(), cellReference.getRow()); } /** diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/AbstractSheetReader.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/AbstractSheetReader.java index ac993fd4f..ad3b877ce 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/AbstractSheetReader.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/AbstractSheetReader.java @@ -12,12 +12,12 @@ package org.dromara.hutool.poi.excel.reader; +import org.apache.poi.ss.usermodel.Sheet; import org.dromara.hutool.core.collection.CollUtil; import org.dromara.hutool.core.util.ObjUtil; -import org.dromara.hutool.poi.excel.ExcelUtil; import org.dromara.hutool.poi.excel.RowUtil; import org.dromara.hutool.poi.excel.cell.CellEditor; -import org.apache.poi.ss.usermodel.Sheet; +import org.dromara.hutool.poi.excel.cell.CellReferenceUtil; import java.util.ArrayList; import java.util.LinkedHashMap; @@ -137,7 +137,7 @@ public abstract class AbstractSheetReader implements SheetReader { */ protected String aliasHeader(final Object headerObj, final int index) { if (null == headerObj) { - return ExcelUtil.indexToColName(index); + return CellReferenceUtil.indexToColName(index); } final String header = headerObj.toString(); diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/style/StyleSet.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/style/StyleSet.java new file mode 100644 index 000000000..cf922ee5e --- /dev/null +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/style/StyleSet.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024. looly(loolly@aliyun.com) + * Hutool is licensed under Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * https://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, + * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, + * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +package org.dromara.hutool.poi.excel.style; + +import org.apache.poi.ss.usermodel.CellStyle; + +public interface StyleSet { + CellStyle getStyleFor(int x, int y, Object cellValue); +} diff --git a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/ExcelUtilTest.java b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/ExcelUtilTest.java index 472f20075..78c8b7cf0 100644 --- a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/ExcelUtilTest.java +++ b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/ExcelUtilTest.java @@ -12,7 +12,8 @@ package org.dromara.hutool.poi.excel; -import org.dromara.hutool.poi.excel.cell.CellLocation; +import org.apache.poi.ss.util.CellReference; +import org.dromara.hutool.poi.excel.cell.CellReferenceUtil; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -23,39 +24,39 @@ public class ExcelUtilTest { @Test public void indexToColNameTest() { - Assertions.assertEquals("A", ExcelUtil.indexToColName(0)); - Assertions.assertEquals("B", ExcelUtil.indexToColName(1)); - Assertions.assertEquals("C", ExcelUtil.indexToColName(2)); + Assertions.assertEquals("A", CellReferenceUtil.indexToColName(0)); + Assertions.assertEquals("B", CellReferenceUtil.indexToColName(1)); + Assertions.assertEquals("C", CellReferenceUtil.indexToColName(2)); - Assertions.assertEquals("AA", ExcelUtil.indexToColName(26)); - Assertions.assertEquals("AB", ExcelUtil.indexToColName(27)); - Assertions.assertEquals("AC", ExcelUtil.indexToColName(28)); + Assertions.assertEquals("AA", CellReferenceUtil.indexToColName(26)); + Assertions.assertEquals("AB", CellReferenceUtil.indexToColName(27)); + Assertions.assertEquals("AC", CellReferenceUtil.indexToColName(28)); - Assertions.assertEquals("AAA", ExcelUtil.indexToColName(702)); - Assertions.assertEquals("AAB", ExcelUtil.indexToColName(703)); - Assertions.assertEquals("AAC", ExcelUtil.indexToColName(704)); + Assertions.assertEquals("AAA", CellReferenceUtil.indexToColName(702)); + Assertions.assertEquals("AAB", CellReferenceUtil.indexToColName(703)); + Assertions.assertEquals("AAC", CellReferenceUtil.indexToColName(704)); } @Test public void colNameToIndexTest() { - Assertions.assertEquals(704, ExcelUtil.colNameToIndex("AAC")); - Assertions.assertEquals(703, ExcelUtil.colNameToIndex("AAB")); - Assertions.assertEquals(702, ExcelUtil.colNameToIndex("AAA")); + Assertions.assertEquals(704, CellReferenceUtil.colNameToIndex("AAC")); + Assertions.assertEquals(703, CellReferenceUtil.colNameToIndex("AAB")); + Assertions.assertEquals(702, CellReferenceUtil.colNameToIndex("AAA")); - Assertions.assertEquals(28, ExcelUtil.colNameToIndex("AC")); - Assertions.assertEquals(27, ExcelUtil.colNameToIndex("AB")); - Assertions.assertEquals(26, ExcelUtil.colNameToIndex("AA")); + Assertions.assertEquals(28, CellReferenceUtil.colNameToIndex("AC")); + Assertions.assertEquals(27, CellReferenceUtil.colNameToIndex("AB")); + Assertions.assertEquals(26, CellReferenceUtil.colNameToIndex("AA")); - Assertions.assertEquals(2, ExcelUtil.colNameToIndex("C")); - Assertions.assertEquals(1, ExcelUtil.colNameToIndex("B")); - Assertions.assertEquals(0, ExcelUtil.colNameToIndex("A")); + Assertions.assertEquals(2, CellReferenceUtil.colNameToIndex("C")); + Assertions.assertEquals(1, CellReferenceUtil.colNameToIndex("B")); + Assertions.assertEquals(0, CellReferenceUtil.colNameToIndex("A")); } @Test - public void toLocationTest() { - final CellLocation a11 = ExcelUtil.toLocation("A11"); - Assertions.assertEquals(0, a11.getX()); - Assertions.assertEquals(10, a11.getY()); + public void cellReferenceTest() { + final CellReference a11 = new CellReference("A11"); + Assertions.assertEquals(0, a11.getCol()); + Assertions.assertEquals(10, a11.getRow()); } @Test diff --git a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/BigExcelWriteTest.java b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/BigExcelWriteTest.java index 48334eb12..63f084a05 100644 --- a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/BigExcelWriteTest.java +++ b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/BigExcelWriteTest.java @@ -12,6 +12,11 @@ package org.dromara.hutool.poi.excel.writer; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.util.CellRangeAddress; import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.date.DateUtil; import org.dromara.hutool.core.io.file.FileUtil; @@ -22,10 +27,6 @@ import org.dromara.hutool.poi.excel.ExcelUtil; import org.dromara.hutool.poi.excel.ExcelWriter; import org.dromara.hutool.poi.excel.TestBean; import org.dromara.hutool.poi.excel.style.StyleUtil; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.FillPatternType; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.IndexedColors; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -102,7 +103,7 @@ public class BigExcelWriteTest { writer.write(rows); // 合并单元格后的标题行,使用默认标题样式 - writer.merge(7, 10, 4, 10, "测试Merge", false); + writer.merge(new CellRangeAddress(7, 10, 4, 10), "测试Merge", false); // 关闭writer,释放内存 writer.close(); diff --git a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/ExcelWriteTest.java b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/ExcelWriteTest.java index 804de5da4..8021f7786 100644 --- a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/ExcelWriteTest.java +++ b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/ExcelWriteTest.java @@ -12,6 +12,7 @@ package org.dromara.hutool.poi.excel.writer; +import org.apache.poi.ss.util.CellRangeAddress; import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.date.DateUtil; import org.dromara.hutool.core.io.file.FileUtil; @@ -187,7 +188,7 @@ public class ExcelWriteTest { writer.write(rows); // 合并单元格后的标题行,使用默认标题样式 - writer.merge(7, 10, 4, 10, "测试Merge", false); + writer.merge(new CellRangeAddress(7, 10, 4, 10), "测试Merge", false); // 关闭writer,释放内存 writer.close(); @@ -705,14 +706,14 @@ public class ExcelWriteTest { cellStyle.setFont(font); // 合并单元格后的标题行,使用设置好的样式 - writer.merge(0, 1, 0, row1.size() - 1, "标题XXXXXXXX", cellStyle); + writer.merge(new CellRangeAddress(0, 1, 0, row1.size() - 1), "标题XXXXXXXX", cellStyle); Console.log(writer.getCurrentRow()); //设置复杂表头 - writer.merge(2, 3, 0, 0, "序号", true); - writer.merge(2, 2, 1, 2, "AABB", true); - writer.merge(2, 3, 3, 3, "CCCC", true); - writer.merge(2, 2, 4, 5, "DDEE", true); + writer.merge(new CellRangeAddress(2, 3, 0, 0), "序号", true); + writer.merge(new CellRangeAddress(2, 2, 1, 2), "AABB", true); + writer.merge(new CellRangeAddress(2, 3, 3, 3), "CCCC", true); + writer.merge(new CellRangeAddress(2, 2, 4, 5), "DDEE", true); writer.setCurrentRow(3); final List sechead = ListUtil.of("AA", "BB", "DD", "EE"); @@ -775,7 +776,7 @@ public class ExcelWriteTest { //合并单元格后的标题行,使用默认标题样式 writer.merge(7, "测试标题"); - writer.merge(3, 4, 0, 0, new XSSFRichTextString("9999"), true); + writer.merge(new CellRangeAddress(3, 4, 0, 0), new XSSFRichTextString("9999"), true); writer.write(list, true); writer.close(); } @@ -789,7 +790,7 @@ public class ExcelWriteTest { final String path = "d:/test/mergeForDate.xlsx"; FileUtil.del(FileUtil.file(path)); final ExcelWriter writer = ExcelUtil.getWriter(path); - writer.merge(0, 3, 0, 2, DateUtil.now(), false); + writer.merge(new CellRangeAddress(0, 3, 0, 2), DateUtil.now(), false); writer.close(); } @@ -870,7 +871,7 @@ public class ExcelWriteTest { FileUtil.del(tempFile); final BigExcelWriter writer = new BigExcelWriter(tempFile); - writer.merge(0, 1, 2, 2, 3.99, false); + writer.merge(new CellRangeAddress(0, 1, 2, 2), 3.99, false); writer.close(); } diff --git a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/Issue2221Test.java b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/Issue2221Test.java index c2e607897..a2d9ddadd 100644 --- a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/Issue2221Test.java +++ b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/Issue2221Test.java @@ -12,6 +12,7 @@ package org.dromara.hutool.poi.excel.writer; +import org.apache.poi.ss.util.CellRangeAddress; import org.dromara.hutool.core.collection.ListUtil; import org.dromara.hutool.core.map.MapUtil; import org.dromara.hutool.poi.excel.ExcelUtil; @@ -84,9 +85,9 @@ public class Issue2221Test { writer.setOnlyAlias(true); // 设置合并的单元格 - writer.merge(0, 1, 0, 0, "日期", true); - writer.merge(0, 0, 1, 2, "运行次数", true); - writer.merge(0, 0, 3, 4, "新增人数", true); + writer.merge(new CellRangeAddress(0, 1, 0, 0), "日期", true); + writer.merge(new CellRangeAddress(0, 0, 1, 2), "运行次数", true); + writer.merge(new CellRangeAddress(0, 0, 3, 4), "新增人数", true); // 写入数据 final List> data = ListUtil.view(