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

View File

@ -75,13 +75,13 @@ public class ExcelUtil {
* 通过Sax方式读取Excel同时支持03和07格式 * 通过Sax方式读取Excel同时支持03和07格式
* *
* @param file Excel文件 * @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 行处理器 * @param rowHandler 行处理器
* @since 5.4.4 * @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); 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格式 * 通过Sax方式读取Excel同时支持03和07格式
* *
* @param in Excel流 * @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 行处理器 * @param rowHandler 行处理器
* @since 5.4.4 * @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); in = IoUtil.toMarkSupportStream(in);
final ExcelSaxReader<?> reader = ExcelSaxUtil.createSaxReader(ExcelFileUtil.isXlsx(in), rowHandler); final ExcelSaxReader<?> reader = ExcelSaxUtil.createSaxReader(ExcelFileUtil.isXlsx(in), rowHandler);
reader.read(in, idOrRid); reader.read(in, idOrRidOrSheetName);
} }
// ------------------------------------------------------------------------------------ Read by Sax end // ------------------------------------------------------------------------------------ Read by Sax end

View File

@ -196,7 +196,8 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
// Sheet边界记录此Record中可以获得Sheet名 // Sheet边界记录此Record中可以获得Sheet名
final BoundSheetRecord boundSheetRecord = (BoundSheetRecord) record; final BoundSheetRecord boundSheetRecord = (BoundSheetRecord) record;
boundSheetRecords.add(boundSheetRecord); 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; this.rid = this.boundSheetRecords.size() -1;
} }
} else if (record instanceof SSTRecord) { } else if (record instanceof SSTRecord) {
@ -383,14 +384,17 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
// rid直接处理 // rid直接处理
if (StrUtil.startWithIgnoreCase(idOrRidOrSheetName, RID_PREFIX)) { if (StrUtil.startWithIgnoreCase(idOrRidOrSheetName, RID_PREFIX)) {
return Integer.parseInt(StrUtil.removePrefixIgnoreCase(idOrRidOrSheetName, RID_PREFIX)); return Integer.parseInt(StrUtil.removePrefixIgnoreCase(idOrRidOrSheetName, RID_PREFIX));
} } else if(StrUtil.startWithIgnoreCase(idOrRidOrSheetName, SHEET_NAME_PREFIX)){
// since 5.7.10支持任意名称
this.sheetName = StrUtil.removePrefixIgnoreCase(idOrRidOrSheetName, SHEET_NAME_PREFIX);
} else {
try { try {
return Integer.parseInt(idOrRidOrSheetName); return Integer.parseInt(idOrRidOrSheetName);
} catch (NumberFormatException ignore) { } catch (NumberFormatException ignore) {
// 如果用于传入非数字按照sheet名称对待 // 如果用于传入非数字按照sheet名称对待
this.sheetName = idOrRidOrSheetName; this.sheetName = idOrRidOrSheetName;
} }
}
return -1; 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.IORuntimeException;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.sax.handler.RowHandler; import cn.hutool.poi.excel.sax.handler.RowHandler;
import cn.hutool.poi.exceptions.POIException; import cn.hutool.poi.exceptions.POIException;
@ -202,18 +203,28 @@ public class Excel07SaxReader implements ExcelSaxReader<Excel07SaxReader> {
// sheetIndex需转换为rid // sheetIndex需转换为rid
final SheetRidReader ridReader = new SheetRidReader().read(xssfReader); final SheetRidReader ridReader = new SheetRidReader().read(xssfReader);
final int sheetIndex; if (StrUtil.startWithIgnoreCase(idOrRidOrSheetName, SHEET_NAME_PREFIX)) {
Integer rid; // name:开头的被认为是sheet名称直接处理
try { idOrRidOrSheetName = StrUtil.removePrefixIgnoreCase(idOrRidOrSheetName, SHEET_NAME_PREFIX);
sheetIndex = Integer.parseInt(idOrRidOrSheetName); final Integer rid = ridReader.getRidByNameBase0(idOrRidOrSheetName);
rid = ridReader.getRidBySheetIdBase0(sheetIndex);
return (null != rid) ? rid : sheetIndex;
} catch (NumberFormatException ignore) {
// 非数字可能为sheet名称
rid = ridReader.getRidByNameBase0(idOrRidOrSheetName);
if (null != rid) { if (null != rid) {
return 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); throw new IllegalArgumentException("Invalid rId or id or sheetName: " + idOrRidOrSheetName);

View File

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

View File

@ -32,6 +32,17 @@ public class ExcelSaxReadTest {
ExcelUtil.readBySax("aaa.xlsx", 0, createRowHandler()); 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 @Test
public void excel07FromStreamTest() { public void excel07FromStreamTest() {
// issue#1225 非markSupport的流读取会错误 // issue#1225 非markSupport的流读取会错误
@ -51,6 +62,7 @@ public class ExcelSaxReadTest {
public void excel03ByNameTest() { public void excel03ByNameTest() {
Excel03SaxReader reader = new Excel03SaxReader(createRowHandler()); Excel03SaxReader reader = new Excel03SaxReader(createRowHandler());
reader.read("aaa.xls", "校园入学"); reader.read("aaa.xls", "校园入学");
reader.read("aaa.xls", "sheetName:校园入学");
} }
@Test(expected = POIException.class) @Test(expected = POIException.class)