From dd3ea66a959a84c6ae7504fe2062fddff996b817 Mon Sep 17 00:00:00 2001 From: Looly Date: Fri, 26 May 2023 12:24:17 +0800 Subject: [PATCH] fix code --- .../org/dromara/hutool/poi/excel/RowUtil.java | 1 + .../poi/excel/sax/Excel07SaxReader.java | 24 ++++++++++---- .../poi/excel/sax/SheetDataSaxHandler.java | 33 +++++++++++-------- .../hutool/poi/excel/ExcelSaxReadTest.java | 18 ++++++---- 4 files changed, 49 insertions(+), 27 deletions(-) diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/RowUtil.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/RowUtil.java index a1f06c0f8..bf7e1b357 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/RowUtil.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/RowUtil.java @@ -13,6 +13,7 @@ package org.dromara.hutool.poi.excel; import org.dromara.hutool.core.collection.ListUtil; +import org.dromara.hutool.core.lang.Console; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.poi.excel.cell.CellEditor; import org.dromara.hutool.poi.excel.cell.CellUtil; diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/sax/Excel07SaxReader.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/sax/Excel07SaxReader.java index 61a532855..e58ab982b 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/sax/Excel07SaxReader.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/sax/Excel07SaxReader.java @@ -44,10 +44,20 @@ public class Excel07SaxReader implements ExcelSaxReader { /** * 构造 * - * @param rowHandler 行处理器 + * @param rowHandler 行处理器 */ public Excel07SaxReader(final RowHandler rowHandler) { - this.handler = new SheetDataSaxHandler(rowHandler); + this(rowHandler, false); + } + + /** + * 构造 + * + * @param rowHandler 行处理器 + * @param padCellAtEndOfRow 是否对齐数据,即在行尾补充null cell + */ + public Excel07SaxReader(final RowHandler rowHandler, final boolean padCellAtEndOfRow) { + this.handler = new SheetDataSaxHandler(rowHandler, padCellAtEndOfRow); } /** @@ -69,7 +79,7 @@ public class Excel07SaxReader implements ExcelSaxReader { @Override public Excel07SaxReader read(final File file, final String idOrRidOrSheetName) throws POIException { - try (final OPCPackage open = OPCPackage.open(file, PackageAccess.READ)){ + try (final OPCPackage open = OPCPackage.open(file, PackageAccess.READ)) { return read(open, idOrRidOrSheetName); } catch (final InvalidFormatException | IOException e) { throw new POIException(e); @@ -107,8 +117,8 @@ public class Excel07SaxReader implements ExcelSaxReader { /** * 开始读取Excel,Sheet编号从0开始计数 * - * @param opcPackage {@link OPCPackage},Excel包,读取后不关闭 - * @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet + * @param opcPackage {@link OPCPackage},Excel包,读取后不关闭 + * @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet * @return this * @throws POIException POI异常 */ @@ -125,8 +135,8 @@ public class Excel07SaxReader implements ExcelSaxReader { /** * 开始读取Excel,Sheet编号从0开始计数 * - * @param xssfReader {@link XSSFReader},Excel读取器 - * @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet + * @param xssfReader {@link XSSFReader},Excel读取器 + * @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet * @return this * @throws POIException POI异常 * @since 5.4.4 diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/sax/SheetDataSaxHandler.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/sax/SheetDataSaxHandler.java index b180d2751..a4dd8ea71 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/sax/SheetDataSaxHandler.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/sax/SheetDataSaxHandler.java @@ -12,6 +12,7 @@ package org.dromara.hutool.poi.excel.sax; +import org.dromara.hutool.core.lang.Console; import org.dromara.hutool.core.text.StrUtil; import org.dromara.hutool.core.util.ObjUtil; import org.dromara.hutool.poi.excel.cell.values.FormulaCellValue; @@ -37,6 +38,13 @@ import java.util.List; */ public class SheetDataSaxHandler extends DefaultHandler { + /** + * 行处理器 + */ + protected RowHandler rowHandler; + // 配置项:是否对齐数据,即在行尾补充null cell + private final boolean padCellAtEndOfRow; + // 单元格的格式表,对应style.xml protected StylesTable stylesTable; // excel 2007 的共享字符串表,对应sharedString.xml @@ -77,17 +85,14 @@ public class SheetDataSaxHandler extends DefaultHandler { /** * 构造 * - * @param rowHandler 行处理器 + * @param rowHandler 行处理器 + * @param padCellAtEndOfRow 是否对齐数据,即在行尾补充null cell */ - public SheetDataSaxHandler(final RowHandler rowHandler) { + public SheetDataSaxHandler(final RowHandler rowHandler, final boolean padCellAtEndOfRow) { this.rowHandler = rowHandler; + this.padCellAtEndOfRow = padCellAtEndOfRow; } - /** - * 行处理器 - */ - protected RowHandler rowHandler; - /** * 设置行处理器 * @@ -228,8 +233,8 @@ public class SheetDataSaxHandler extends DefaultHandler { } // 补全一行尾部可能缺失的单元格 - if (maxCellCoordinate != null) { - fillBlankCell(curCoordinate, maxCellCoordinate, true); + if (padCellAtEndOfRow && maxCellCoordinate != null) { + padCell(curCoordinate, maxCellCoordinate, true); } rowHandler.handle(sheetIndex, rowNumber, rowCellList); @@ -251,7 +256,7 @@ public class SheetDataSaxHandler extends DefaultHandler { */ private void endCell() { // 补全单元格之间的空格 - fillBlankCell(preCoordinate, curCoordinate, false); + padCell(preCoordinate, curCoordinate, false); final String contentStr = StrUtil.trim(lastContent); Object value = ExcelSaxUtil.getDataValue(this.cellDataType, contentStr, this.sharedStrings, this.numFmtString); @@ -279,14 +284,14 @@ public class SheetDataSaxHandler extends DefaultHandler { * @param curCoordinate 当前单元格坐标 * @param isEnd 是否为最后一个单元格 */ - private void fillBlankCell(final String preCoordinate, final String curCoordinate, final boolean isEnd) { + private void padCell(final String preCoordinate, final String curCoordinate, final boolean isEnd) { if (!curCoordinate.equals(preCoordinate)) { int len = ExcelSaxUtil.countNullCell(preCoordinate, curCoordinate); if (isEnd) { len++; } while (len-- > 0) { - addCellValue(curCell++, StrUtil.EMPTY); + addCellValue(curCell++, null); } } } @@ -309,8 +314,8 @@ public class SheetDataSaxHandler extends DefaultHandler { // 单元格存储格式的索引,对应style.xml中的numFmts元素的子元素索引 final int numFmtIndex = xssfCellStyle.getDataFormat(); this.numFmtString = ObjUtil.defaultIfNull( - xssfCellStyle.getDataFormatString(), - () -> BuiltinFormats.getBuiltinFormat(numFmtIndex)); + xssfCellStyle.getDataFormatString(), + () -> BuiltinFormats.getBuiltinFormat(numFmtIndex)); if (CellDataType.NUMBER == this.cellDataType && ExcelSaxUtil.isDateFormat(numFmtIndex, numFmtString)) { cellDataType = CellDataType.DATE; } diff --git a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/ExcelSaxReadTest.java b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/ExcelSaxReadTest.java index 14d83d116..06899b1fa 100644 --- a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/ExcelSaxReadTest.java +++ b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/ExcelSaxReadTest.java @@ -166,11 +166,16 @@ public class ExcelSaxReadTest { @Test public void formulaRead07Test() { + // since 6.0.0修改 + // 默认不在行尾对齐单元格,因此只读取了有第二个值的行 final List rows = new ArrayList<>(); - ExcelUtil.readBySax("data_for_sax_test.xlsx", 0, (i, i1, list) -> - rows.add(list.get(1))); + ExcelUtil.readBySax("data_for_sax_test.xlsx", 0, (i, i1, list) -> { + if(list.size() > 1){ + rows.add(list.get(1)); + } + }); - final FormulaCellValue value = (FormulaCellValue) rows.get(3); + final FormulaCellValue value = (FormulaCellValue) rows.get(1); Assertions.assertEquals(50L, value.getResult()); } @@ -211,12 +216,13 @@ public class ExcelSaxReadTest { } @Test - @Disabled + //@Disabled public void readBlankTest() { - final File file = new File("D:/test/b.xlsx"); + final File file = FileUtil.file("aaa.xlsx"); - ExcelUtil.readBySax(file, 0, (sheetIndex, rowIndex, rowList) -> rowList.forEach(Console::log)); + ExcelUtil.readBySax(file, 0, (sheetIndex, rowIndex, rowList) -> Console.log(rowList)); + Console.log("-------------------------------------"); ExcelUtil.getReader(file).read().forEach(Console::log); }