diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3899a6d9b..f8f831059 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,7 @@
* 【http 】 完善StrUtil的注释(pr#186@Gitee)
* 【aop 】 去除调试日志(issue#1116@Github)
* 【core 】 增加'反转义(pr#1121@Github)
+* 【poi 】 增加SheetReader和XXXRowHandler(issue#I1WHJP@Gitee)
### Bug修复
* 【crypto 】 修复SM2验签后无法解密问题(issue#I1W0VP@Gitee)
diff --git a/hutool-cron/src/test/java/cn/hutool/cron/demo/CronTest.java b/hutool-cron/src/test/java/cn/hutool/cron/demo/CronTest.java
index 2f166c2c9..569e54cd4 100644
--- a/hutool-cron/src/test/java/cn/hutool/cron/demo/CronTest.java
+++ b/hutool-cron/src/test/java/cn/hutool/cron/demo/CronTest.java
@@ -1,12 +1,13 @@
package cn.hutool.cron.demo;
-import org.junit.Ignore;
-import org.junit.Test;
-
import cn.hutool.core.lang.Console;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.cron.CronUtil;
+import cn.hutool.cron.TaskExecutor;
+import cn.hutool.cron.listener.TaskListener;
import cn.hutool.cron.task.Task;
+import org.junit.Ignore;
+import org.junit.Test;
/**
* 定时任务样例
@@ -38,6 +39,23 @@ public class CronTest {
@Test
@Ignore
public void cronTest2() {
+ CronUtil.getScheduler().addListener(new TaskListener() {
+ @Override
+ public void onStart(TaskExecutor executor) {
+ Console.log("Listen task start!");
+ }
+
+ @Override
+ public void onSucceeded(TaskExecutor executor) {
+
+ }
+
+ @Override
+ public void onFailed(TaskExecutor executor, Throwable exception) {
+
+ }
+ });
+
// 支持秒级别定时任务
CronUtil.setMatchSecond(true);
CronUtil.start();
diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelExtractorUtil.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelExtractorUtil.java
new file mode 100644
index 000000000..db7022dff
--- /dev/null
+++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelExtractorUtil.java
@@ -0,0 +1,45 @@
+package cn.hutool.poi.excel;
+
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.extractor.ExcelExtractor;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.extractor.XSSFExcelExtractor;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+/**
+ * {@link ExcelExtractor}工具封装
+ *
+ * @author looly
+ * @since 5.4.4
+ */
+public class ExcelExtractorUtil {
+ /**
+ * 获取 {@link ExcelExtractor} 对象
+ *
+ * @return {@link ExcelExtractor}
+ */
+ public static ExcelExtractor getExtractor(Workbook wb) {
+ ExcelExtractor extractor;
+ if (wb instanceof HSSFWorkbook) {
+ extractor = new org.apache.poi.hssf.extractor.ExcelExtractor((HSSFWorkbook) wb);
+ } else {
+ extractor = new XSSFExcelExtractor((XSSFWorkbook) wb);
+ }
+ return extractor;
+ }
+
+ /**
+ * 读取为文本格式
+ * 使用{@link ExcelExtractor} 提取Excel内容
+ *
+ * @param wb {@link Workbook}
+ * @param withSheetName 是否附带sheet名
+ * @return Excel文本
+ * @since 4.1.0
+ */
+ public static String readAsText(Workbook wb, boolean withSheetName) {
+ final ExcelExtractor extractor = getExtractor(wb);
+ extractor.setIncludeSheetNames(withSheetName);
+ return extractor.getText();
+ }
+}
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 308de73b7..a8dd2c4e6 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
@@ -1,28 +1,22 @@
package cn.hutool.poi.excel;
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
-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 cn.hutool.poi.excel.reader.BeanSheetReader;
+import cn.hutool.poi.excel.reader.ListSheetReader;
+import cn.hutool.poi.excel.reader.MapSheetReader;
+import cn.hutool.poi.excel.reader.SheetReader;
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;
-import org.apache.poi.xssf.extractor.XSSFExcelExtractor;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.File;
import java.io.InputStream;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -256,37 +250,31 @@ public class ExcelReader extends ExcelBase {
}
/**
- * 读取工作簿中指定的Sheet
+ * 读取工作簿中指定的Sheet,此方法会把第一行作为标题行,替换标题别名
*
* @param startRowIndex 起始行(包含,从0开始计数)
* @param endRowIndex 结束行(包含,从0开始计数)
* @return 行的集合,一行使用List表示
*/
- @SuppressWarnings({"rawtypes", "unchecked"})
public List> read(int startRowIndex, int endRowIndex) {
- checkNotClosed();
- List> resultList = new ArrayList<>();
+ return read(startRowIndex, endRowIndex, true);
+ }
- startRowIndex = Math.max(startRowIndex, this.sheet.getFirstRowNum());// 读取起始行(包含)
- endRowIndex = Math.min(endRowIndex, this.sheet.getLastRowNum());// 读取结束行(包含)
- boolean isFirstLine = true;
- List rowList;
- for (int i = startRowIndex; i <= endRowIndex; i++) {
- rowList = readRow(i);
- if (CollUtil.isNotEmpty(rowList) || false == ignoreEmptyRow) {
- if (null == rowList) {
- rowList = new ArrayList<>(0);
- }
- if (isFirstLine) {
- isFirstLine = false;
- if (MapUtil.isNotEmpty(this.headerAlias)) {
- rowList = aliasHeader(rowList);
- }
- }
- resultList.add(rowList);
- }
- }
- return resultList;
+ /**
+ * 读取工作簿中指定的Sheet
+ *
+ * @param startRowIndex 起始行(包含,从0开始计数)
+ * @param endRowIndex 结束行(包含,从0开始计数)
+ * @param aliasFirstLine 是否首行作为标题行转换别名
+ * @return 行的集合,一行使用List表示
+ * @since 5.4.4
+ */
+ public List> read(int startRowIndex, int endRowIndex, boolean aliasFirstLine) {
+ final ListSheetReader reader = new ListSheetReader(startRowIndex, endRowIndex, aliasFirstLine);
+ reader.setCellEditor(this.cellEditor);
+ reader.setIgnoreEmptyRow(this.ignoreEmptyRow);
+ reader.setHeaderAlias(headerAlias);
+ return read(reader);
}
/**
@@ -348,33 +336,11 @@ public class ExcelReader extends ExcelBase {
* @return Map的列表
*/
public List