This commit is contained in:
Looly 2023-05-26 12:24:17 +08:00
parent e80ef50246
commit dd3ea66a95
4 changed files with 49 additions and 27 deletions

View File

@ -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;

View File

@ -44,10 +44,20 @@ public class Excel07SaxReader implements ExcelSaxReader<Excel07SaxReader> {
/**
* 构造
*
* @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<Excel07SaxReader> {
@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<Excel07SaxReader> {
/**
* 开始读取ExcelSheet编号从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<Excel07SaxReader> {
/**
* 开始读取ExcelSheet编号从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

View File

@ -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;
}

View File

@ -166,11 +166,16 @@ public class ExcelSaxReadTest {
@Test
public void formulaRead07Test() {
// since 6.0.0修改
// 默认不在行尾对齐单元格因此只读取了有第二个值的行
final List<Object> 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);
}