support sheetName

This commit is contained in:
Looly 2021-08-22 18:38:55 +08:00
parent 40828f69d1
commit 4acfe47bbe
7 changed files with 54 additions and 24 deletions

View File

@ -16,6 +16,7 @@
* 【poi 】 增加EscapeStrCellSetterissue#I466ZZ@Gitee
* 【poi 】 ExcelBase增加renameSheet、cloneSheetissue#I466ZZ@Gitee
* 【core 】 ListUtil增加splitAvg方法pr#397@Gitee
* 【poi 】 Excel07SaxReader支持数字类型sheet名称、支持sheetName:名称前缀issue#I46OMA@Gitee
### 🐞Bug修复
* 【core 】 修复MapUtil.sort比较器不一致返回原map的问题issue#I46AQJ@Gitee

View File

@ -75,13 +75,13 @@ public class ExcelUtil {
* 通过Sax方式读取Excel同时支持03和07格式
*
* @param file Excel文件
* @param idOrRid Excel中的sheet id或rid编号rid必须加rId前缀例如rId1如果为-1处理所有编号的sheet
* @param idOrRidOrSheetName Excel中的sheet id或rid编号或sheet名称rid必须加rId前缀例如rId1如果为-1处理所有编号的sheet
* @param rowHandler 行处理器
* @since 5.4.4
*/
public static void readBySax(File file, String idOrRid, RowHandler rowHandler) {
public static void readBySax(File file, String idOrRidOrSheetName, RowHandler rowHandler) {
final ExcelSaxReader<?> reader = ExcelSaxUtil.createSaxReader(ExcelFileUtil.isXlsx(file), rowHandler);
reader.read(file, idOrRid);
reader.read(file, idOrRidOrSheetName);
}
/**
@ -102,14 +102,14 @@ public class ExcelUtil {
* 通过Sax方式读取Excel同时支持03和07格式
*
* @param in Excel流
* @param idOrRid Excel中的sheet id或rid编号rid必须加rId前缀例如rId1如果为-1处理所有编号的sheet
* @param idOrRidOrSheetName Excel中的sheet id或rid编号或sheet名称rid必须加rId前缀例如rId1如果为-1处理所有编号的sheet
* @param rowHandler 行处理器
* @since 5.4.4
*/
public static void readBySax(InputStream in, String idOrRid, RowHandler rowHandler) {
public static void readBySax(InputStream in, String idOrRidOrSheetName, RowHandler rowHandler) {
in = IoUtil.toMarkSupportStream(in);
final ExcelSaxReader<?> reader = ExcelSaxUtil.createSaxReader(ExcelFileUtil.isXlsx(in), rowHandler);
reader.read(in, idOrRid);
reader.read(in, idOrRidOrSheetName);
}
// ------------------------------------------------------------------------------------ Read by Sax end

View File

@ -196,7 +196,8 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
// Sheet边界记录此Record中可以获得Sheet名
final BoundSheetRecord boundSheetRecord = (BoundSheetRecord) record;
boundSheetRecords.add(boundSheetRecord);
if(this.rid < 0 && null != this.sheetName && StrUtil.equals(this.sheetName, boundSheetRecord.getSheetname())){
final String currentSheetName = boundSheetRecord.getSheetname();
if(null != this.sheetName && StrUtil.equals(this.sheetName, currentSheetName)){
this.rid = this.boundSheetRecords.size() -1;
}
} else if (record instanceof SSTRecord) {
@ -383,13 +384,16 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
// rid直接处理
if (StrUtil.startWithIgnoreCase(idOrRidOrSheetName, RID_PREFIX)) {
return Integer.parseInt(StrUtil.removePrefixIgnoreCase(idOrRidOrSheetName, RID_PREFIX));
}
try {
return Integer.parseInt(idOrRidOrSheetName);
} catch (NumberFormatException ignore) {
// 如果用于传入非数字按照sheet名称对待
this.sheetName = idOrRidOrSheetName;
} else if(StrUtil.startWithIgnoreCase(idOrRidOrSheetName, SHEET_NAME_PREFIX)){
// since 5.7.10支持任意名称
this.sheetName = StrUtil.removePrefixIgnoreCase(idOrRidOrSheetName, SHEET_NAME_PREFIX);
} else {
try {
return Integer.parseInt(idOrRidOrSheetName);
} catch (NumberFormatException ignore) {
// 如果用于传入非数字按照sheet名称对待
this.sheetName = idOrRidOrSheetName;
}
}
return -1;

View File

@ -2,6 +2,7 @@ package cn.hutool.poi.excel.sax;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.sax.handler.RowHandler;
import cn.hutool.poi.exceptions.POIException;
@ -202,18 +203,28 @@ public class Excel07SaxReader implements ExcelSaxReader<Excel07SaxReader> {
// sheetIndex需转换为rid
final SheetRidReader ridReader = new SheetRidReader().read(xssfReader);
final int sheetIndex;
Integer rid;
try {
sheetIndex = Integer.parseInt(idOrRidOrSheetName);
rid = ridReader.getRidBySheetIdBase0(sheetIndex);
return (null != rid) ? rid : sheetIndex;
} catch (NumberFormatException ignore) {
// 非数字可能为sheet名称
rid = ridReader.getRidByNameBase0(idOrRidOrSheetName);
if (StrUtil.startWithIgnoreCase(idOrRidOrSheetName, SHEET_NAME_PREFIX)) {
// name:开头的被认为是sheet名称直接处理
idOrRidOrSheetName = StrUtil.removePrefixIgnoreCase(idOrRidOrSheetName, SHEET_NAME_PREFIX);
final Integer rid = ridReader.getRidByNameBase0(idOrRidOrSheetName);
if (null != rid) {
return rid;
}
} else {
// 尝试查找名称
Integer rid = ridReader.getRidByNameBase0(idOrRidOrSheetName);
if (null != rid) {
return rid;
}
try {
final int sheetIndex = Integer.parseInt(idOrRidOrSheetName);
rid = ridReader.getRidBySheetIdBase0(sheetIndex);
// 如果查找不到对应index则认为用户传入的直接是rid
return ObjectUtil.defaultIfNull(rid, sheetIndex);
} catch (NumberFormatException ignore) {
// 非数字说明非index且没有对应名称抛出异常
}
}
throw new IllegalArgumentException("Invalid rId or id or sheetName: " + idOrRidOrSheetName);

View File

@ -17,6 +17,8 @@ public interface ExcelSaxReader<T> {
// sheet r:Id前缀
String RID_PREFIX = "rId";
// sheet name前缀
String SHEET_NAME_PREFIX = "sheetName:";
/**
* 开始读取Excel

View File

@ -32,6 +32,17 @@ public class ExcelSaxReadTest {
ExcelUtil.readBySax("aaa.xlsx", 0, createRowHandler());
}
@Test
public void excel07ByNameTest() {
// 工具化快速读取
// sheet名称是区分大小写的
ExcelUtil.readBySax("aaa.xlsx", "Sheet1", createRowHandler());
// 纯数字名称也支持
ExcelUtil.readBySax("aaa.xlsx", "12", createRowHandler());
// 前缀支持
ExcelUtil.readBySax("aaa.xlsx", "sheetName:12", createRowHandler());
}
@Test
public void excel07FromStreamTest() {
// issue#1225 非markSupport的流读取会错误
@ -51,6 +62,7 @@ public class ExcelSaxReadTest {
public void excel03ByNameTest() {
Excel03SaxReader reader = new Excel03SaxReader(createRowHandler());
reader.read("aaa.xls", "校园入学");
reader.read("aaa.xls", "sheetName:校园入学");
}
@Test(expected = POIException.class)