mirror of
https://gitee.com/dromara/hutool.git
synced 2025-05-04 04:37:59 +08:00
fix readBySax for xls not support sheetName
This commit is contained in:
parent
c5887344e9
commit
9c290c4bcc
@ -1583,6 +1583,57 @@ public class CollUtil {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取匹配规则定义中匹配到元素的第一个位置<br>
|
||||||
|
* 此方法对于某些无序集合的位置信息,以转换为数组后的位置为准。
|
||||||
|
*
|
||||||
|
* @param <T> 元素类型
|
||||||
|
* @param collection 集合
|
||||||
|
* @param matcher 匹配器,为空则全部匹配
|
||||||
|
* @return 第一个位置
|
||||||
|
* @since 5.6.6
|
||||||
|
*/
|
||||||
|
public static <T> int indexOf(Collection<T> collection, Matcher<T> matcher) {
|
||||||
|
if (isNotEmpty(collection)) {
|
||||||
|
int index = 0;
|
||||||
|
for (T t : collection) {
|
||||||
|
if (null == matcher || matcher.match(t)) {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取匹配规则定义中匹配到元素的最后位置<br>
|
||||||
|
* 此方法对于某些无序集合的位置信息,以转换为数组后的位置为准。
|
||||||
|
*
|
||||||
|
* @param <T> 元素类型
|
||||||
|
* @param collection 集合
|
||||||
|
* @param matcher 匹配器,为空则全部匹配
|
||||||
|
* @return 最后一个位置
|
||||||
|
* @since 5.6.6
|
||||||
|
*/
|
||||||
|
public static <T> int lastIndexOf(Collection<T> collection, Matcher<T> matcher) {
|
||||||
|
if(collection instanceof List){
|
||||||
|
// List的查找最后一个有优化算法
|
||||||
|
return ListUtil.lastIndexOf((List<T>)collection, matcher);
|
||||||
|
}
|
||||||
|
int matchIndex = -1;
|
||||||
|
if (isNotEmpty(collection)) {
|
||||||
|
int index = collection.size();
|
||||||
|
for (T t : collection) {
|
||||||
|
if (null == matcher || matcher.match(t)) {
|
||||||
|
matchIndex = index;
|
||||||
|
}
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return matchIndex;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取匹配规则定义中匹配到元素的所有位置<br>
|
* 获取匹配规则定义中匹配到元素的所有位置<br>
|
||||||
* 此方法对于某些无序集合的位置信息,以转换为数组后的位置为准。
|
* 此方法对于某些无序集合的位置信息,以转换为数组后的位置为准。
|
||||||
|
@ -2,7 +2,6 @@ package cn.hutool.core.collection;
|
|||||||
|
|
||||||
import cn.hutool.core.comparator.PinyinComparator;
|
import cn.hutool.core.comparator.PinyinComparator;
|
||||||
import cn.hutool.core.comparator.PropertyComparator;
|
import cn.hutool.core.comparator.PropertyComparator;
|
||||||
import cn.hutool.core.convert.Convert;
|
|
||||||
import cn.hutool.core.lang.Editor;
|
import cn.hutool.core.lang.Editor;
|
||||||
import cn.hutool.core.lang.Matcher;
|
import cn.hutool.core.lang.Matcher;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
@ -455,6 +454,30 @@ public class ListUtil {
|
|||||||
return list2;
|
return list2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取匹配规则定义中匹配到元素的最后位置<br>
|
||||||
|
* 此方法对于某些无序集合的位置信息,以转换为数组后的位置为准。
|
||||||
|
*
|
||||||
|
* @param <T> 元素类型
|
||||||
|
* @param list List集合
|
||||||
|
* @param matcher 匹配器,为空则全部匹配
|
||||||
|
* @return 最后一个位置
|
||||||
|
* @since 5.6.6
|
||||||
|
*/
|
||||||
|
public static <T> int lastIndexOf(List<T> list, Matcher<T> matcher) {
|
||||||
|
if (null != list) {
|
||||||
|
final int size = list.size();
|
||||||
|
if(size > 0){
|
||||||
|
for(int i = size -1; i >= 0; i--){
|
||||||
|
if (null == matcher || matcher.match(list.get(i))) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取匹配规则定义中匹配到元素的所有位置
|
* 获取匹配规则定义中匹配到元素的所有位置
|
||||||
*
|
*
|
||||||
@ -465,17 +488,7 @@ public class ListUtil {
|
|||||||
* @since 5.2.5
|
* @since 5.2.5
|
||||||
*/
|
*/
|
||||||
public static <T> int[] indexOfAll(List<T> list, Matcher<T> matcher) {
|
public static <T> int[] indexOfAll(List<T> list, Matcher<T> matcher) {
|
||||||
final List<Integer> indexList = new ArrayList<>();
|
return CollUtil.indexOfAll(list, matcher);
|
||||||
if (null != list) {
|
|
||||||
int index = 0;
|
|
||||||
for (T t : list) {
|
|
||||||
if (null == matcher || matcher.match(t)) {
|
|
||||||
indexList.add(index);
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Convert.convert(int[].class, indexList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -163,16 +163,36 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T firstMatch(Matcher<T> matcher, T... array) {
|
public static <T> T firstMatch(Matcher<T> matcher, T... array) {
|
||||||
if (isNotEmpty(array)) {
|
final int index = matchIndex(matcher, array);
|
||||||
for (final T val : array) {
|
if(index < 0){
|
||||||
if (matcher.match(val)) {
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return array[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回数组中第一个匹配规则的值的位置
|
||||||
|
*
|
||||||
|
* @param <T> 数组元素类型
|
||||||
|
* @param matcher 匹配接口,实现此接口自定义匹配规则
|
||||||
|
* @param array 数组
|
||||||
|
* @return 匹配到元素的位置,-1表示未匹配到
|
||||||
|
* @since 5.6.6
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T> int matchIndex(Matcher<T> matcher, T... array) {
|
||||||
|
if (isNotEmpty(array)) {
|
||||||
|
for(int i = 0; i < array.length; i++){
|
||||||
|
if(matcher.match(array[i])){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return INDEX_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新建一个空数组
|
* 新建一个空数组
|
||||||
*
|
*
|
||||||
@ -739,14 +759,7 @@ public class ArrayUtil extends PrimitiveArrayUtil {
|
|||||||
* @since 3.0.7
|
* @since 3.0.7
|
||||||
*/
|
*/
|
||||||
public static <T> int indexOf(T[] array, Object value) {
|
public static <T> int indexOf(T[] array, Object value) {
|
||||||
if (null != array) {
|
return matchIndex((obj)-> ObjectUtil.equal(value, obj), array);
|
||||||
for (int i = 0; i < array.length; i++) {
|
|
||||||
if (ObjectUtil.equal(value, array[i])) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return INDEX_NOT_FOUND;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -686,6 +686,29 @@ public class CollUtilTest {
|
|||||||
Assert.assertEquals(Integer.valueOf(1), countMap.get("d"));
|
Assert.assertEquals(Integer.valueOf(1), countMap.get("d"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void indexOfTest() {
|
||||||
|
ArrayList<String> list = CollUtil.newArrayList("a", "b", "c", "c", "a", "b", "d");
|
||||||
|
final int i = CollUtil.indexOf(list, (str) -> str.charAt(0) == 'c');
|
||||||
|
Assert.assertEquals(2, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lastIndexOfTest() {
|
||||||
|
// List有优化
|
||||||
|
ArrayList<String> list = CollUtil.newArrayList("a", "b", "c", "c", "a", "b", "d");
|
||||||
|
final int i = CollUtil.lastIndexOf(list, (str) -> str.charAt(0) == 'c');
|
||||||
|
Assert.assertEquals(3, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void lastIndexOfSetTest() {
|
||||||
|
Set<String> list = CollUtil.set(true, "a", "b", "c", "c", "a", "b", "d");
|
||||||
|
// 去重后c排第三
|
||||||
|
final int i = CollUtil.lastIndexOf(list, (str) -> str.charAt(0) == 'c');
|
||||||
|
Assert.assertEquals(2, i);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void pageTest(){
|
public void pageTest(){
|
||||||
List<Dict> objects = CollUtil.newArrayList();
|
List<Dict> objects = CollUtil.newArrayList();
|
||||||
|
@ -80,9 +80,19 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
|
|||||||
* 自定义需要处理的sheet编号,如果-1表示处理所有sheet
|
* 自定义需要处理的sheet编号,如果-1表示处理所有sheet
|
||||||
*/
|
*/
|
||||||
private int rid = -1;
|
private int rid = -1;
|
||||||
// 当前rid索引
|
/**
|
||||||
|
* sheet名称,主要用于使用sheet名读取的情况
|
||||||
|
*/
|
||||||
|
private String sheetName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当前rid索引
|
||||||
|
*/
|
||||||
private int curRid = -1;
|
private int curRid = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 行处理器
|
||||||
|
*/
|
||||||
private final RowHandler rowHandler;
|
private final RowHandler rowHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -159,9 +169,14 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
|
|||||||
* @return Sheet名
|
* @return Sheet名
|
||||||
*/
|
*/
|
||||||
public String getSheetName() {
|
public String getSheetName() {
|
||||||
|
if(null != this.sheetName){
|
||||||
|
return this.sheetName;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.boundSheetRecords.size() > this.rid) {
|
if (this.boundSheetRecords.size() > this.rid) {
|
||||||
return this.boundSheetRecords.get(this.rid > -1 ? this.rid : this.curRid).getSheetname();
|
return this.boundSheetRecords.get(this.rid > -1 ? this.rid : this.curRid).getSheetname();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +194,11 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
|
|||||||
|
|
||||||
if (record instanceof BoundSheetRecord) {
|
if (record instanceof BoundSheetRecord) {
|
||||||
// Sheet边界记录,此Record中可以获得Sheet名
|
// Sheet边界记录,此Record中可以获得Sheet名
|
||||||
boundSheetRecords.add((BoundSheetRecord) record);
|
final BoundSheetRecord boundSheetRecord = (BoundSheetRecord) record;
|
||||||
|
boundSheetRecords.add(boundSheetRecord);
|
||||||
|
if(this.rid < 0 && null != this.sheetName && StrUtil.equals(this.sheetName, boundSheetRecord.getSheetname())){
|
||||||
|
this.rid = this.boundSheetRecords.size() -1;
|
||||||
|
}
|
||||||
} else if (record instanceof SSTRecord) {
|
} else if (record instanceof SSTRecord) {
|
||||||
// 静态字符串表
|
// 静态字符串表
|
||||||
sstRecord = (SSTRecord) record;
|
sstRecord = (SSTRecord) record;
|
||||||
@ -193,6 +212,9 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
|
|||||||
curRid++;
|
curRid++;
|
||||||
}
|
}
|
||||||
} else if (record instanceof EOFRecord){
|
} else if (record instanceof EOFRecord){
|
||||||
|
if(this.rid < 0 && null != this.sheetName){
|
||||||
|
throw new POIException("Sheet [{}] not exist!", this.sheetName);
|
||||||
|
}
|
||||||
processLastCellSheet();
|
processLastCellSheet();
|
||||||
} else if (isProcessCurrentSheet()) {
|
} else if (isProcessCurrentSheet()) {
|
||||||
if (record instanceof MissingCellDummyRecord) {
|
if (record instanceof MissingCellDummyRecord) {
|
||||||
@ -340,7 +362,8 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
|
|||||||
* @return 是否处理当前sheet
|
* @return 是否处理当前sheet
|
||||||
*/
|
*/
|
||||||
private boolean isProcessCurrentSheet() {
|
private boolean isProcessCurrentSheet() {
|
||||||
return this.rid < 0 || this.curRid == this.rid;
|
// rid < 0 且 sheet名称存在,说明没有匹配到sheet名称
|
||||||
|
return (this.rid < 0 && null == this.sheetName) || this.rid == this.curRid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -365,31 +388,11 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
|
|||||||
final int sheetIndex;
|
final int sheetIndex;
|
||||||
try {
|
try {
|
||||||
return Integer.parseInt(idOrRidOrSheetName);
|
return Integer.parseInt(idOrRidOrSheetName);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException ignore) {
|
||||||
// 非数字,可能为sheet名称
|
// 如果用于传入非数字,按照sheet名称对待
|
||||||
sheetIndex = getSheetIndexByName(idOrRidOrSheetName);
|
this.sheetName = idOrRidOrSheetName;
|
||||||
if(sheetIndex > 0){
|
|
||||||
return sheetIndex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException("Invalid rId or id or sheetName: " + idOrRidOrSheetName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 通过sheet名称获取其位置(rid)
|
|
||||||
* @param sheetName sheet名称
|
|
||||||
* @return 位置,-1表示未找到
|
|
||||||
* @since 5.6.6
|
|
||||||
*/
|
|
||||||
private int getSheetIndexByName(String sheetName){
|
|
||||||
final List<BoundSheetRecord> boundSheetRecords = this.boundSheetRecords;
|
|
||||||
final int size = boundSheetRecords.size();
|
|
||||||
for(int i = 0; i < size; i++){
|
|
||||||
if(StrUtil.equals(sheetName, boundSheetRecords.get(i).getSheetname())){
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------------------------- Private method end
|
// ---------------------------------------------------------------------------------------------- Private method end
|
||||||
|
@ -75,24 +75,24 @@ public interface ExcelSaxReader<T> {
|
|||||||
* 开始读取Excel
|
* 开始读取Excel
|
||||||
*
|
*
|
||||||
* @param path 文件路径
|
* @param path 文件路径
|
||||||
* @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet
|
* @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名称,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
|
||||||
* @return this
|
* @return this
|
||||||
* @throws POIException POI异常
|
* @throws POIException POI异常
|
||||||
*/
|
*/
|
||||||
default T read(String path, int rid) throws POIException {
|
default T read(String path, int idOrRidOrSheetName) throws POIException {
|
||||||
return read(FileUtil.file(path), rid);
|
return read(FileUtil.file(path), idOrRidOrSheetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开始读取Excel
|
* 开始读取Excel
|
||||||
*
|
*
|
||||||
* @param path 文件路径
|
* @param path 文件路径
|
||||||
* @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet
|
* @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名称,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
|
||||||
* @return this
|
* @return this
|
||||||
* @throws POIException POI异常
|
* @throws POIException POI异常
|
||||||
*/
|
*/
|
||||||
default T read(String path, String rid) throws POIException {
|
default T read(String path, String idOrRidOrSheetName) throws POIException {
|
||||||
return read(FileUtil.file(path), rid);
|
return read(FileUtil.file(path), idOrRidOrSheetName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,6 +9,7 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import cn.hutool.poi.excel.cell.FormulaCellValue;
|
import cn.hutool.poi.excel.cell.FormulaCellValue;
|
||||||
import cn.hutool.poi.excel.sax.Excel03SaxReader;
|
import cn.hutool.poi.excel.sax.Excel03SaxReader;
|
||||||
import cn.hutool.poi.excel.sax.handler.RowHandler;
|
import cn.hutool.poi.excel.sax.handler.RowHandler;
|
||||||
|
import cn.hutool.poi.exceptions.POIException;
|
||||||
import org.apache.poi.ss.usermodel.CellStyle;
|
import org.apache.poi.ss.usermodel.CellStyle;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
@ -41,10 +42,24 @@ public class ExcelSaxReadTest {
|
|||||||
public void excel03Test() {
|
public void excel03Test() {
|
||||||
Excel03SaxReader reader = new Excel03SaxReader(createRowHandler());
|
Excel03SaxReader reader = new Excel03SaxReader(createRowHandler());
|
||||||
reader.read("aaa.xls", 1);
|
reader.read("aaa.xls", 1);
|
||||||
|
|
||||||
// Console.log("Sheet index: [{}], Sheet name: [{}]", reader.getSheetIndex(), reader.getSheetName());
|
// Console.log("Sheet index: [{}], Sheet name: [{}]", reader.getSheetIndex(), reader.getSheetName());
|
||||||
ExcelUtil.readBySax("aaa.xls", 1, createRowHandler());
|
ExcelUtil.readBySax("aaa.xls", 1, createRowHandler());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void excel03ByNameTest() {
|
||||||
|
Excel03SaxReader reader = new Excel03SaxReader(createRowHandler());
|
||||||
|
reader.read("aaa.xls", "校园入学");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = POIException.class)
|
||||||
|
public void excel03ByNameErrorTest() {
|
||||||
|
// sheet名称不存在则报错
|
||||||
|
Excel03SaxReader reader = new Excel03SaxReader(createRowHandler());
|
||||||
|
reader.read("aaa.xls", "校园入学1");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
public void readBlankLineTest() {
|
public void readBlankLineTest() {
|
||||||
@ -124,7 +139,6 @@ public class ExcelSaxReadTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void formulaRead03Test() {
|
public void formulaRead03Test() {
|
||||||
Console.log(FileUtil.file("data_for_sax_test.xls"));
|
|
||||||
List<Object> rows = new ArrayList<>();
|
List<Object> rows = new ArrayList<>();
|
||||||
ExcelUtil.readBySax("data_for_sax_test.xls", -1, (i, i1, list) -> {
|
ExcelUtil.readBySax("data_for_sax_test.xls", -1, (i, i1, list) -> {
|
||||||
if(list.size() > 1){
|
if(list.size() > 1){
|
||||||
|
Loading…
Reference in New Issue
Block a user