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

View File

@ -1,6 +1,7 @@
package cn.hutool.poi.excel.sax; package cn.hutool.poi.excel.sax;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil; 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;
@ -121,7 +122,7 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
* @throws POIException IO异常包装 * @throws POIException IO异常包装
*/ */
public Excel03SaxReader read(POIFSFileSystem fs, String id) throws POIException { public Excel03SaxReader read(POIFSFileSystem fs, String id) throws POIException {
this.rid = Integer.parseInt(id); this.rid = getSheetIndex(id);
formatListener = new FormatTrackingHSSFListener(new MissingRecordAwareHSSFListener(this)); formatListener = new FormatTrackingHSSFListener(new MissingRecordAwareHSSFListener(this));
final HSSFRequest request = new HSSFRequest(); final HSSFRequest request = new HSSFRequest();
@ -341,5 +342,32 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
private boolean isProcessCurrentSheet() { private boolean isProcessCurrentSheet() {
return this.rid < 0 || this.curRid == this.rid; 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 // ---------------------------------------------------------------------------------------------- Private method end
} }

View File

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

View File

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

View File

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