mirror of
https://gitee.com/dromara/hutool.git
synced 2025-07-17 01:46:22 +08:00
add read
This commit is contained in:
parent
b6a9bc6991
commit
3bca95c34a
@ -15,6 +15,7 @@
|
|||||||
* 【core 】 增加StrUtil.removeAny方法(issue#923@Github)
|
* 【core 】 增加StrUtil.removeAny方法(issue#923@Github)
|
||||||
* 【db 】 增加部分Connection参数支持(issue#924@Github)
|
* 【db 】 增加部分Connection参数支持(issue#924@Github)
|
||||||
* 【core 】 FileUtil增加别名方法(pr#926@Github)
|
* 【core 】 FileUtil增加别名方法(pr#926@Github)
|
||||||
|
* 【poi 】 EcelReader中增加read重载,提供每个单元格单独处理的方法(issue#I1JZTL@Gitee)
|
||||||
|
|
||||||
### Bug修复
|
### Bug修复
|
||||||
* 【json 】 修复append方法导致的JSONConfig传递失效问题(issue#906@Github)
|
* 【json 】 修复append方法导致的JSONConfig传递失效问题(issue#906@Github)
|
||||||
|
@ -9,9 +9,11 @@ import cn.hutool.core.map.MapUtil;
|
|||||||
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.cell.CellEditor;
|
import cn.hutool.poi.excel.cell.CellEditor;
|
||||||
|
import cn.hutool.poi.excel.cell.CellHandler;
|
||||||
import cn.hutool.poi.excel.cell.CellUtil;
|
import cn.hutool.poi.excel.cell.CellUtil;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
import org.apache.poi.ss.extractor.ExcelExtractor;
|
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.Row;
|
||||||
import org.apache.poi.ss.usermodel.Sheet;
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
@ -34,19 +36,26 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class ExcelReader extends ExcelBase<ExcelReader> {
|
public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||||
|
|
||||||
/** 是否忽略空行 */
|
/**
|
||||||
|
* 是否忽略空行
|
||||||
|
*/
|
||||||
private boolean ignoreEmptyRow = true;
|
private boolean ignoreEmptyRow = true;
|
||||||
/** 单元格值处理接口 */
|
/**
|
||||||
|
* 单元格值处理接口
|
||||||
|
*/
|
||||||
private CellEditor cellEditor;
|
private CellEditor cellEditor;
|
||||||
/** 标题别名 */
|
/**
|
||||||
|
* 标题别名
|
||||||
|
*/
|
||||||
private Map<String, String> headerAlias = new HashMap<>();
|
private Map<String, String> headerAlias = new HashMap<>();
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------------- Constructor start
|
// ------------------------------------------------------------------------------------------------------- Constructor start
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param excelFilePath Excel文件路径,绝对路径或相对于ClassPath路径
|
* @param excelFilePath Excel文件路径,绝对路径或相对于ClassPath路径
|
||||||
* @param sheetIndex sheet序号,0表示第一个sheet
|
* @param sheetIndex sheet序号,0表示第一个sheet
|
||||||
*/
|
*/
|
||||||
public ExcelReader(String excelFilePath, int sheetIndex) {
|
public ExcelReader(String excelFilePath, int sheetIndex) {
|
||||||
this(FileUtil.file(excelFilePath), sheetIndex);
|
this(FileUtil.file(excelFilePath), sheetIndex);
|
||||||
@ -55,7 +64,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param bookFile Excel文件
|
* @param bookFile Excel文件
|
||||||
* @param sheetIndex sheet序号,0表示第一个sheet
|
* @param sheetIndex sheet序号,0表示第一个sheet
|
||||||
*/
|
*/
|
||||||
public ExcelReader(File bookFile, int sheetIndex) {
|
public ExcelReader(File bookFile, int sheetIndex) {
|
||||||
@ -65,7 +74,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param bookFile Excel文件
|
* @param bookFile Excel文件
|
||||||
* @param sheetName sheet名,第一个默认是sheet1
|
* @param sheetName sheet名,第一个默认是sheet1
|
||||||
*/
|
*/
|
||||||
public ExcelReader(File bookFile, String sheetName) {
|
public ExcelReader(File bookFile, String sheetName) {
|
||||||
@ -75,8 +84,8 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param bookStream Excel文件的流
|
* @param bookStream Excel文件的流
|
||||||
* @param sheetIndex sheet序号,0表示第一个sheet
|
* @param sheetIndex sheet序号,0表示第一个sheet
|
||||||
* @param closeAfterRead 读取结束是否关闭流
|
* @param closeAfterRead 读取结束是否关闭流
|
||||||
*/
|
*/
|
||||||
public ExcelReader(InputStream bookStream, int sheetIndex, boolean closeAfterRead) {
|
public ExcelReader(InputStream bookStream, int sheetIndex, boolean closeAfterRead) {
|
||||||
@ -86,8 +95,8 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param bookStream Excel文件的流
|
* @param bookStream Excel文件的流
|
||||||
* @param sheetName sheet名,第一个默认是sheet1
|
* @param sheetName sheet名,第一个默认是sheet1
|
||||||
* @param closeAfterRead 读取结束是否关闭流
|
* @param closeAfterRead 读取结束是否关闭流
|
||||||
*/
|
*/
|
||||||
public ExcelReader(InputStream bookStream, String sheetName, boolean closeAfterRead) {
|
public ExcelReader(InputStream bookStream, String sheetName, boolean closeAfterRead) {
|
||||||
@ -97,7 +106,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param book {@link Workbook} 表示一个Excel文件
|
* @param book {@link Workbook} 表示一个Excel文件
|
||||||
* @param sheetIndex sheet序号,0表示第一个sheet
|
* @param sheetIndex sheet序号,0表示第一个sheet
|
||||||
*/
|
*/
|
||||||
public ExcelReader(Workbook book, int sheetIndex) {
|
public ExcelReader(Workbook book, int sheetIndex) {
|
||||||
@ -107,7 +116,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
/**
|
/**
|
||||||
* 构造
|
* 构造
|
||||||
*
|
*
|
||||||
* @param book {@link Workbook} 表示一个Excel文件
|
* @param book {@link Workbook} 表示一个Excel文件
|
||||||
* @param sheetName sheet名,第一个默认是sheet1
|
* @param sheetName sheet名,第一个默认是sheet1
|
||||||
*/
|
*/
|
||||||
public ExcelReader(Workbook book, String sheetName) {
|
public ExcelReader(Workbook book, String sheetName) {
|
||||||
@ -125,6 +134,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
// ------------------------------------------------------------------------------------------------------- Constructor end
|
// ------------------------------------------------------------------------------------------------------- Constructor end
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------------- Getters and Setters start
|
// ------------------------------------------------------------------------------------------------------- Getters and Setters start
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否忽略空行
|
* 是否忽略空行
|
||||||
*
|
*
|
||||||
@ -181,7 +191,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
* 增加标题别名
|
* 增加标题别名
|
||||||
*
|
*
|
||||||
* @param header 标题
|
* @param header 标题
|
||||||
* @param alias 别名
|
* @param alias 别名
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public ExcelReader addHeaderAlias(String header, String alias) {
|
public ExcelReader addHeaderAlias(String header, String alias) {
|
||||||
@ -225,10 +235,10 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
* 读取工作簿中指定的Sheet
|
* 读取工作簿中指定的Sheet
|
||||||
*
|
*
|
||||||
* @param startRowIndex 起始行(包含,从0开始计数)
|
* @param startRowIndex 起始行(包含,从0开始计数)
|
||||||
* @param endRowIndex 结束行(包含,从0开始计数)
|
* @param endRowIndex 结束行(包含,从0开始计数)
|
||||||
* @return 行的集合,一行使用List表示
|
* @return 行的集合,一行使用List表示
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||||
public List<List<Object>> read(int startRowIndex, int endRowIndex) {
|
public List<List<Object>> read(int startRowIndex, int endRowIndex) {
|
||||||
checkNotClosed();
|
checkNotClosed();
|
||||||
List<List<Object>> resultList = new ArrayList<>();
|
List<List<Object>> resultList = new ArrayList<>();
|
||||||
@ -255,6 +265,45 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
return resultList;
|
return resultList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取工作簿中指定的Sheet,此方法为类流处理方式,当读到指定单元格时,会调用CellEditor接口<br>
|
||||||
|
* 用户通过实现此接口,可以更加灵活的处理每个单元格的数据。
|
||||||
|
*
|
||||||
|
* @param cellHandler 单元格处理器,用于处理读到的单元格及其数据
|
||||||
|
* @since 5.3.8
|
||||||
|
*/
|
||||||
|
public void read(CellHandler cellHandler) {
|
||||||
|
read(0, Integer.MAX_VALUE, cellHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取工作簿中指定的Sheet,此方法为类流处理方式,当读到指定单元格时,会调用CellEditor接口<br>
|
||||||
|
* 用户通过实现此接口,可以更加灵活的处理每个单元格的数据。
|
||||||
|
*
|
||||||
|
* @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的列表,读取所有行,默认第一行做为标题,数据从第二行开始<br>
|
* 读取Excel为Map的列表,读取所有行,默认第一行做为标题,数据从第二行开始<br>
|
||||||
* Map表示一行,标题为key,单元格内容为value
|
* Map表示一行,标题为key,单元格内容为value
|
||||||
@ -270,8 +319,8 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
* Map表示一行,标题为key,单元格内容为value
|
* Map表示一行,标题为key,单元格内容为value
|
||||||
*
|
*
|
||||||
* @param headerRowIndex 标题所在行,如果标题行在读取的内容行中间,这行做为数据将忽略
|
* @param headerRowIndex 标题所在行,如果标题行在读取的内容行中间,这行做为数据将忽略
|
||||||
* @param startRowIndex 起始行(包含,从0开始计数)
|
* @param startRowIndex 起始行(包含,从0开始计数)
|
||||||
* @param endRowIndex 读取结束行(包含,从0开始计数)
|
* @param endRowIndex 读取结束行(包含,从0开始计数)
|
||||||
* @return Map的列表
|
* @return Map的列表
|
||||||
*/
|
*/
|
||||||
public List<Map<String, Object>> read(int headerRowIndex, int startRowIndex, int endRowIndex) {
|
public List<Map<String, Object>> read(int headerRowIndex, int startRowIndex, int endRowIndex) {
|
||||||
@ -307,7 +356,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
/**
|
/**
|
||||||
* 读取Excel为Bean的列表,读取所有行,默认第一行做为标题,数据从第二行开始
|
* 读取Excel为Bean的列表,读取所有行,默认第一行做为标题,数据从第二行开始
|
||||||
*
|
*
|
||||||
* @param <T> Bean类型
|
* @param <T> Bean类型
|
||||||
* @param beanType 每行对应Bean的类型
|
* @param beanType 每行对应Bean的类型
|
||||||
* @return Map的列表
|
* @return Map的列表
|
||||||
*/
|
*/
|
||||||
@ -318,10 +367,10 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
/**
|
/**
|
||||||
* 读取Excel为Bean的列表
|
* 读取Excel为Bean的列表
|
||||||
*
|
*
|
||||||
* @param <T> Bean类型
|
* @param <T> Bean类型
|
||||||
* @param headerRowIndex 标题所在行,如果标题行在读取的内容行中间,这行做为数据将忽略,,从0开始计数
|
* @param headerRowIndex 标题所在行,如果标题行在读取的内容行中间,这行做为数据将忽略,,从0开始计数
|
||||||
* @param startRowIndex 起始行(包含,从0开始计数)
|
* @param startRowIndex 起始行(包含,从0开始计数)
|
||||||
* @param beanType 每行对应Bean的类型
|
* @param beanType 每行对应Bean的类型
|
||||||
* @return Map的列表
|
* @return Map的列表
|
||||||
* @since 4.0.1
|
* @since 4.0.1
|
||||||
*/
|
*/
|
||||||
@ -332,11 +381,11 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
/**
|
/**
|
||||||
* 读取Excel为Bean的列表
|
* 读取Excel为Bean的列表
|
||||||
*
|
*
|
||||||
* @param <T> Bean类型
|
* @param <T> Bean类型
|
||||||
* @param headerRowIndex 标题所在行,如果标题行在读取的内容行中间,这行做为数据将忽略,,从0开始计数
|
* @param headerRowIndex 标题所在行,如果标题行在读取的内容行中间,这行做为数据将忽略,,从0开始计数
|
||||||
* @param startRowIndex 起始行(包含,从0开始计数)
|
* @param startRowIndex 起始行(包含,从0开始计数)
|
||||||
* @param endRowIndex 读取结束行(包含,从0开始计数)
|
* @param endRowIndex 读取结束行(包含,从0开始计数)
|
||||||
* @param beanType 每行对应Bean的类型
|
* @param beanType 每行对应Bean的类型
|
||||||
* @return Map的列表
|
* @return Map的列表
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@ -420,6 +469,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------------- Private methods start
|
// ------------------------------------------------------------------------------------------------------- Private methods start
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取一行
|
* 读取一行
|
||||||
*
|
*
|
||||||
@ -443,7 +493,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
result.add(aliasHeader(headerList.get(i), i));
|
result.add(aliasHeader(headerList.get(i), i));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -453,12 +503,12 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
|||||||
* 转换标题别名,如果没有别名则使用原标题,当标题为空时,列号对应的字母便是header
|
* 转换标题别名,如果没有别名则使用原标题,当标题为空时,列号对应的字母便是header
|
||||||
*
|
*
|
||||||
* @param headerObj 原标题
|
* @param headerObj 原标题
|
||||||
* @param index 标题所在列号,当标题为空时,列号对应的字母便是header
|
* @param index 标题所在列号,当标题为空时,列号对应的字母便是header
|
||||||
* @return 转换别名列表
|
* @return 转换别名列表
|
||||||
* @since 4.3.2
|
* @since 4.3.2
|
||||||
*/
|
*/
|
||||||
private String aliasHeader(Object headerObj, int index) {
|
private String aliasHeader(Object headerObj, int index) {
|
||||||
if(null == headerObj) {
|
if (null == headerObj) {
|
||||||
return ExcelUtil.indexToColName(index);
|
return ExcelUtil.indexToColName(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,13 +4,16 @@ import org.apache.poi.ss.usermodel.Cell;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 单元格编辑器接口
|
* 单元格编辑器接口
|
||||||
* @author Looly
|
|
||||||
*
|
*
|
||||||
|
* @author Looly
|
||||||
*/
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
public interface CellEditor {
|
public interface CellEditor {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 编辑
|
* 编辑
|
||||||
* @param cell 单元格对象,可以获取单元格行、列样式等信息
|
*
|
||||||
|
* @param cell 单元格对象,可以获取单元格行、列样式等信息
|
||||||
* @param value 单元格值
|
* @param value 单元格值
|
||||||
* @return 编辑后的对象
|
* @return 编辑后的对象
|
||||||
*/
|
*/
|
||||||
|
@ -0,0 +1,20 @@
|
|||||||
|
package cn.hutool.poi.excel.cell;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单元格处理器接口
|
||||||
|
*
|
||||||
|
* @author Looly
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface CellHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理
|
||||||
|
*
|
||||||
|
* @param cell 单元格对象,可以获取单元格行、列样式等信息
|
||||||
|
* @param value 单元格值
|
||||||
|
*/
|
||||||
|
void handle(Cell cell, Object value);
|
||||||
|
}
|
@ -208,4 +208,10 @@ public class ExcelReadTest {
|
|||||||
Assert.assertEquals(11L, read.get(2).get(2));
|
Assert.assertEquals(11L, read.get(2).get(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void readCellsTest() {
|
||||||
|
final ExcelReader reader = ExcelUtil.getReader("merge_test.xlsx");
|
||||||
|
reader.read((cell, value)-> Console.log("{}, {} {}", cell.getRowIndex(), cell.getColumnIndex(), value));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user