add read by name support

This commit is contained in:
Looly 2020-12-27 05:15:07 +08:00
parent ee5331f53e
commit dc440b2cc7
5 changed files with 72 additions and 28 deletions

View File

@ -13,6 +13,7 @@
* 【poi 】 增加ExcelDateUtil更多日期格式支持issue#1316@Github
* 【core 】 NumberUtil.toBigDecimal支持各类数字格式如1,234.56等issue#1334@Github
* 【core 】 NumberUtil增加parseXXX方法issue#1334@Github
* 【poi 】 Excel07SaxReader支持通过sheetName读取issue#I2AOSE@Gitee
### Bug修复
* 【core 】 FileUtil.isSub相对路径判断问题pr#1315@Github

View File

@ -1,6 +1,7 @@
package cn.hutool.poi.excel.sax;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.sax.handler.RowHandler;
@ -121,7 +122,7 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
* @throws POIException IO异常包装
*/
public Excel03SaxReader read(POIFSFileSystem fs, String id) throws POIException {
this.rid = Integer.parseInt(id);
this.rid = getSheetIndex(id);
formatListener = new FormatTrackingHSSFListener(new MissingRecordAwareHSSFListener(this));
final HSSFRequest request = new HSSFRequest();
@ -341,5 +342,32 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
private boolean isProcessCurrentSheet() {
return this.rid < 0 || this.curRid == this.rid;
}
/**
* 获取sheet索引从0开始
* <ul>
* <li>传入'rId'开头直接去除rId前缀</li>
* <li>传入纯数字表示sheetIndex直接转换为rid</li>
* </ul>
*
* @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名称从0开始rid必须加rId前缀例如rId0如果为-1处理所有编号的sheet
* @return sheet索引从0开始
* @since 5.5.5
*/
private int getSheetIndex(String idOrRidOrSheetName) {
Assert.notBlank(idOrRidOrSheetName, "id or rid or sheetName must be not blank!");
// rid直接处理
if (StrUtil.startWithIgnoreCase(idOrRidOrSheetName, RID_PREFIX)) {
return Integer.parseInt(StrUtil.removePrefixIgnoreCase(idOrRidOrSheetName, RID_PREFIX));
}
final int sheetIndex;
try {
return Integer.parseInt(idOrRidOrSheetName);
} catch (NumberFormatException ignore) {
throw new IllegalArgumentException("Invalid sheet id: " + idOrRidOrSheetName);
}
}
// ---------------------------------------------------------------------------------------------- Private method end
}

View File

