bodys : BODY_LIST) {
- for (int i = 0; i < bodys.size(); i++) {
- if (i == 0) {
- sb.append('|');
- }
- String body = bodys.get(i);
- sb.append(Convert.toSBC(" "));
- sb.append(body);
- sb.append(Convert.toSBC(" "));
- int l = body.length();
- int lw = columnCharNumber.get(i);
- if (lw > l) {
- for (int j = 0; j < (lw - l); j++) {
- sb.append(Convert.toSBC(" "));
- }
- }
- sb.append('|');
- }
- sb.append('\n');
- }
- fillBorder(sb);
- return sb.toString();
- }
-
- /**
- * 拼装边框
- *
- * @param sb
- */
- private void fillBorder(StringBuilder sb) {
- sb.append('*');
- for (Integer width : columnCharNumber) {
- sb.append(Convert.toSBC(StrUtil.fillAfter("", '-', width + 2)));
- sb.append('*');
- }
- sb.append('\n');
- }
-
- /**
- * 打印到控制台
- */
- public void print() {
- Console.print(toString());
- }
-
-}
\ No newline at end of file
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ArrayUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ArrayUtil.java
index a16f40b78..c09dd1b87 100644
--- a/hutool-core/src/main/java/cn/hutool/core/util/ArrayUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/util/ArrayUtil.java
@@ -1613,7 +1613,7 @@ public class ArrayUtil {
public static int indexOf(double[] array, double value) {
if (null != array) {
for (int i = 0; i < array.length; i++) {
- if (value == array[i]) {
+ if (NumberUtil.equals(value, array[i])) {
return i;
}
}
@@ -1632,7 +1632,7 @@ public class ArrayUtil {
public static int lastIndexOf(double[] array, double value) {
if (null != array) {
for (int i = array.length - 1; i >= 0; i--) {
- if (value == array[i]) {
+ if (NumberUtil.equals(value, array[i])) {
return i;
}
}
@@ -1663,7 +1663,7 @@ public class ArrayUtil {
public static int indexOf(float[] array, float value) {
if (null != array) {
for (int i = 0; i < array.length; i++) {
- if (value == array[i]) {
+ if (NumberUtil.equals(value, array[i])) {
return i;
}
}
@@ -1682,7 +1682,7 @@ public class ArrayUtil {
public static int lastIndexOf(float[] array, float value) {
if (null != array) {
for (int i = array.length - 1; i >= 0; i--) {
- if (value == array[i]) {
+ if (NumberUtil.equals(value, array[i])) {
return i;
}
}
@@ -1777,7 +1777,7 @@ public class ArrayUtil {
}
/**
- * 包装类数组转为原始类型数组
+ * 包装类数组转为原始类型数组,null转为0
*
* @param values 包装类型数组
* @return 原始类型数组
@@ -1793,7 +1793,7 @@ public class ArrayUtil {
final int[] array = new int[length];
for (int i = 0; i < length; i++) {
- array[i] = values[i];
+ array[i] = ObjectUtil.defaultIfNull(values[i], 0);
}
return array;
}
@@ -1837,7 +1837,7 @@ public class ArrayUtil {
final long[] array = new long[length];
for (int i = 0; i < length; i++) {
- array[i] = values[i];
+ array[i] = ObjectUtil.defaultIfNull(values[i], 0L);
}
return array;
}
@@ -1881,7 +1881,7 @@ public class ArrayUtil {
char[] array = new char[length];
for (int i = 0; i < length; i++) {
- array[i] = values[i];
+ array[i] = ObjectUtil.defaultIfNull(values[i], Character.MIN_VALUE);
}
return array;
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/CreditCodeUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/CreditCodeUtil.java
index 557ccb3d4..0eb925da2 100644
--- a/hutool-core/src/main/java/cn/hutool/core/util/CreditCodeUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/util/CreditCodeUtil.java
@@ -98,11 +98,11 @@ public class CreditCodeUtil {
}
for (int i = 2; i < 8; i++) {
int num = RandomUtil.randomInt(10);
- buf.append(Character.toUpperCase(BASE_CODE_ARRAY[num]));
+ buf.append(BASE_CODE_ARRAY[num]);
}
for (int i = 8; i < 17; i++) {
int num = RandomUtil.randomInt(BASE_CODE_ARRAY.length - 1);
- buf.append(Character.toUpperCase(BASE_CODE_ARRAY[num]));
+ buf.append(BASE_CODE_ARRAY[num]);
}
final String code = buf.toString();
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java
index bb5e7af11..8465c0f29 100644
--- a/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/util/NumberUtil.java
@@ -1712,7 +1712,7 @@ public class NumberUtil {
/**
* 比较大小,值相等 返回true
- * 此方法通过调用{@link BigDecimal#compareTo(BigDecimal)}方法来判断是否相等
+ * 此方法通过调用{@link Double#doubleToLongBits(double)}方法来判断是否相等
* 此方法判断值相等时忽略精度的,即0.00 == 0
*
* @param num1 数字1
@@ -1721,7 +1721,21 @@ public class NumberUtil {
* @since 5.4.2
*/
public static boolean equals(double num1, double num2) {
- return equals(toBigDecimal(num1), toBigDecimal(num2));
+ return Double.doubleToLongBits(num1) == Double.doubleToLongBits(num2);
+ }
+
+ /**
+ * 比较大小,值相等 返回true
+ * 此方法通过调用{@link Double#doubleToLongBits(double)}方法来判断是否相等
+ * 此方法判断值相等时忽略精度的,即0.00 == 0
+ *
+ * @param num1 数字1
+ * @param num2 数字2
+ * @return 是否相等
+ * @since 5.4.5
+ */
+ public static boolean equals(float num1, float num2) {
+ return Float.floatToIntBits(num1) == Float.floatToIntBits(num2);
}
/**
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/RandomUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/RandomUtil.java
index 54b2bba5c..984a76867 100644
--- a/hutool-core/src/main/java/cn/hutool/core/util/RandomUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/util/RandomUtil.java
@@ -48,8 +48,8 @@ public class RandomUtil {
* ThreadLocalRandom是JDK 7之后提供并发产生随机数,能够解决多个线程发生的竞争争夺。
*
*
- * 注意:此方法返回的{@link ThreadLocalRandom}不可以在多线程环境下共享对象,否则有重复随机数问题。
- * 见:https://www.jianshu.com/p/89dfe990295c
+ * 注意:此方法返回的{@link ThreadLocalRandom}不可以在多线程环境下共享对象,否则有重复随机数问题。
+ * 见:https://www.jianshu.com/p/89dfe990295c
*
*
* @return {@link ThreadLocalRandom}
@@ -522,9 +522,10 @@ public class RandomUtil {
*
* @return 随机颜色
* @since 4.1.5
- * @deprecated 使用{@link ImagUtil#randomColor()}
+ * @deprecated 使用ImgUtil.randomColor()
*/
- public static Color randomColor() {
+ @Deprecated
+ public static Color randomColor() {
final Random random = getRandom();
return new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java
index c4f1e686e..51bac588c 100644
--- a/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/util/StrUtil.java
@@ -34,53 +34,95 @@ public class StrUtil {
public static final int INDEX_NOT_FOUND = -1;
- /** 字符常量:空格符 ' ' */
+ /**
+ * 字符常量:空格符 ' '
+ */
public static final char C_SPACE = CharUtil.SPACE;
- /** 字符常量:制表符 \t */
+ /**
+ * 字符常量:制表符 \t
+ */
public static final char C_TAB = CharUtil.TAB;
- /** 字符常量:点 . */
+ /**
+ * 字符常量:点 .
+ */
public static final char C_DOT = CharUtil.DOT;
- /** 字符常量:斜杠 / */
+ /**
+ * 字符常量:斜杠 /
+ */
public static final char C_SLASH = CharUtil.SLASH;
- /** 字符常量:反斜杠 \ */
+ /**
+ * 字符常量:反斜杠 \
+ */
public static final char C_BACKSLASH = CharUtil.BACKSLASH;
- /** 字符常量:回车符 \r */
+ /**
+ * 字符常量:回车符 \r
+ */
public static final char C_CR = CharUtil.CR;
- /** 字符常量:换行符 \n */
+ /**
+ * 字符常量:换行符 \n
+ */
public static final char C_LF = CharUtil.LF;
- /** 字符常量:下划线 _ */
+ /**
+ * 字符常量:下划线 _
+ */
public static final char C_UNDERLINE = CharUtil.UNDERLINE;
- /** 字符常量:逗号 , */
+ /**
+ * 字符常量:逗号 ,
+ */
public static final char C_COMMA = CharUtil.COMMA;
- /** 字符常量:花括号(左) { */
+ /**
+ * 字符常量:花括号(左) {
+ */
public static final char C_DELIM_START = CharUtil.DELIM_START;
- /** 字符常量:花括号(右) } */
+ /**
+ * 字符常量:花括号(右) }
+ */
public static final char C_DELIM_END = CharUtil.DELIM_END;
- /** 字符常量:中括号(左) [ */
+ /**
+ * 字符常量:中括号(左) [
+ */
public static final char C_BRACKET_START = CharUtil.BRACKET_START;
- /** 字符常量:中括号(右) ] */
+ /**
+ * 字符常量:中括号(右) ]
+ */
public static final char C_BRACKET_END = CharUtil.BRACKET_END;
- /** 字符常量:冒号 : */
+ /**
+ * 字符常量:冒号 :
+ */
public static final char C_COLON = CharUtil.COLON;
- /** 字符常量:艾特 @ */
+ /**
+ * 字符常量:艾特 @
+ */
public static final char C_AT = CharUtil.AT;
- /** 字符串常量:空格符 ' ' */
+ /**
+ * 字符串常量:空格符 ' '
+ */
public static final String SPACE = " ";
- /** 字符串常量:制表符 \t */
+ /**
+ * 字符串常量:制表符 \t
+ */
public static final String TAB = " ";
- /** 字符串常量:点 . */
+ /**
+ * 字符串常量:点 .
+ */
public static final String DOT = ".";
/**
* 字符串常量:双点 ..
* 用途:作为指向上级文件夹的路径 "../path"
*/
public static final String DOUBLE_DOT = "..";
- /** 字符串常量:斜杠 / */
+ /**
+ * 字符串常量:斜杠 /
+ */
public static final String SLASH = "/";
- /** 字符串常量:反斜杠 \ */
+ /**
+ * 字符串常量:反斜杠 \
+ */
public static final String BACKSLASH = "\\";
- /** 字符串常量:空字符串 "" */
+ /**
+ * 字符串常量:空字符串 ""
+ */
public static final String EMPTY = "";
/**
* 字符串常量:"null"
@@ -92,45 +134,79 @@ public class StrUtil {
* 解释:该字符常用于表示 Linux 系统和 MacOS 系统下的文本换行
*/
public static final String CR = "\r";
- /** 字符串常量:换行符 \n */
+ /**
+ * 字符串常量:换行符 \n
+ */
public static final String LF = "\n";
/**
* 字符串常量:Windows 换行 \r\n
* 解释:该字符串常用于表示 Windows 系统下的文本换行
*/
public static final String CRLF = "\r\n";
- /** 字符串常量:下划线 _ */
+ /**
+ * 字符串常量:下划线 _
+ */
public static final String UNDERLINE = "_";
- /** 字符串常量:减号(中划线) - */
+ /**
+ * 字符串常量:减号(中划线) -
+ */
public static final String DASHED = "-";
- /** 字符串常量:逗号 , */
+ /**
+ * 字符串常量:逗号 ,
+ */
public static final String COMMA = ",";
- /** 字符串常量:花括号(左) { */
+ /**
+ * 字符串常量:花括号(左) {
+ */
public static final String DELIM_START = "{";
- /** 字符串常量:花括号(右) } */
+ /**
+ * 字符串常量:花括号(右) }
+ */
public static final String DELIM_END = "}";
- /** 字符串常量:中括号(左) [ */
+ /**
+ * 字符串常量:中括号(左) [
+ */
public static final String BRACKET_START = "[";
- /** 字符串常量:中括号(右) ] */
+ /**
+ * 字符串常量:中括号(右) ]
+ */
public static final String BRACKET_END = "]";
- /** 字符串常量:冒号 : */
+ /**
+ * 字符串常量:冒号 :
+ */
public static final String COLON = ":";
- /** 字符串常量:艾特 @ */
+ /**
+ * 字符串常量:艾特 @
+ */
public static final String AT = "@";
- /** 字符串常量:HTML 空格转义 */
+ /**
+ * 字符串常量:HTML 空格转义
+ */
public static final String HTML_NBSP = " ";
- /** 字符串常量:HTML And 符转义 & */
+ /**
+ * 字符串常量:HTML And 符转义 &
+ */
public static final String HTML_AMP = "&";
- /** 字符串常量:HTML 双引号转义 " */
+ /**
+ * 字符串常量:HTML 双引号转义 "
+ */
public static final String HTML_QUOTE = """;
- /** 字符串常量:HTML 单引号转义 ' */
+ /**
+ * 字符串常量:HTML 单引号转义 '
+ */
public static final String HTML_APOS = "'";
- /** 字符串常量:HTML 小于号转义 < */
+ /**
+ * 字符串常量:HTML 小于号转义 <
+ */
public static final String HTML_LT = "<";
- /** 字符串常量:HTML 大于号转义 > */
+ /**
+ * 字符串常量:HTML 大于号转义 >
+ */
public static final String HTML_GT = ">";
- /** 字符串常量:空 JSON "{}" */
+ /**
+ * 字符串常量:空 JSON "{}"
+ */
public static final String EMPTY_JSON = "{}";
// ------------------------------------------------------------------------ Blank
@@ -189,8 +265,7 @@ public class StrUtil {
*
* @param obj 对象
* @return 如果为字符串是否为空串
- *
- * @see StrUtil#isBlank(CharSequence)
+ * @see StrUtil#isBlank(CharSequence)
* @since 3.3.0
*/
public static boolean isBlankIfStr(Object obj) {
@@ -667,6 +742,9 @@ public class StrUtil {
* @return 是否开始
*/
public static boolean startWith(CharSequence str, char c) {
+ if (isEmpty(str)) {
+ return false;
+ }
return c == str.charAt(0);
}
@@ -674,8 +752,8 @@ public class StrUtil {
* 是否以指定字符串开头
* 如果给定的字符串和开头字符串都为null则返回true,否则任意一个值为null返回false
*
- * @param str 被监测字符串
- * @param prefix 开头字符串
+ * @param str 被监测字符串
+ * @param prefix 开头字符串
* @param ignoreCase 是否忽略大小写
* @return 是否以指定字符串开头
* @since 5.4.3
@@ -690,14 +768,14 @@ public class StrUtil {
*
* @param str 被监测字符串
* @param prefix 开头字符串
- * @param ignoreCase 是否忽略大小写
+ * @param ignoreCase 是否忽略大小写
* @param ignoreEquals 是否忽略字符串相等的情况
* @return 是否以指定字符串开头
* @since 5.4.3
*/
public static boolean startWith(CharSequence str, CharSequence prefix, boolean ignoreCase, boolean ignoreEquals) {
if (null == str || null == prefix) {
- if(false == ignoreEquals){
+ if (false == ignoreEquals) {
return false;
}
return null == str && null == prefix;
@@ -710,7 +788,7 @@ public class StrUtil {
isStartWith = str.toString().startsWith(prefix.toString());
}
- if(isStartWith){
+ if (isStartWith) {
return (false == ignoreEquals) || (false == equals(str, prefix, ignoreCase));
}
return false;
@@ -779,6 +857,9 @@ public class StrUtil {
* @return 是否结尾
*/
public static boolean endWith(CharSequence str, char c) {
+ if (isEmpty(str)) {
+ return false;
+ }
return c == str.charAt(str.length() - 1);
}
@@ -1073,7 +1154,8 @@ public class StrUtil {
* @return 移除后的字符串
*/
public static String removeAll(CharSequence str, CharSequence strToRemove) {
- if (isEmpty(str)) {
+ // strToRemove如果为空, 也不用继续后面的逻辑
+ if (isEmpty(str) || isEmpty(strToRemove)) {
return str(str);
}
return str.toString().replace(strToRemove, EMPTY);
@@ -2125,7 +2207,6 @@ public class StrUtil {
}
final List result = new LinkedList<>();
- final String[] split = split(str, prefix);
for (String fragment : split(str, prefix)) {
int suffixIndex = fragment.indexOf(suffix.toString());
if (suffixIndex > 0) {
@@ -2205,10 +2286,10 @@ public class StrUtil {
if (null == str) {
return null;
}
- if (count <= 0) {
+ if (count <= 0 || str.length() == 0) {
return EMPTY;
}
- if (count == 1 || str.length() == 0) {
+ if (count == 1) {
return str.toString();
}
@@ -3997,11 +4078,12 @@ public class StrUtil {
return false;
}
int len = value.length();
- boolean isAllMatch = true;
for (int i = 0; i < len; i++) {
- isAllMatch &= matcher.match(value.charAt(i));
+ if (false == matcher.match(value.charAt(i))) {
+ return false;
+ }
}
- return isAllMatch;
+ return true;
}
/**
diff --git a/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java
index 4b9d80a93..e7162eb4f 100644
--- a/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java
@@ -4,6 +4,7 @@ import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.exceptions.UtilException;
import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.BiMap;
@@ -13,7 +14,11 @@ import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.DefaultHandler;
import javax.xml.XMLConstants;
import javax.xml.namespace.NamespaceContext;
@@ -21,6 +26,8 @@ import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
@@ -62,6 +69,10 @@ public class XmlUtil {
* 在XML中无效的字符 正则
*/
public static final String INVALID_REGEX = "[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]";
+ /**
+ * 在XML中注释的内容 正则
+ */
+ public static final String COMMENT_REGEX = "(?s)";
/**
* XML格式化输出默认缩进量
*/
@@ -76,6 +87,10 @@ public class XmlUtil {
* 是否打开命名空间支持
*/
private static boolean namespaceAware = true;
+ /**
+ * Sax读取器工厂缓存
+ */
+ private static SAXParserFactory factory;
/**
* 禁用默认的DocumentBuilderFactory,禁用后如果有第三方的实现(如oracle的xdb包中的xmlparse),将会自动加载实现。
@@ -184,6 +199,92 @@ public class XmlUtil {
}
}
+ /**
+ * 使用Sax方式读取指定的XML
+ * 如果用户传入的contentHandler为{@link DefaultHandler},则其接口都会被处理
+ *
+ * @param file XML源文件,使用后自动关闭
+ * @param contentHandler XML流处理器,用于按照Element处理xml
+ * @since 5.4.4
+ */
+ public static void readBySax(File file, ContentHandler contentHandler) {
+ InputStream in = null;
+ try{
+ in = FileUtil.getInputStream(file);
+ readBySax(new InputSource(in), contentHandler);
+ } finally {
+ IoUtil.close(in);
+ }
+ }
+
+ /**
+ * 使用Sax方式读取指定的XML
+ * 如果用户传入的contentHandler为{@link DefaultHandler},则其接口都会被处理
+ *
+ * @param reader XML源Reader,使用后自动关闭
+ * @param contentHandler XML流处理器,用于按照Element处理xml
+ * @since 5.4.4
+ */
+ public static void readBySax(Reader reader, ContentHandler contentHandler) {
+ try{
+ readBySax(new InputSource(reader), contentHandler);
+ } finally {
+ IoUtil.close(reader);
+ }
+ }
+
+ /**
+ * 使用Sax方式读取指定的XML
+ * 如果用户传入的contentHandler为{@link DefaultHandler},则其接口都会被处理
+ *
+ * @param source XML源流,使用后自动关闭
+ * @param contentHandler XML流处理器,用于按照Element处理xml
+ * @since 5.4.4
+ */
+ public static void readBySax(InputStream source, ContentHandler contentHandler) {
+ try{
+ readBySax(new InputSource(source), contentHandler);
+ } finally {
+ IoUtil.close(source);
+ }
+ }
+
+ /**
+ * 使用Sax方式读取指定的XML
+ * 如果用户传入的contentHandler为{@link DefaultHandler},则其接口都会被处理
+ *
+ * @param source XML源,可以是文件、流、路径等
+ * @param contentHandler XML流处理器,用于按照Element处理xml
+ * @since 5.4.4
+ */
+ public static void readBySax(InputSource source, ContentHandler contentHandler) {
+ // 1.获取解析工厂
+ if (null == factory) {
+ factory = SAXParserFactory.newInstance();
+ factory.setValidating(false);
+ factory.setNamespaceAware(namespaceAware);
+ }
+ // 2.从解析工厂获取解析器
+ final SAXParser parse;
+ XMLReader reader;
+ try {
+ parse = factory.newSAXParser();
+ if (contentHandler instanceof DefaultHandler) {
+ parse.parse(source, (DefaultHandler) contentHandler);
+ return;
+ }
+
+ // 3.得到解读器
+ reader = parse.getXMLReader();
+ reader.setContentHandler(contentHandler);
+ reader.parse(source);
+ } catch (ParserConfigurationException | SAXException e) {
+ throw new UtilException(e);
+ } catch (IOException e) {
+ throw new IORuntimeException(e);
+ }
+ }
+
/**
* 将String类型的XML转换为XML文档
*
@@ -574,6 +675,20 @@ public class XmlUtil {
return xmlContent.replaceAll(INVALID_REGEX, "");
}
+ /**
+ * 去除XML文本中的注释内容
+ *
+ * @param xmlContent XML文本
+ * @return 当传入为null时返回null
+ * @since 5.4.5
+ */
+ public static String cleanComment(String xmlContent) {
+ if (xmlContent == null) {
+ return null;
+ }
+ return xmlContent.replaceAll(COMMENT_REGEX, StrUtil.EMPTY);
+ }
+
/**
* 根据节点名获得子节点列表
*
diff --git a/hutool-core/src/test/java/cn/hutool/core/date/ChineseDateTest.java b/hutool-core/src/test/java/cn/hutool/core/date/ChineseDateTest.java
index 53bd1dca6..877064d84 100644
--- a/hutool-core/src/test/java/cn/hutool/core/date/ChineseDateTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/date/ChineseDateTest.java
@@ -1,5 +1,6 @@
package cn.hutool.core.date;
+import cn.hutool.core.util.StrUtil;
import org.junit.Assert;
import org.junit.Test;
@@ -77,4 +78,11 @@ public class ChineseDateTest {
chineseDate = new ChineseDate(2020,4,15);
Assert.assertEquals("闰四月", chineseDate.getChineseMonth());
}
+
+ @Test
+ public void getFestivalsTest(){
+ // issue#I1XHSF@Gitee,2023-01-20对应农历腊月29,非除夕
+ ChineseDate chineseDate = new ChineseDate(DateUtil.parseDate("2023-01-20"));
+ Assert.assertTrue(StrUtil.isEmpty(chineseDate.getFestivals()));
+ }
}
diff --git a/hutool-core/src/test/java/cn/hutool/core/img/ImgUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/img/ImgUtilTest.java
index 9243a34a1..87aebdb5a 100644
--- a/hutool-core/src/test/java/cn/hutool/core/img/ImgUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/img/ImgUtilTest.java
@@ -25,7 +25,9 @@ public class ImgUtilTest {
@Test
@Ignore
public void scaleTest2() {
- ImgUtil.scale(FileUtil.file("e:/pic/test.jpg"), FileUtil.file("e:/pic/test_result.jpg"), 0.8f);
+ ImgUtil.scale(
+ FileUtil.file("d:/test/2.png"),
+ FileUtil.file("d:/test/2_result.jpg"), 600, 337, null);
}
@Test
diff --git a/hutool-core/src/test/java/cn/hutool/core/lang/ConsoleTableTest.java b/hutool-core/src/test/java/cn/hutool/core/lang/ConsoleTableTest.java
new file mode 100644
index 000000000..b92ddfd72
--- /dev/null
+++ b/hutool-core/src/test/java/cn/hutool/core/lang/ConsoleTableTest.java
@@ -0,0 +1,35 @@
+package cn.hutool.core.lang;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class ConsoleTableTest {
+
+ @Test
+ @Ignore
+ public void printTest() {
+ ConsoleTable t = new ConsoleTable();
+ t.addHeader("姓名", "年龄");
+ t.addBody("张三", "15");
+ t.addBody("李四", "29");
+ t.addBody("王二麻子", "37");
+ t.print();
+
+ Console.log();
+
+ t = new ConsoleTable();
+ t.addHeader("体温", "占比");
+ t.addHeader("℃", "%");
+ t.addBody("36.8", "10");
+ t.addBody("37", "5");
+ t.print();
+
+ Console.log();
+
+ t = new ConsoleTable();
+ t.addHeader("标题1", "标题2");
+ t.addBody("12345", "混合321654asdfcSDF");
+ t.addBody("sd e3ee ff22", "ff值");
+ t.print();
+ }
+}
diff --git a/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java
index dd1710807..d0de97034 100644
--- a/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/util/NumberUtilTest.java
@@ -263,10 +263,10 @@ public class NumberUtilTest {
@Test
public void isPowerOfTwoTest() {
- Assert.assertEquals(false, NumberUtil.isPowerOfTwo(-1));
- Assert.assertEquals(true, NumberUtil.isPowerOfTwo(16));
- Assert.assertEquals(true, NumberUtil.isPowerOfTwo(65536));
- Assert.assertEquals(true, NumberUtil.isPowerOfTwo(1));
- Assert.assertEquals(false, NumberUtil.isPowerOfTwo(17));
+ Assert.assertFalse(NumberUtil.isPowerOfTwo(-1));
+ Assert.assertTrue(NumberUtil.isPowerOfTwo(16));
+ Assert.assertTrue(NumberUtil.isPowerOfTwo(65536));
+ Assert.assertTrue(NumberUtil.isPowerOfTwo(1));
+ Assert.assertFalse(NumberUtil.isPowerOfTwo(17));
}
}
diff --git a/hutool-core/src/test/java/cn/hutool/core/util/XmlUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/util/XmlUtilTest.java
index 231de5133..658d2440a 100644
--- a/hutool-core/src/test/java/cn/hutool/core/util/XmlUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/util/XmlUtilTest.java
@@ -9,10 +9,13 @@ import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.w3c.dom.Document;
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.DefaultHandler;
import javax.xml.xpath.XPathConstants;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.Set;
/**
* {@link XmlUtil} 工具类
@@ -148,6 +151,18 @@ public class XmlUtilTest {
Assert.assertNotNull(doc);
}
+ @Test
+ public void readBySaxTest(){
+ final Set eles = CollUtil.newHashSet(
+ "returnsms", "returnstatus", "message", "remainpoint", "taskID", "successCounts");
+ XmlUtil.readBySax(ResourceUtil.getStream("test.xml"), new DefaultHandler(){
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) {
+ Assert.assertTrue(eles.contains(localName));
+ }
+ });
+ }
+
@Test
public void mapToXmlTestWithOmitXmlDeclaration() {
@@ -196,6 +211,13 @@ public class XmlUtilTest {
Assert.assertEquals(testBean.getBankCode(), testBean2.getBankCode());
}
+ @Test
+ public void cleanCommentTest() {
+ final String xmlContent = "hutooljava";
+ final String ret = XmlUtil.cleanComment(xmlContent);
+ Assert.assertEquals("hutooljava", ret);
+ }
+
@Data
public static class TestBean {
private String ReqCode;
diff --git a/hutool-cron/pom.xml b/hutool-cron/pom.xml
index e1fb492f9..f4f0368c7 100644
--- a/hutool-cron/pom.xml
+++ b/hutool-cron/pom.xml
@@ -7,7 +7,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool-cron
diff --git a/hutool-crypto/pom.xml b/hutool-crypto/pom.xml
index e84f71c45..25acea0a2 100644
--- a/hutool-crypto/pom.xml
+++ b/hutool-crypto/pom.xml
@@ -9,7 +9,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool-crypto
diff --git a/hutool-db/pom.xml b/hutool-db/pom.xml
index 991444907..99518169b 100644
--- a/hutool-db/pom.xml
+++ b/hutool-db/pom.xml
@@ -9,7 +9,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool-db
@@ -19,9 +19,9 @@
0.9.5.5
- 2.7.0
+ 2.8.0
9.0.30
- 1.1.23
+ 1.1.24
2.4.13
3.12.7
3.32.3.2
diff --git a/hutool-dfa/pom.xml b/hutool-dfa/pom.xml
index 07dc1656d..1d2a09ab2 100644
--- a/hutool-dfa/pom.xml
+++ b/hutool-dfa/pom.xml
@@ -7,7 +7,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool-dfa
diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml
index 454c0df47..f91f5ac87 100644
--- a/hutool-extra/pom.xml
+++ b/hutool-extra/pom.xml
@@ -9,7 +9,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool-extra
@@ -19,15 +19,15 @@
2.2
- 3.2.0.RELEASE
+ 3.2.1.RELEASE
1.3.0
2.3.30
4.9.01
3.0.11.RELEASE
1.6.2
0.1.55
- 3.4.0
- 3.6
+ 3.4.1
+ 3.7
5.1.1
4.0.1
2.3.4.RELEASE
diff --git a/hutool-http/pom.xml b/hutool-http/pom.xml
index f5ca543b9..a7b33873e 100644
--- a/hutool-http/pom.xml
+++ b/hutool-http/pom.xml
@@ -9,7 +9,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool-http
diff --git a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java
index 875805e21..b0cae62d8 100644
--- a/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java
+++ b/hutool-http/src/main/java/cn/hutool/http/HttpRequest.java
@@ -28,6 +28,7 @@ import java.io.OutputStream;
import java.net.CookieManager;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
+import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URLStreamHandler;
import java.util.Collection;
@@ -841,6 +842,20 @@ public class HttpRequest extends HttpBase {
return this;
}
+ /**
+ * 设置Http代理
+ *
+ * @param host 代理 主机
+ * @param port 代理 端口
+ * @return this
+ * @since 5.4.5
+ */
+ public HttpRequest setHttpProxy(String host, int port) {
+ final Proxy proxy = new Proxy(Proxy.Type.HTTP,
+ new InetSocketAddress(host, port));
+ return setProxy(proxy);
+ }
+
/**
* 设置代理
*
diff --git a/hutool-json/pom.xml b/hutool-json/pom.xml
index 617a9ca00..b84f23bec 100644
--- a/hutool-json/pom.xml
+++ b/hutool-json/pom.xml
@@ -9,7 +9,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool-json
diff --git a/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java b/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java
index c6ccf2e85..1b1e2c28f 100644
--- a/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java
+++ b/hutool-json/src/test/java/cn/hutool/json/JSONUtilTest.java
@@ -154,4 +154,11 @@ public class JSONUtilTest {
Assert.assertEquals("aa", json.get("name"));
Assert.assertEquals(1, json.get("gender"));
}
+
+ @Test
+ public void doubleTest(){
+ String json = "{\"test\": 12.00}";
+ final JSONObject jsonObject = JSONUtil.parseObj(json);
+ Assert.assertEquals("12.00", jsonObject.getBigDecimal("test").setScale(2).toString());
+ }
}
diff --git a/hutool-log/pom.xml b/hutool-log/pom.xml
index 19429e26e..3d15e4203 100644
--- a/hutool-log/pom.xml
+++ b/hutool-log/pom.xml
@@ -9,7 +9,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool-log
diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml
index 6d74e4a4b..47dcd4ea4 100644
--- a/hutool-poi/pom.xml
+++ b/hutool-poi/pom.xml
@@ -8,7 +8,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool-poi
diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelFileUtil.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelFileUtil.java
index 2c04fc90e..73e686160 100644
--- a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelFileUtil.java
+++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelFileUtil.java
@@ -1,9 +1,10 @@
package cn.hutool.poi.excel;
import cn.hutool.core.io.IORuntimeException;
+import cn.hutool.core.io.IoUtil;
import org.apache.poi.poifs.filesystem.FileMagic;
-import java.io.BufferedInputStream;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -48,11 +49,24 @@ public class ExcelFileUtil {
* @return 是否为XLSX格式的Excel文件(XSSF)
*/
public static boolean isXlsx(InputStream in) {
- if (false == in.markSupported()) {
- in = new BufferedInputStream(in);
- }
try {
- return FileMagic.valueOf(in) == FileMagic.OOXML;
+ return FileMagic.valueOf(IoUtil.toMarkSupportStream(in)) == FileMagic.OOXML;
+ } catch (IOException e) {
+ throw new IORuntimeException(e);
+ }
+ }
+
+ /**
+ * 是否为XLSX格式的Excel文件(XSSF)
+ * XLSX文件主要用于Excel 2007+创建
+ *
+ * @param file excel文件
+ * @return 是否为XLSX格式的Excel文件(XSSF)
+ * @since 5.4.4
+ */
+ public static boolean isXlsx(File file) {
+ try {
+ return FileMagic.valueOf(file) == FileMagic.OOXML;
} catch (IOException e) {
throw new IORuntimeException(e);
}
diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelUtil.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelUtil.java
index 1fd7a470b..884746b1c 100644
--- a/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelUtil.java
+++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/ExcelUtil.java
@@ -2,7 +2,6 @@ package cn.hutool.poi.excel;
import cn.hutool.core.exceptions.DependencyException;
import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
@@ -10,9 +9,10 @@ import cn.hutool.poi.PoiChecker;
import cn.hutool.poi.excel.cell.CellLocation;
import cn.hutool.poi.excel.sax.Excel03SaxReader;
import cn.hutool.poi.excel.sax.Excel07SaxReader;
+import cn.hutool.poi.excel.sax.ExcelSaxReader;
+import cn.hutool.poi.excel.sax.ExcelSaxUtil;
import cn.hutool.poi.excel.sax.handler.RowHandler;
-import java.io.BufferedInputStream;
import java.io.File;
import java.io.InputStream;
@@ -29,67 +29,92 @@ public class ExcelUtil {
* 通过Sax方式读取Excel,同时支持03和07格式
*
* @param path Excel文件路径
- * @param sheetIndex sheet序号
+ * @param rid sheet rid,-1表示全部Sheet, 0表示第一个Sheet
* @param rowHandler 行处理器
* @since 3.2.0
*/
- public static void readBySax(String path, int sheetIndex, RowHandler rowHandler) {
- BufferedInputStream in = null;
- try {
- in = FileUtil.getInputStream(path);
- readBySax(in, sheetIndex, rowHandler);
- } finally {
- IoUtil.close(in);
- }
+ public static void readBySax(String path, int rid, RowHandler rowHandler) {
+ readBySax(FileUtil.file(path), rid, rowHandler);
+ }
+
+ /**
+ * 通过Sax方式读取Excel,同时支持03和07格式
+ *
+ * @param path Excel文件路径
+ * @param idOrRid Excel中的sheet id或者rid编号,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
+ * @param rowHandler 行处理器
+ * @since 5.4.4
+ */
+ public static void readBySax(String path, String idOrRid, RowHandler rowHandler) {
+ readBySax(FileUtil.file(path), idOrRid, rowHandler);
}
/**
* 通过Sax方式读取Excel,同时支持03和07格式
*
* @param file Excel文件
- * @param sheetIndex sheet序号
+ * @param rid sheet rid,-1表示全部Sheet, 0表示第一个Sheet
* @param rowHandler 行处理器
* @since 3.2.0
*/
- public static void readBySax(File file, int sheetIndex, RowHandler rowHandler) {
- BufferedInputStream in = null;
- try {
- in = FileUtil.getInputStream(file);
- readBySax(in, sheetIndex, rowHandler);
- } finally {
- IoUtil.close(in);
- }
+ public static void readBySax(File file, int rid, RowHandler rowHandler) {
+ final ExcelSaxReader> reader = ExcelSaxUtil.createSaxReader(ExcelFileUtil.isXlsx(file), rowHandler);
+ reader.read(file, rid);
+ }
+
+ /**
+ * 通过Sax方式读取Excel,同时支持03和07格式
+ *
+ * @param file Excel文件
+ * @param idOrRid Excel中的sheet id或者rid编号,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
+ * @param rowHandler 行处理器
+ * @since 5.4.4
+ */
+ public static void readBySax(File file, String idOrRid, RowHandler rowHandler) {
+ final ExcelSaxReader> reader = ExcelSaxUtil.createSaxReader(ExcelFileUtil.isXlsx(file), rowHandler);
+ reader.read(file, idOrRid);
}
/**
* 通过Sax方式读取Excel,同时支持03和07格式
*
* @param in Excel流
- * @param sheetIndex sheet序号
+ * @param rid sheet rid,-1表示全部Sheet, 0表示第一个Sheet
* @param rowHandler 行处理器
* @since 3.2.0
*/
- public static void readBySax(InputStream in, int sheetIndex, RowHandler rowHandler) {
- in = IoUtil.toMarkSupportStream(in);
- if (ExcelFileUtil.isXlsx(in)) {
- read07BySax(in, sheetIndex, rowHandler);
- } else {
- read03BySax(in, sheetIndex, rowHandler);
- }
+ public static void readBySax(InputStream in, int rid, RowHandler rowHandler) {
+ final ExcelSaxReader> reader = ExcelSaxUtil.createSaxReader(ExcelFileUtil.isXlsx(in), rowHandler);
+ reader.read(in, rid);
+ }
+
+ /**
+ * 通过Sax方式读取Excel,同时支持03和07格式
+ *
+ * @param in Excel流
+ * @param idOrRid Excel中的sheet id或者rid编号,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
+ * @param rowHandler 行处理器
+ * @since 5.4.4
+ */
+ public static void readBySax(InputStream in, String idOrRid, RowHandler rowHandler) {
+ final ExcelSaxReader> reader = ExcelSaxUtil.createSaxReader(ExcelFileUtil.isXlsx(in), rowHandler);
+ reader.read(in, idOrRid);
}
/**
* Sax方式读取Excel07
*
* @param in 输入流
- * @param sheetIndex Sheet索引,-1表示全部Sheet, 0表示第一个Sheet
+ * @param rid Sheet rid,-1表示全部Sheet, 0表示第一个Sheet
* @param rowHandler 行处理器
* @return {@link Excel07SaxReader}
* @since 3.2.0
+ * @deprecated 请使用 {@link #readBySax(InputStream, int, RowHandler)}
*/
- public static Excel07SaxReader read07BySax(InputStream in, int sheetIndex, RowHandler rowHandler) {
+ @Deprecated
+ public static Excel07SaxReader read07BySax(InputStream in, int rid, RowHandler rowHandler) {
try {
- return new Excel07SaxReader(rowHandler).read(in, sheetIndex);
+ return new Excel07SaxReader(rowHandler).read(in, rid);
} catch (NoClassDefFoundError e) {
throw new DependencyException(ObjectUtil.defaultIfNull(e.getCause(), e), PoiChecker.NO_POI_ERROR_MSG);
}
@@ -99,14 +124,16 @@ public class ExcelUtil {
* Sax方式读取Excel07
*
* @param file 文件
- * @param sheetIndex Sheet索引,-1表示全部Sheet, 0表示第一个Sheet
+ * @param rid Sheet rid,-1表示全部Sheet, 0表示第一个Sheet
* @param rowHandler 行处理器
* @return {@link Excel07SaxReader}
* @since 3.2.0
+ * @deprecated 请使用 {@link #readBySax(File, int, RowHandler)}
*/
- public static Excel07SaxReader read07BySax(File file, int sheetIndex, RowHandler rowHandler) {
+ @Deprecated
+ public static Excel07SaxReader read07BySax(File file, int rid, RowHandler rowHandler) {
try {
- return new Excel07SaxReader(rowHandler).read(file, sheetIndex);
+ return new Excel07SaxReader(rowHandler).read(file, rid);
} catch (NoClassDefFoundError e) {
throw new DependencyException(ObjectUtil.defaultIfNull(e.getCause(), e), PoiChecker.NO_POI_ERROR_MSG);
}
@@ -116,14 +143,16 @@ public class ExcelUtil {
* Sax方式读取Excel07
*
* @param path 路径
- * @param sheetIndex Sheet索引,-1表示全部Sheet, 0表示第一个Sheet
+ * @param rid Sheet rid,-1表示全部Sheet, 0表示第一个Sheet
* @param rowHandler 行处理器
* @return {@link Excel07SaxReader}
* @since 3.2.0
+ * @deprecated 请使用 {@link #readBySax(String, int, RowHandler)}
*/
- public static Excel07SaxReader read07BySax(String path, int sheetIndex, RowHandler rowHandler) {
+ @Deprecated
+ public static Excel07SaxReader read07BySax(String path, int rid, RowHandler rowHandler) {
try {
- return new Excel07SaxReader(rowHandler).read(path, sheetIndex);
+ return new Excel07SaxReader(rowHandler).read(path, rid);
} catch (NoClassDefFoundError e) {
throw new DependencyException(ObjectUtil.defaultIfNull(e.getCause(), e), PoiChecker.NO_POI_ERROR_MSG);
}
@@ -135,9 +164,11 @@ public class ExcelUtil {
* @param in 输入流
* @param sheetIndex Sheet索引,-1表示全部Sheet, 0表示第一个Sheet
* @param rowHandler 行处理器
- * @return {@link Excel07SaxReader}
+ * @return {@link Excel03SaxReader}
* @since 3.2.0
+ * @deprecated 请使用 {@link #readBySax(InputStream, int, RowHandler)}
*/
+ @Deprecated
public static Excel03SaxReader read03BySax(InputStream in, int sheetIndex, RowHandler rowHandler) {
try {
return new Excel03SaxReader(rowHandler).read(in, sheetIndex);
@@ -154,7 +185,9 @@ public class ExcelUtil {
* @param rowHandler 行处理器
* @return {@link Excel03SaxReader}
* @since 3.2.0
+ * @deprecated 请使用 {@link #readBySax(File, int, RowHandler)}
*/
+ @Deprecated
public static Excel03SaxReader read03BySax(File file, int sheetIndex, RowHandler rowHandler) {
try {
return new Excel03SaxReader(rowHandler).read(file, sheetIndex);
@@ -171,7 +204,9 @@ public class ExcelUtil {
* @param rowHandler 行处理器
* @return {@link Excel03SaxReader}
* @since 3.2.0
+ * @deprecated 请使用 {@link #readBySax(String, int, RowHandler)}
*/
+ @Deprecated
public static Excel03SaxReader read03BySax(String path, int sheetIndex, RowHandler rowHandler) {
try {
return new Excel03SaxReader(rowHandler).read(path, sheetIndex);
diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/AbstractExcelSaxReader.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/AbstractExcelSaxReader.java
deleted file mode 100644
index ed3a245fe..000000000
--- a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/AbstractExcelSaxReader.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package cn.hutool.poi.excel.sax;
-
-import java.io.File;
-import java.io.InputStream;
-
-import cn.hutool.core.io.FileUtil;
-import cn.hutool.poi.exceptions.POIException;
-
-/**
- * 抽象的Sax方式Excel读取器,提供一些共用方法
- *
- * @author looly
- *
- * @param 子对象类型,用于标记返回值this
- * @since 3.2.0
- */
-public abstract class AbstractExcelSaxReader implements ExcelSaxReader {
-
- @Override
- public T read(String path) throws POIException {
- return read(FileUtil.file(path));
- }
-
- @Override
- public T read(File file) throws POIException {
- return read(file, -1);
- }
-
- @Override
- public T read(InputStream in) throws POIException {
- return read(in, -1);
- }
-
- @Override
- public T read(String path, int sheetIndex) throws POIException {
- return read(FileUtil.file(path), sheetIndex);
- }
-}
diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel03SaxReader.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel03SaxReader.java
index 56beeef4a..6aa1e7bfd 100644
--- a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel03SaxReader.java
+++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel03SaxReader.java
@@ -30,7 +30,7 @@ import java.util.List;
*
* @author looly
*/
-public class Excel03SaxReader extends AbstractExcelSaxReader implements HSSFListener {
+public class Excel03SaxReader implements HSSFListener, ExcelSaxReader {
/**
* 如果为公式,true表示输出公式计算后的结果值,false表示输出公式本身
@@ -83,18 +83,18 @@ public class Excel03SaxReader extends AbstractExcelSaxReader i
// ------------------------------------------------------------------------------ Read start
@Override
- public Excel03SaxReader read(File file, int rid) throws POIException {
+ public Excel03SaxReader read(File file, String idOrRid) throws POIException {
try {
- return read(new POIFSFileSystem(file), rid);
+ return read(new POIFSFileSystem(file), idOrRid);
} catch (IOException e) {
throw new POIException(e);
}
}
@Override
- public Excel03SaxReader read(InputStream excelStream, int rid) throws POIException {
+ public Excel03SaxReader read(InputStream excelStream, String idOrRid) throws POIException {
try {
- return read(new POIFSFileSystem(excelStream), rid);
+ return read(new POIFSFileSystem(excelStream), idOrRid);
} catch (IOException e) {
throw new POIException(e);
}
@@ -104,12 +104,12 @@ public class Excel03SaxReader extends AbstractExcelSaxReader i
* 读取
*
* @param fs {@link POIFSFileSystem}
- * @param rid sheet序号
+ * @param id sheet序号
* @return this
* @throws POIException IO异常包装
*/
- public Excel03SaxReader read(POIFSFileSystem fs, int rid) throws POIException {
- this.rid = rid;
+ public Excel03SaxReader read(POIFSFileSystem fs, String id) throws POIException {
+ this.rid = Integer.parseInt(id);
formatListener = new FormatTrackingHSSFListener(new MissingRecordAwareHSSFListener(this));
final HSSFRequest request = new HSSFRequest();
diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel07SaxReader.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel07SaxReader.java
index 0ff2aae60..d51ccc98c 100644
--- a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel07SaxReader.java
+++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel07SaxReader.java
@@ -1,10 +1,14 @@
package cn.hutool.poi.excel.sax;
+import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.StrBuilder;
+import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.sax.handler.RowHandler;
import cn.hutool.poi.exceptions.POIException;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
@@ -12,10 +16,10 @@ import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.Locator;
+import org.xml.sax.helpers.DefaultHandler;
import java.io.File;
+import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
@@ -28,7 +32,7 @@ import java.util.List;
* @author Looly
* @since 3.1.2
*/
-public class Excel07SaxReader extends AbstractExcelSaxReader implements ContentHandler {
+public class Excel07SaxReader extends DefaultHandler implements ExcelSaxReader {
// sheet r:Id前缀
private static final String RID_PREFIX = "rId";
@@ -92,20 +96,30 @@ public class Excel07SaxReader extends AbstractExcelSaxReader i
// ------------------------------------------------------------------------------ Read start
@Override
public Excel07SaxReader read(File file, int rid) throws POIException {
+ return read(file, RID_PREFIX + rid);
+ }
+
+ @Override
+ public Excel07SaxReader read(File file, String idOrRid) throws POIException {
try {
- return read(OPCPackage.open(file), rid);
- } catch (Exception e) {
+ return read(OPCPackage.open(file), idOrRid);
+ } catch (InvalidFormatException e) {
throw new POIException(e);
}
}
@Override
public Excel07SaxReader read(InputStream in, int rid) throws POIException {
- try {
- return read(OPCPackage.open(in), rid);
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
+ return read(in, RID_PREFIX + rid);
+ }
+
+ @Override
+ public Excel07SaxReader read(InputStream in, String idOrRid) throws POIException {
+ try (final OPCPackage opcPackage = OPCPackage.open(in)) {
+ return read(opcPackage, idOrRid);
+ } catch (IOException e) {
+ throw new IORuntimeException(e);
+ } catch (InvalidFormatException e) {
throw new POIException(e);
}
}
@@ -113,53 +127,60 @@ public class Excel07SaxReader extends AbstractExcelSaxReader i
/**
* 开始读取Excel,Sheet编号从0开始计数
*
- * @param opcPackage {@link OPCPackage},Excel包
+ * @param opcPackage {@link OPCPackage},Excel包,读取后不关闭
* @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet
* @return this
* @throws POIException POI异常
*/
public Excel07SaxReader read(OPCPackage opcPackage, int rid) throws POIException {
- InputStream sheetInputStream = null;
+ return read(opcPackage, RID_PREFIX + rid);
+ }
+
+ /**
+ * 开始读取Excel,Sheet编号从0开始计数
+ *
+ * @param opcPackage {@link OPCPackage},Excel包,读取后不关闭
+ * @param idOrRid Excel中的sheet id或者rid编号,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
+ * @return this
+ * @throws POIException POI异常
+ */
+ public Excel07SaxReader read(OPCPackage opcPackage, String idOrRid) throws POIException {
try {
- final XSSFReader xssfReader = new XSSFReader(opcPackage);
-
- // 获取共享样式表
- try {
- stylesTable = xssfReader.getStylesTable();
- } catch (Exception e) {
- //ignore
- }
- // 获取共享字符串表
- this.sharedStringsTable = xssfReader.getSharedStringsTable();
-
- if (rid > -1) {
- this.sheetIndex = rid;
- // 根据 rId# 或 rSheet# 查找sheet
- sheetInputStream = xssfReader.getSheet(RID_PREFIX + (rid + 1));
- ExcelSaxUtil.readFrom(sheetInputStream, this);
- rowHandler.doAfterAllAnalysed();
- } else {
- this.sheetIndex = -1;
- // 遍历所有sheet
- final Iterator sheetInputStreams = xssfReader.getSheetsData();
- while (sheetInputStreams.hasNext()) {
- // 重新读取一个sheet时行归零
- index = 0;
- this.sheetIndex++;
- sheetInputStream = sheetInputStreams.next();
- ExcelSaxUtil.readFrom(sheetInputStream, this);
- rowHandler.doAfterAllAnalysed();
- }
- }
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
+ return read(new XSSFReader(opcPackage), idOrRid);
+ } catch (OpenXML4JException e) {
throw new POIException(e);
- } finally {
- IoUtil.close(sheetInputStream);
- IoUtil.close(opcPackage);
+ } catch (IOException e) {
+ throw new IORuntimeException(e);
}
- return this;
+ }
+
+ /**
+ * 开始读取Excel,Sheet编号从0开始计数
+ *
+ * @param xssfReader {@link XSSFReader},Excel读取器
+ * @param idOrRid Excel中的sheet id或者rid编号,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
+ * @return this
+ * @throws POIException POI异常
+ * @since 5.4.4
+ */
+ public Excel07SaxReader read(XSSFReader xssfReader, String idOrRid) throws POIException {
+ // 获取共享样式表
+ try {
+ stylesTable = xssfReader.getStylesTable();
+ } catch (Exception e) {
+ //ignore
+ }
+
+ // 获取共享字符串表
+ try {
+ this.sharedStringsTable = xssfReader.getSharedStringsTable();
+ } catch (IOException e) {
+ throw new IORuntimeException(e);
+ } catch (InvalidFormatException e) {
+ throw new POIException(e);
+ }
+
+ return readSheets(xssfReader, idOrRid);
}
// ------------------------------------------------------------------------------ Read end
@@ -196,53 +217,57 @@ public class Excel07SaxReader extends AbstractExcelSaxReader i
lastContent.append(ch, start, length);
}
- // --------------------------------------------------------------------------------------- Pass method start
- @Override
- public void setDocumentLocator(Locator locator) {
- // pass
- }
+ // --------------------------------------------------------------------------------------- Private method start
/**
- * ?xml标签的回调处理方法
+ * 开始读取Excel,Sheet编号从0开始计数
+ *
+ * @param xssfReader {@link XSSFReader},Excel读取器
+ * @param idOrRid Excel中的sheet id或者rid编号,rid必须加rId前缀,例如rId0,如果为-1处理所有编号的sheet
+ * @return this
+ * @throws POIException POI异常
+ * @since 5.4.4
*/
- @Override
- public void startDocument() {
- // pass
+ private Excel07SaxReader readSheets(XSSFReader xssfReader, String idOrRid) throws POIException {
+ // 将sheetId转换为rid
+ if (NumberUtil.isInteger(idOrRid)) {
+ final SheetRidReader ridReader = new SheetRidReader();
+ final String rid = ridReader.read(xssfReader).getRidBySheetId(idOrRid);
+ if (StrUtil.isNotEmpty(rid)) {
+ idOrRid = rid;
+ }
+ }
+ this.sheetIndex = Integer.parseInt(StrUtil.removePrefixIgnoreCase(idOrRid, RID_PREFIX));
+ InputStream sheetInputStream = null;
+ try {
+ if (this.sheetIndex > -1) {
+ // 根据 rId# 或 rSheet# 查找sheet
+ sheetInputStream = xssfReader.getSheet(RID_PREFIX + (this.sheetIndex + 1));
+ ExcelSaxUtil.readFrom(sheetInputStream, this);
+ rowHandler.doAfterAllAnalysed();
+ } else {
+ this.sheetIndex = -1;
+ // 遍历所有sheet
+ final Iterator sheetInputStreams = xssfReader.getSheetsData();
+ while (sheetInputStreams.hasNext()) {
+ // 重新读取一个sheet时行归零
+ index = 0;
+ this.sheetIndex++;
+ sheetInputStream = sheetInputStreams.next();
+ ExcelSaxUtil.readFrom(sheetInputStream, this);
+ rowHandler.doAfterAllAnalysed();
+ }
+ }
+ } catch (RuntimeException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new POIException(e);
+ } finally {
+ IoUtil.close(sheetInputStream);
+ }
+ return this;
}
- @Override
- public void endDocument() {
- // pass
- }
-
- @Override
- public void startPrefixMapping(String prefix, String uri) {
- // pass
- }
-
- @Override
- public void endPrefixMapping(String prefix) {
- // pass
- }
-
- @Override
- public void ignorableWhitespace(char[] ch, int start, int length) {
- // pass
- }
-
- @Override
- public void processingInstruction(String target, String data) {
- // pass
- }
-
- @Override
- public void skippedEntity(String name) {
- // pass
- }
- // --------------------------------------------------------------------------------------- Pass method end
-
- // --------------------------------------------------------------------------------------- Private method start
-
/**
* 行开始
*
@@ -317,10 +342,11 @@ public class Excel07SaxReader extends AbstractExcelSaxReader i
/**
* 在一行中的指定列增加值
+ *
* @param index 位置
* @param value 值
*/
- private void addCellValue(int index, Object value){
+ private void addCellValue(int index, Object value) {
this.rowCellList.add(index, value);
this.rowHandler.handleCell(this.sheetIndex, this.rowNumber, index, value, this.xssfCellStyle);
}
diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxReader.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxReader.java
index 58cbc330d..fff65028f 100644
--- a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxReader.java
+++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxReader.java
@@ -1,10 +1,11 @@
package cn.hutool.poi.excel.sax;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.poi.exceptions.POIException;
+
import java.io.File;
import java.io.InputStream;
-import cn.hutool.poi.exceptions.POIException;
-
/**
* Sax方式读取Excel接口,提供一些共用方法
* @author looly
@@ -13,60 +14,105 @@ import cn.hutool.poi.exceptions.POIException;
* @since 3.2.0
*/
public interface ExcelSaxReader {
+
+ /**
+ * 开始读取Excel
+ *
+ * @param file Excel文件
+ * @param idOrRid Excel中的sheet id或者rid编号,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
+ * @return this
+ * @throws POIException POI异常
+ */
+ T read(File file, String idOrRid) throws POIException;
+
+ /**
+ * 开始读取Excel,读取结束后并不关闭流
+ *
+ * @param in Excel流
+ * @param idOrRid Excel中的sheet id或者rid编号,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
+ * @return this
+ * @throws POIException POI异常
+ */
+ T read(InputStream in, String idOrRid) throws POIException;
+
/**
* 开始读取Excel,读取所有sheet
- *
+ *
* @param path Excel文件路径
* @return this
* @throws POIException POI异常
*/
- T read(String path) throws POIException;
+ default T read(String path) throws POIException {
+ return read(FileUtil.file(path));
+ }
/**
* 开始读取Excel,读取所有sheet
- *
+ *
* @param file Excel文件
* @return this
* @throws POIException POI异常
*/
- T read(File file) throws POIException;
+ default T read(File file) throws POIException {
+ return read(file, -1);
+ }
/**
* 开始读取Excel,读取所有sheet,读取结束后并不关闭流
- *
+ *
* @param in Excel包流
* @return this
* @throws POIException POI异常
*/
- T read(InputStream in) throws POIException;
+ default T read(InputStream in) throws POIException {
+ return read(in, -1);
+ }
/**
* 开始读取Excel
- *
+ *
* @param path 文件路径
* @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet
* @return this
* @throws POIException POI异常
*/
- T read(String path, int rid) throws POIException;
+ default T read(String path, int rid) throws POIException {
+ return read(FileUtil.file(path), rid);
+ }
/**
* 开始读取Excel
- *
+ *
+ * @param path 文件路径
+ * @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet
+ * @return this
+ * @throws POIException POI异常
+ */
+ default T read(String path, String rid) throws POIException {
+ return read(FileUtil.file(path), rid);
+ }
+
+ /**
+ * 开始读取Excel
+ *
* @param file Excel文件
* @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet
* @return this
* @throws POIException POI异常
*/
- T read(File file, int rid) throws POIException;
+ default T read(File file, int rid) throws POIException{
+ return read(file, String.valueOf(rid));
+ }
/**
* 开始读取Excel,读取结束后并不关闭流
- *
+ *
* @param in Excel流
* @param rid Excel中的sheet rid编号,如果为-1处理所有编号的sheet
* @return this
* @throws POIException POI异常
*/
- T read(InputStream in, int rid) throws POIException;
+ default T read(InputStream in, int rid) throws POIException{
+ return read(in, String.valueOf(rid));
+ };
}
diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxUtil.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxUtil.java
index b8acb25ce..c98b01334 100644
--- a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxUtil.java
+++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/ExcelSaxUtil.java
@@ -5,6 +5,7 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.DependencyException;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.StrUtil;
+import cn.hutool.poi.excel.sax.handler.RowHandler;
import cn.hutool.poi.exceptions.POIException;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.ss.usermodel.DataFormatter;
@@ -73,9 +74,9 @@ public class ExcelSaxUtil {
}
break;
case NUMBER:
- try{
+ try {
result = getNumberValue(value, numFmtString);
- }catch (NumberFormatException e){
+ } catch (NumberFormatException e) {
result = value;
}
break;
@@ -150,6 +151,7 @@ public class ExcelSaxUtil {
public static void readFrom(InputStream xmlDocStream, ContentHandler handler) throws DependencyException, POIException, IORuntimeException {
XMLReader xmlReader;
try {
+// xmlReader = XMLReaderFactory.createXMLReader();
//noinspection deprecation
xmlReader = SAXHelper.newXMLReader();
} catch (SAXException | ParserConfigurationException e) {
@@ -191,6 +193,20 @@ public class ExcelSaxUtil {
return DateUtil.date(org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value, false));
}
+ /**
+ * 创建 {@link ExcelSaxReader}
+ *
+ * @param isXlsx 是否为xlsx格式(07格式)
+ * @param rowHandler 行处理器
+ * @return {@link ExcelSaxReader}
+ * @since 5.4.4
+ */
+ public static ExcelSaxReader> createSaxReader(boolean isXlsx, RowHandler rowHandler) {
+ return isXlsx
+ ? new Excel07SaxReader(rowHandler)
+ : new Excel03SaxReader(rowHandler);
+ }
+
/**
* 获取数字类型值
*
diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/SheetRidReader.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/SheetRidReader.java
new file mode 100644
index 000000000..abe9b7176
--- /dev/null
+++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/SheetRidReader.java
@@ -0,0 +1,111 @@
+package cn.hutool.poi.excel.sax;
+
+import cn.hutool.core.io.IORuntimeException;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.poi.exceptions.POIException;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.xssf.eventusermodel.XSSFReader;
+import org.xml.sax.Attributes;
+import org.xml.sax.helpers.DefaultHandler;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 在Sax方式读取Excel时,读取sheet标签中sheetId和rid的对应关系,类似于:
+ *
+ * <sheet name="Sheet6" sheetId="4" r:id="6"/>
+ *
+ *
+ * 读取结果为:
+ *
+ *
+ * {"4": "6"}
+ *
+ *
+ * @author looly
+ * @since 5.4.4
+ */
+public class SheetRidReader extends DefaultHandler {
+
+ private final static String TAG_NAME = "sheet";
+ private final static String RID_ATTR = "r:id";
+ private final static String SHEET_ID_ATTR = "sheetId";
+ private final static String NAME_ATTR = "name";
+
+ private final Map ID_RID_MAP = new HashMap<>();
+ private final Map NAME_RID_MAP = new HashMap<>();
+
+ /**
+ * 读取Wordkbook的XML中sheet标签中sheetId和rid的对应关系
+ *
+ * @param xssfReader XSSF读取器
+ * @return this
+ */
+ public SheetRidReader read(XSSFReader xssfReader) {
+ InputStream workbookData = null;
+ try {
+ workbookData = xssfReader.getWorkbookData();
+ ExcelSaxUtil.readFrom(workbookData, this);
+ } catch (InvalidFormatException e) {
+ throw new POIException(e);
+ } catch (IOException e) {
+ throw new IORuntimeException(e);
+ } finally {
+ IoUtil.close(workbookData);
+ }
+ return this;
+ }
+
+ /**
+ * 根据sheetId获取rid
+ *
+ * @param sheetId Sheet的ID
+ * @return rid
+ */
+ public String getRidBySheetId(String sheetId) {
+ return ID_RID_MAP.get(sheetId);
+ }
+
+ /**
+ * 根据sheet name获取rid
+ *
+ * @param sheetName Sheet的name
+ * @return rid
+ */
+ public String getRidByName(String sheetName) {
+ return NAME_RID_MAP.get(sheetName);
+ }
+
+ @Override
+ public void startElement(String uri, String localName, String qName, Attributes attributes) {
+ if (TAG_NAME.equalsIgnoreCase(localName)) {
+ final int length = attributes.getLength();
+ String sheetId = null;
+ String rid = null;
+ String name = null;
+ for (int i = 0; i < length; i++) {
+ switch (attributes.getLocalName(i)) {
+ case SHEET_ID_ATTR:
+ sheetId = attributes.getValue(i);
+ break;
+ case RID_ATTR:
+ rid = attributes.getValue(i);
+ break;
+ case NAME_ATTR:
+ name = attributes.getValue(i);
+ break;
+ }
+ if (StrUtil.isNotEmpty(sheetId)) {
+ ID_RID_MAP.put(sheetId, rid);
+ }
+ if (StrUtil.isNotEmpty(name)) {
+ NAME_RID_MAP.put(name, rid);
+ }
+ }
+ }
+ }
+}
diff --git a/hutool-poi/src/test/java/cn/hutool/poi/excel/test/ExcelSaxReadTest.java b/hutool-poi/src/test/java/cn/hutool/poi/excel/test/ExcelSaxReadTest.java
index 88d34d4d0..888fa4e6a 100644
--- a/hutool-poi/src/test/java/cn/hutool/poi/excel/test/ExcelSaxReadTest.java
+++ b/hutool-poi/src/test/java/cn/hutool/poi/excel/test/ExcelSaxReadTest.java
@@ -25,7 +25,7 @@ public class ExcelSaxReadTest {
@Test
public void excel07Test() {
// 工具化快速读取
- ExcelUtil.read07BySax("aaa.xlsx", 0, createRowHandler());
+ ExcelUtil.readBySax("aaa.xlsx", 0, createRowHandler());
}
@Test
@@ -33,7 +33,7 @@ public class ExcelSaxReadTest {
Excel03SaxReader reader = new Excel03SaxReader(createRowHandler());
reader.read("aaa.xls", 1);
// Console.log("Sheet index: [{}], Sheet name: [{}]", reader.getSheetIndex(), reader.getSheetName());
- ExcelUtil.read03BySax("aaa.xls", 1, createRowHandler());
+ ExcelUtil.readBySax("aaa.xls", 1, createRowHandler());
}
@Test
@@ -60,7 +60,7 @@ public class ExcelSaxReadTest {
private RowHandler createRowHandler() {
return (sheetIndex, rowIndex, rowlist) -> {
-// Console.log("[{}] [{}] {}", sheetIndex, rowIndex, rowlist);
+// Console.log("[{}] [{}] {}", sheetIndex, rowIndex, rowlist);
if (5 != rowIndex && 6 != rowIndex) {
// 测试样例中除第五行、第六行都为非空行
Assert.assertTrue(CollUtil.isNotEmpty(rowlist));
@@ -105,14 +105,14 @@ public class ExcelSaxReadTest {
@Test
@Ignore
- public void dateReadTest(){
+ public void dateReadTest() {
ExcelUtil.readBySax("d:/test/sax_date_test.xlsx", 0, (i, i1, list) ->
Console.log(StrUtil.join(", ", list)));
}
@Test
@Ignore
- public void readBlankTest(){
+ public void readBlankTest() {
File file = new File("D:/test/b.xlsx");
ExcelUtil.readBySax(file, 0, (sheetIndex, rowIndex, rowList) -> rowList.forEach(Console::log));
diff --git a/hutool-script/pom.xml b/hutool-script/pom.xml
index 0bc5d4c63..995789f43 100644
--- a/hutool-script/pom.xml
+++ b/hutool-script/pom.xml
@@ -8,7 +8,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool-script
@@ -18,7 +18,7 @@
2.7.2
3.0.1
- 3.0.2
+ 3.0.6
diff --git a/hutool-setting/pom.xml b/hutool-setting/pom.xml
index 7ab60de80..00e487784 100644
--- a/hutool-setting/pom.xml
+++ b/hutool-setting/pom.xml
@@ -9,7 +9,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool-setting
diff --git a/hutool-socket/pom.xml b/hutool-socket/pom.xml
index 19509870c..459441938 100644
--- a/hutool-socket/pom.xml
+++ b/hutool-socket/pom.xml
@@ -9,7 +9,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool-socket
diff --git a/hutool-system/pom.xml b/hutool-system/pom.xml
index 93fb286bb..8110b4903 100644
--- a/hutool-system/pom.xml
+++ b/hutool-system/pom.xml
@@ -9,7 +9,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool-system
diff --git a/pom.xml b/pom.xml
index 534a944a2..57c5d9379 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
cn.hutool
hutool-parent
- 5.4.4-SNAPSHOT
+ 5.4.5-SNAPSHOT
hutool
Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。
https://github.com/looly/hutool