diff --git a/CHANGELOG.md b/CHANGELOG.md
index da3a74429..992c4315c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@
* 【core 】 增加StrUtil.removeAny方法(issue#923@Github)
* 【db 】 增加部分Connection参数支持(issue#924@Github)
* 【core 】 FileUtil增加别名方法(pr#926@Github)
+* 【poi 】 EcelReader中增加read重载,提供每个单元格单独处理的方法(issue#I1JZTL@Gitee)
### Bug修复
* 【json 】 修复append方法导致的JSONConfig传递失效问题(issue#906@Github)
diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelReader.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelReader.java
index 5c8cbb013..47b9fa924 100644
--- a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelReader.java
+++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelReader.java
@@ -9,9 +9,11 @@ import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.cell.CellEditor;
+import cn.hutool.poi.excel.cell.CellHandler;
import cn.hutool.poi.excel.cell.CellUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.extractor.ExcelExtractor;
+import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
@@ -28,25 +30,32 @@ import java.util.Map;
/**
* Excel读取器
* 读取Excel工作簿
- *
+ *
* @author Looly
* @since 3.1.0
*/
public class ExcelReader extends ExcelBase {
- /** 是否忽略空行 */
+ /**
+ * 是否忽略空行
+ */
private boolean ignoreEmptyRow = true;
- /** 单元格值处理接口 */
+ /**
+ * 单元格值处理接口
+ */
private CellEditor cellEditor;
- /** 标题别名 */
+ /**
+ * 标题别名
+ */
private Map headerAlias = new HashMap<>();
// ------------------------------------------------------------------------------------------------------- Constructor start
+
/**
* 构造
- *
+ *
* @param excelFilePath Excel文件路径,绝对路径或相对于ClassPath路径
- * @param sheetIndex sheet序号,0表示第一个sheet
+ * @param sheetIndex sheet序号,0表示第一个sheet
*/
public ExcelReader(String excelFilePath, int sheetIndex) {
this(FileUtil.file(excelFilePath), sheetIndex);
@@ -54,8 +63,8 @@ public class ExcelReader extends ExcelBase {
/**
* 构造
- *
- * @param bookFile Excel文件
+ *
+ * @param bookFile Excel文件
* @param sheetIndex sheet序号,0表示第一个sheet
*/
public ExcelReader(File bookFile, int sheetIndex) {
@@ -64,8 +73,8 @@ public class ExcelReader extends ExcelBase {
/**
* 构造
- *
- * @param bookFile Excel文件
+ *
+ * @param bookFile Excel文件
* @param sheetName sheet名,第一个默认是sheet1
*/
public ExcelReader(File bookFile, String sheetName) {
@@ -74,9 +83,9 @@ public class ExcelReader extends ExcelBase {
/**
* 构造
- *
- * @param bookStream Excel文件的流
- * @param sheetIndex sheet序号,0表示第一个sheet
+ *
+ * @param bookStream Excel文件的流
+ * @param sheetIndex sheet序号,0表示第一个sheet
* @param closeAfterRead 读取结束是否关闭流
*/
public ExcelReader(InputStream bookStream, int sheetIndex, boolean closeAfterRead) {
@@ -85,9 +94,9 @@ public class ExcelReader extends ExcelBase {
/**
* 构造
- *
- * @param bookStream Excel文件的流
- * @param sheetName sheet名,第一个默认是sheet1
+ *
+ * @param bookStream Excel文件的流
+ * @param sheetName sheet名,第一个默认是sheet1
* @param closeAfterRead 读取结束是否关闭流
*/
public ExcelReader(InputStream bookStream, String sheetName, boolean closeAfterRead) {
@@ -96,8 +105,8 @@ public class ExcelReader extends ExcelBase {
/**
* 构造
- *
- * @param book {@link Workbook} 表示一个Excel文件
+ *
+ * @param book {@link Workbook} 表示一个Excel文件
* @param sheetIndex sheet序号,0表示第一个sheet
*/
public ExcelReader(Workbook book, int sheetIndex) {
@@ -106,8 +115,8 @@ public class ExcelReader extends ExcelBase {
/**
* 构造
- *
- * @param book {@link Workbook} 表示一个Excel文件
+ *
+ * @param book {@link Workbook} 表示一个Excel文件
* @param sheetName sheet名,第一个默认是sheet1
*/
public ExcelReader(Workbook book, String sheetName) {
@@ -116,7 +125,7 @@ public class ExcelReader extends ExcelBase {
/**
* 构造
- *
+ *
* @param sheet Excel中的sheet
*/
public ExcelReader(Sheet sheet) {
@@ -125,9 +134,10 @@ public class ExcelReader extends ExcelBase {
// ------------------------------------------------------------------------------------------------------- Constructor end
// ------------------------------------------------------------------------------------------------------- Getters and Setters start
+
/**
* 是否忽略空行
- *
+ *
* @return 是否忽略空行
*/
public boolean isIgnoreEmptyRow() {
@@ -136,7 +146,7 @@ public class ExcelReader extends ExcelBase {
/**
* 设置是否忽略空行
- *
+ *
* @param ignoreEmptyRow 是否忽略空行
* @return this
*/
@@ -148,7 +158,7 @@ public class ExcelReader extends ExcelBase {
/**
* 设置单元格值处理逻辑
* 当Excel中的值并不能满足我们的读取要求时,通过传入一个编辑接口,可以对单元格值自定义,例如对数字和日期类型值转换为字符串等
- *
+ *
* @param cellEditor 单元格值处理接口
* @return this
*/
@@ -159,7 +169,7 @@ public class ExcelReader extends ExcelBase {
/**
* 获得标题行的别名Map
- *
+ *
* @return 别名Map
*/
public Map getHeaderAlias() {
@@ -168,7 +178,7 @@ public class ExcelReader extends ExcelBase {
/**
* 设置标题行的别名Map
- *
+ *
* @param headerAlias 别名Map
* @return this
*/
@@ -179,9 +189,9 @@ public class ExcelReader extends ExcelBase {
/**
* 增加标题别名
- *
+ *
* @param header 标题
- * @param alias 别名
+ * @param alias 别名
* @return this
*/
public ExcelReader addHeaderAlias(String header, String alias) {
@@ -191,7 +201,7 @@ public class ExcelReader extends ExcelBase {
/**
* 去除标题别名
- *
+ *
* @param header 标题
* @return this
*/
@@ -203,7 +213,7 @@ public class ExcelReader extends ExcelBase {
/**
* 读取工作簿中指定的Sheet的所有行列数据
- *
+ *
* @return 行的集合,一行使用List表示
*/
public List> read() {
@@ -212,7 +222,7 @@ public class ExcelReader extends ExcelBase {
/**
* 读取工作簿中指定的Sheet
- *
+ *
* @param startRowIndex 起始行(包含,从0开始计数)
* @return 行的集合,一行使用List表示
* @since 4.0.0
@@ -223,12 +233,12 @@ public class ExcelReader extends ExcelBase {
/**
* 读取工作簿中指定的Sheet
- *
+ *
* @param startRowIndex 起始行(包含,从0开始计数)
- * @param endRowIndex 结束行(包含,从0开始计数)
+ * @param endRowIndex 结束行(包含,从0开始计数)
* @return 行的集合,一行使用List表示
*/
- @SuppressWarnings({ "rawtypes", "unchecked" })
+ @SuppressWarnings({"rawtypes", "unchecked"})
public List> read(int startRowIndex, int endRowIndex) {
checkNotClosed();
List> resultList = new ArrayList<>();
@@ -255,10 +265,49 @@ public class ExcelReader extends ExcelBase {
return resultList;
}
+ /**
+ * 读取工作簿中指定的Sheet,此方法为类流处理方式,当读到指定单元格时,会调用CellEditor接口
+ * 用户通过实现此接口,可以更加灵活的处理每个单元格的数据。
+ *
+ * @param cellHandler 单元格处理器,用于处理读到的单元格及其数据
+ * @since 5.3.8
+ */
+ public void read(CellHandler cellHandler) {
+ read(0, Integer.MAX_VALUE, cellHandler);
+ }
+
+ /**
+ * 读取工作簿中指定的Sheet,此方法为类流处理方式,当读到指定单元格时,会调用CellEditor接口
+ * 用户通过实现此接口,可以更加灵活的处理每个单元格的数据。
+ *
+ * @param startRowIndex 起始行(包含,从0开始计数)
+ * @param endRowIndex 结束行(包含,从0开始计数)
+ * @param cellHandler 单元格处理器,用于处理读到的单元格及其数据
+ * @since 5.3.8
+ */
+ public void read(int startRowIndex, int endRowIndex, CellHandler cellHandler) {
+ checkNotClosed();
+
+ startRowIndex = Math.max(startRowIndex, this.sheet.getFirstRowNum());// 读取起始行(包含)
+ endRowIndex = Math.min(endRowIndex, this.sheet.getLastRowNum());// 读取结束行(包含)
+
+ Row row;
+ short columnSize;
+ for (int y = startRowIndex; y <= endRowIndex; y++) {
+ row = this.sheet.getRow(y);
+ columnSize = row.getLastCellNum();
+ Cell cell;
+ for (short x = 0; x < columnSize; x++) {
+ cell = row.getCell(x);
+ cellHandler.handle(cell, CellUtil.getCellValue(cell));
+ }
+ }
+ }
+
/**
* 读取Excel为Map的列表,读取所有行,默认第一行做为标题,数据从第二行开始
* Map表示一行,标题为key,单元格内容为value
- *
+ *
* @return Map的列表
*/
public List