ソースを参照

add read by name support

Looly 5 年 前
コミット
dc440b2cc7

+ 1 - 0
CHANGELOG.md

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

+ 29 - 1
hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel03SaxReader.java

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

+ 34 - 27
hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel07SaxReader.java

@@ -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> {
 	 * 开始读取Excel,Sheet编号从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> {
 	 * 开始读取Excel,Sheet编号从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> {
 	/**
 	 * 开始读取Excel,Sheet编号从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
 }

+ 3 - 0
hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxReader.java

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

+ 5 - 0
hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelSaxReadTest.java

@@ -67,6 +67,11 @@ public class ExcelSaxReadTest {
 	}
 
 	@Test
+	public void readBySaxByNameTest() {
+		ExcelUtil.readBySax("blankAndDateTest.xlsx", "Sheet1", createRowHandler());
+	}
+
+	@Test
 	@Ignore
 	public void readBySaxTest2() {
 		ExcelUtil.readBySax("d:/test/456789.xlsx", "0", (sheetIndex, rowIndex, rowList) -> Console.log(rowList));