@ -24,8 +24,6 @@ import java.util.Iterator;
*/
public class Excel07SaxReader implements ExcelSaxReader<Excel07SaxReader> {
// sheet r:Id前缀
public static final String RID_PREFIX = "rId";
private final SheetDataSaxHandler handler;
/**
@ -55,9 +53,9 @@ public class Excel07SaxReader implements ExcelSaxReader<Excel07SaxReader> {
}
@Override
public Excel07SaxReader read(File file, String idOrRid) throws POIException {
public Excel07SaxReader read(File file, String idOrRidOrSheetName) throws POIException {
try {
return read(OPCPackage.open(file), idOrRid);
return read(OPCPackage.open(file), idOrRidOrSheetName);
} catch (InvalidFormatException e) {
throw new POIException(e);
}
@ -69,9 +67,9 @@ public class Excel07SaxReader implements ExcelSaxReader<Excel07SaxReader> {
}
@Override
public Excel07SaxReader read(InputStream in, String idOrRid) throws POIException {
public Excel07SaxReader read(InputStream in, String idOrRidOrSheetName) throws POIException {
try (final OPCPackage opcPackage = OPCPackage.open(in)) {
return read(opcPackage, idOrRid);
return read(opcPackage, idOrRidOrSheetName);
} catch (IOException e) {
throw new IORuntimeException(e);
} catch (InvalidFormatException e) {
@ -95,13 +93,13 @@ public class Excel07SaxReader implements ExcelSaxReader<Excel07SaxReader> {
* 开始读取ExcelSheet编号从0开始计数
*
* @param opcPackage {@link OPCPackage}Excel包读取后不关闭
* @param idOrRid Excel中的sheet id或者rid编号rid必须加rId前缀例如rId1如果为-1处理所有编号的sheet
* @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名rid必须加rId前缀例如rId1如果为-1处理所有编号的sheet
* @return this
* @throws POIException POI异常
*/
public Excel07SaxReader read(OPCPackage opcPackage, String idOrRid) throws POIException {
public Excel07SaxReader read(OPCPackage opcPackage, String idOrRidOrSheetName) throws POIException {
try {
return read(new XSSFReader(opcPackage), idOrRid);
return read(new XSSFReader(opcPackage), idOrRidOrSheetName);
} catch (OpenXML4JException e) {
throw new POIException(e);
} catch (IOException e) {
@ -113,12 +111,12 @@ public class Excel07SaxReader implements ExcelSaxReader<Excel07SaxReader> {
* 开始读取ExcelSheet编号从0开始计数
*
* @param xssfReader {@link XSSFReader}Excel读取器
* @param idOrRid Excel中的sheet id或者rid编号rid必须加rId前缀例如rId1如果为-1处理所有编号的sheet
* @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名rid必须加rId前缀例如rId1如果为-1处理所有编号的sheet
* @return this
* @throws POIException POI异常
* @since 5.4.4
*/
public Excel07SaxReader read(XSSFReader xssfReader, String idOrRid) throws POIException {
public Excel07SaxReader read(XSSFReader xssfReader, String idOrRidOrSheetName) throws POIException {
// 获取共享样式表样式非必须
try {
this.handler.stylesTable = xssfReader.getStylesTable();
@ -135,7 +133,7 @@ public class Excel07SaxReader implements ExcelSaxReader<Excel07SaxReader> {
throw new POIException(e);
}
return readSheets(xssfReader, idOrRid);
return readSheets(xssfReader, idOrRidOrSheetName);
}
// ------------------------------------------------------------------------------ Read end
@ -144,14 +142,14 @@ public class Excel07SaxReader implements ExcelSaxReader<Excel07SaxReader> {
/**
* 开始读取ExcelSheet编号从0开始计数
*
* @param xssfReader {@link XSSFReader}Excel读取器
* @param idOrRid Excel中的sheet id或者rid编号从0开始rid必须加rId前缀例如rId0如果为-1处理所有编号的sheet
* @param xssfReader {@link XSSFReader}Excel读取器
* @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名从0开始rid必须加rId前缀例如rId0如果为-1处理所有编号的sheet
* @return this
* @throws POIException POI异常
* @since 5.4.4
*/
private Excel07SaxReader readSheets(XSSFReader xssfReader, String idOrRid) throws POIException {
this.handler.sheetIndex = getSheetIndex(xssfReader, idOrRid);
private Excel07SaxReader readSheets(XSSFReader xssfReader, String idOrRidOrSheetName) throws POIException {
this.handler.sheetIndex = getSheetIndex(xssfReader, idOrRidOrSheetName);
InputStream sheetInputStream = null;
try {
if (this.handler.sheetIndex > -1) {
@ -187,29 +185,38 @@ public class Excel07SaxReader implements ExcelSaxReader<Excel07SaxReader> {
* <ul>
* <li>传入'rId'开头直接去除rId前缀</li>
* <li>传入纯数字表示sheetIndex通过{@link SheetRidReader}转换为rId</li>
* <li>传入其它字符串表示sheetName通过{@link SheetRidReader}转换为rId</li>
* </ul>
*
* @param xssfReader {@link XSSFReader}Excel读取器
* @param idOrRid Excel中的sheet id或者rid编号从0开始rid必须加rId前缀例如rId0如果为-1处理所有编号的sheet
* @param xssfReader {@link XSSFReader}Excel读取器
* @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名称从0开始rid必须加rId前缀例如rId0如果为-1处理所有编号的sheet
* @return sheet索引从0开始
* @since 5.5.5
*/
private int getSheetIndex(XSSFReader xssfReader, String idOrRid){
private int getSheetIndex(XSSFReader xssfReader, String idOrRidOrSheetName) {
// rid直接处理
if(StrUtil.startWithIgnoreCase(idOrRid, RID_PREFIX)){
return Integer.parseInt(StrUtil.removePrefixIgnoreCase(idOrRid, RID_PREFIX));
if (StrUtil.startWithIgnoreCase(idOrRidOrSheetName, RID_PREFIX)) {
return Integer.parseInt(StrUtil.removePrefixIgnoreCase(idOrRidOrSheetName, RID_PREFIX));
}
// sheetIndex需转换为rid
final int sheetIndex = Integer.parseInt(idOrRid);
final SheetRidReader ridReader = new SheetRidReader();
final Integer rid = ridReader.read(xssfReader).getRidBySheetIdBase0(sheetIndex);
final SheetRidReader ridReader = new SheetRidReader().read(xssfReader);
if(null != rid){
return rid;
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 (null != rid) {
return rid;
}
}
return sheetIndex;
throw new IllegalArgumentException("Invalid rId or id or sheetName: " + idOrRidOrSheetName);
}
// --------------------------------------------------------------------------------------- Private method end
}

View File

@ -15,6 +15,9 @@ import java.io.InputStream;
*/
public interface ExcelSaxReader<T> {
// sheet r:Id前缀
String RID_PREFIX = "rId";
/**
* 开始读取Excel
*

View File

@ -66,6 +66,11 @@ public class ExcelSaxReadTest {
ExcelUtil.readBySax("blankAndDateTest.xlsx", 0, createRowHandler());
}
@Test
public void readBySaxByNameTest() {
ExcelUtil.readBySax("blankAndDateTest.xlsx", "Sheet1", createRowHandler());
}
@Test
@Ignore
public void readBySaxTest2() {