mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
add read
This commit is contained in:
parent
b6a9bc6991
commit
3bca95c34a
@ -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)
|
||||
|
@ -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读取器<br>
|
||||
* 读取Excel工作簿
|
||||
*
|
||||
*
|
||||
* @author Looly
|
||||
* @since 3.1.0
|
||||
*/
|
||||
public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/** 是否忽略空行 */
|
||||
/**
|
||||
* 是否忽略空行
|
||||
*/
|
||||
private boolean ignoreEmptyRow = true;
|
||||
/** 单元格值处理接口 */
|
||||
/**
|
||||
* 单元格值处理接口
|
||||
*/
|
||||
private CellEditor cellEditor;
|
||||
/** 标题别名 */
|
||||
/**
|
||||
* 标题别名
|
||||
*/
|
||||
private Map<String, String> 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<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @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<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @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<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @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<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @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<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @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<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @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<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
*
|
||||
* @param sheet Excel中的sheet
|
||||
*/
|
||||
public ExcelReader(Sheet sheet) {
|
||||
@ -125,9 +134,10 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
// ------------------------------------------------------------------------------------------------------- Constructor end
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------- Getters and Setters start
|
||||
|
||||
/**
|
||||
* 是否忽略空行
|
||||
*
|
||||
*
|
||||
* @return 是否忽略空行
|
||||
*/
|
||||
public boolean isIgnoreEmptyRow() {
|
||||
@ -136,7 +146,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 设置是否忽略空行
|
||||
*
|
||||
*
|
||||
* @param ignoreEmptyRow 是否忽略空行
|
||||
* @return this
|
||||
*/
|
||||
@ -148,7 +158,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
/**
|
||||
* 设置单元格值处理逻辑<br>
|
||||
* 当Excel中的值并不能满足我们的读取要求时,通过传入一个编辑接口,可以对单元格值自定义,例如对数字和日期类型值转换为字符串等
|
||||
*
|
||||
*
|
||||
* @param cellEditor 单元格值处理接口
|
||||
* @return this
|
||||
*/
|
||||
@ -159,7 +169,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 获得标题行的别名Map
|
||||
*
|
||||
*
|
||||
* @return 别名Map
|
||||
*/
|
||||
public Map<String, String> getHeaderAlias() {
|
||||
@ -168,7 +178,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 设置标题行的别名Map
|
||||
*
|
||||
*
|
||||
* @param headerAlias 别名Map
|
||||
* @return this
|
||||
*/
|
||||
@ -179,9 +189,9 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 增加标题别名
|
||||
*
|
||||
*
|
||||
* @param header 标题
|
||||
* @param alias 别名
|
||||
* @param alias 别名
|
||||
* @return this
|
||||
*/
|
||||
public ExcelReader addHeaderAlias(String header, String alias) {
|
||||
@ -191,7 +201,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 去除标题别名
|
||||
*
|
||||
*
|
||||
* @param header 标题
|
||||
* @return this
|
||||
*/
|
||||
@ -203,7 +213,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 读取工作簿中指定的Sheet的所有行列数据
|
||||
*
|
||||
*
|
||||
* @return 行的集合,一行使用List表示
|
||||
*/
|
||||
public List<List<Object>> read() {
|
||||
@ -212,7 +222,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 读取工作簿中指定的Sheet
|
||||
*
|
||||
*
|
||||
* @param startRowIndex 起始行(包含,从0开始计数)
|
||||
* @return 行的集合,一行使用List表示
|
||||
* @since 4.0.0
|
||||
@ -223,12 +233,12 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 读取工作簿中指定的Sheet
|
||||
*
|
||||
*
|
||||
* @param startRowIndex 起始行(包含,从0开始计数)
|
||||
* @param endRowIndex 结束行(包含,从0开始计数)
|
||||
* @param endRowIndex 结束行(包含,从0开始计数)
|
||||
* @return 行的集合,一行使用List表示
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public List<List<Object>> read(int startRowIndex, int endRowIndex) {
|
||||
checkNotClosed();
|
||||
List<List<Object>> resultList = new ArrayList<>();
|
||||
@ -255,10 +265,49 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
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>
|
||||
* Map表示一行,标题为key,单元格内容为value
|
||||
*
|
||||
*
|
||||
* @return Map的列表
|
||||
*/
|
||||
public List<Map<String, Object>> readAll() {
|
||||
@ -268,10 +317,10 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
/**
|
||||
* 读取Excel为Map的列表<br>
|
||||
* Map表示一行,标题为key,单元格内容为value
|
||||
*
|
||||
*
|
||||
* @param headerRowIndex 标题所在行,如果标题行在读取的内容行中间,这行做为数据将忽略
|
||||
* @param startRowIndex 起始行(包含,从0开始计数)
|
||||
* @param endRowIndex 读取结束行(包含,从0开始计数)
|
||||
* @param startRowIndex 起始行(包含,从0开始计数)
|
||||
* @param endRowIndex 读取结束行(包含,从0开始计数)
|
||||
* @return Map的列表
|
||||
*/
|
||||
public List<Map<String, Object>> read(int headerRowIndex, int startRowIndex, int endRowIndex) {
|
||||
@ -306,8 +355,8 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 读取Excel为Bean的列表,读取所有行,默认第一行做为标题,数据从第二行开始
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param beanType 每行对应Bean的类型
|
||||
* @return Map的列表
|
||||
*/
|
||||
@ -317,11 +366,11 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 读取Excel为Bean的列表
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param headerRowIndex 标题所在行,如果标题行在读取的内容行中间,这行做为数据将忽略,,从0开始计数
|
||||
* @param startRowIndex 起始行(包含,从0开始计数)
|
||||
* @param beanType 每行对应Bean的类型
|
||||
* @param startRowIndex 起始行(包含,从0开始计数)
|
||||
* @param beanType 每行对应Bean的类型
|
||||
* @return Map的列表
|
||||
* @since 4.0.1
|
||||
*/
|
||||
@ -331,12 +380,12 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 读取Excel为Bean的列表
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
*
|
||||
* @param <T> Bean类型
|
||||
* @param headerRowIndex 标题所在行,如果标题行在读取的内容行中间,这行做为数据将忽略,,从0开始计数
|
||||
* @param startRowIndex 起始行(包含,从0开始计数)
|
||||
* @param endRowIndex 读取结束行(包含,从0开始计数)
|
||||
* @param beanType 每行对应Bean的类型
|
||||
* @param startRowIndex 起始行(包含,从0开始计数)
|
||||
* @param endRowIndex 读取结束行(包含,从0开始计数)
|
||||
* @param beanType 每行对应Bean的类型
|
||||
* @return Map的列表
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -357,7 +406,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
/**
|
||||
* 读取为文本格式<br>
|
||||
* 使用{@link ExcelExtractor} 提取Excel内容
|
||||
*
|
||||
*
|
||||
* @param withSheetName 是否附带sheet名
|
||||
* @return Excel文本
|
||||
* @since 4.1.0
|
||||
@ -370,7 +419,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 获取 {@link ExcelExtractor} 对象
|
||||
*
|
||||
*
|
||||
* @return {@link ExcelExtractor}
|
||||
* @since 4.1.0
|
||||
*/
|
||||
@ -387,7 +436,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 读取某一行数据
|
||||
*
|
||||
*
|
||||
* @param rowIndex 行号,从0开始
|
||||
* @return 一行数据
|
||||
* @since 4.0.3
|
||||
@ -398,7 +447,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 读取某个单元格的值
|
||||
*
|
||||
*
|
||||
* @param x X坐标,从0计数,即列号
|
||||
* @param y Y坐标,从0计数,即行号
|
||||
* @return 值,如果单元格无值返回null
|
||||
@ -411,7 +460,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
/**
|
||||
* 获取Excel写出器<br>
|
||||
* 在读取Excel并做一定编辑后,获取写出器写出
|
||||
*
|
||||
*
|
||||
* @return {@link ExcelWriter}
|
||||
* @since 4.0.6
|
||||
*/
|
||||
@ -420,9 +469,10 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------------- Private methods start
|
||||
|
||||
/**
|
||||
* 读取一行
|
||||
*
|
||||
*
|
||||
* @param row 行
|
||||
* @return 单元格值列表
|
||||
*/
|
||||
@ -432,7 +482,7 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
|
||||
/**
|
||||
* 转换标题别名,如果没有别名则使用原标题,当标题为空时,列号对应的字母便是header
|
||||
*
|
||||
*
|
||||
* @param headerList 原标题列表
|
||||
* @return 转换别名列表
|
||||
*/
|
||||
@ -443,25 +493,25 @@ public class ExcelReader extends ExcelBase<ExcelReader> {
|
||||
return result;
|
||||
}
|
||||
|
||||
for(int i = 0; i < size; i++) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
result.add(aliasHeader(headerList.get(i), i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 转换标题别名,如果没有别名则使用原标题,当标题为空时,列号对应的字母便是header
|
||||
*
|
||||
*
|
||||
* @param headerObj 原标题
|
||||
* @param index 标题所在列号,当标题为空时,列号对应的字母便是header
|
||||
* @param index 标题所在列号,当标题为空时,列号对应的字母便是header
|
||||
* @return 转换别名列表
|
||||
* @since 4.3.2
|
||||
*/
|
||||
private String aliasHeader(Object headerObj, int index) {
|
||||
if(null == headerObj) {
|
||||
if (null == headerObj) {
|
||||
return ExcelUtil.indexToColName(index);
|
||||
}
|
||||
|
||||
|
||||
final String header = headerObj.toString();
|
||||
return ObjectUtil.defaultIfNull(this.headerAlias.get(header), header);
|
||||
}
|
||||
|
@ -4,13 +4,16 @@ import org.apache.poi.ss.usermodel.Cell;
|
||||
|
||||
/**
|
||||
* 单元格编辑器接口
|
||||
* @author Looly
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface CellEditor {
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param cell 单元格对象,可以获取单元格行、列样式等信息
|
||||
*
|
||||
* @param cell 单元格对象,可以获取单元格行、列样式等信息
|
||||
* @param value 单元格值
|
||||
* @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));
|
||||
}
|
||||
|
||||
@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