collection, String... array)
{
@@ -420,6 +472,18 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
}
}
+ /**
+ * 判断是否包含给定数组中的任意一个。
+ *
+ * @param cs 要判断的字符串
+ * @param searchCharSequences 要判断的数组
+ * @return 结果
+ */
+ public static boolean containsAny(final CharSequence cs, final CharSequence... searchCharSequences)
+ {
+ return Strings.CS.containsAny(cs, searchCharSequences);
+ }
+
/**
* 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
*
@@ -443,6 +507,163 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
return false;
}
+ /**
+ * 检查是否包含要搜索的字符串,忽略大小写
+ *
+ * @param str 要检查的字符串
+ * @param searchStr 要查找的字符串
+ * @return 如果包含要搜索的字符串(忽略大小写)则返回true,如果不包含或返回false
+ */
+ public static boolean containsIgnoreCase(final CharSequence str, final CharSequence searchStr)
+ {
+ return Strings.CI.contains(str, searchStr);
+ }
+
+ /**
+ * 检查字符串是否以任意前缀开始
+ *
+ * @param sequence 要检查的字符串
+ * @param searchStrings 区分大小写的字符串前缀数组
+ * @return 结果
+ */
+ public static boolean startsWithAny(final CharSequence sequence, final CharSequence... searchStrings)
+ {
+ return Strings.CS.startsWithAny(sequence, searchStrings);
+ }
+
+ /**
+ * 不区分大小写地检查一个字符串是否以指定前缀开头。
+ *
+ * @param str 待检查的字符串
+ * @param 要查找的前缀
+ * @return 结果
+ */
+ public static boolean startsWithIgnoreCase(final CharSequence str, final CharSequence prefix)
+ {
+ return Strings.CI.startsWith(str, prefix);
+ }
+
+ /**
+ * 比较两个字符串是否相同
+ *
+ * @param cs1 第一个字符串
+ * @param cs2 第二个字符串
+ * @return 如果给定对象与字符串相等,则返回 true;否则返回 false
+ */
+ public static boolean equals(final CharSequence cs1, final CharSequence cs2)
+ {
+ return Strings.CS.equals(cs1, cs2);
+ }
+
+ /**
+ * 替换字符串中所有匹配的字符
+ *
+ * @param text 要搜索和替换的文本
+ * @param searchString 要搜索的字符串
+ * @param replacement 用于替换的字符串
+ * @return 处理完所有替换后的文本
+ */
+ public static String replace(final String text, final String searchString, final String replacement)
+ {
+ return Strings.CS.replace(text, searchString, replacement);
+ }
+
+ /**
+ * 仅当子字符串位于源字符串末尾时才将其移除,否则返回源字符串。
+ * @param str 要搜索的源字符串
+ * @param remove 要搜索并移除的字符串
+ * @return 如果找到并移除了字符串,则返回移除后的子字符串
+ */
+ public static String removeEnd(final String str, final String remove)
+ {
+ return Strings.CS.removeEnd(str, remove);
+ }
+
+ /**
+ * 查找字符串首次出现位置的索引
+ *
+ * @param seq 要检查的字符串
+ * @param searchSeq 要查找的字符串
+ * @return 返回指定字符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,则返回 -1
+ */
+ public static int indexOf(final CharSequence seq, final CharSequence searchSeq)
+ {
+ return Strings.CS.indexOf(seq, searchSeq);
+ }
+
+ /**
+ * 检查字符串是否以指定的后缀结尾
+ *
+ * @param str 要检查的字符
+ * @param suffix 要检查的后缀
+ * @return 若参数与该字符串末尾相符 true;否则 false
+ */
+ public static boolean endsWith(final CharSequence str, final CharSequence suffix)
+ {
+ return Strings.CS.endsWith(str, suffix);
+ }
+
+ /**
+ * 将给定的字符串与数组进行比较
+ *
+ * @param string 要比较的字符串
+ * @param searchStrings 字符串数组
+ * @return 如果字符串等于(区分大小写){@code searchStrings}中的任意其他元素,则返回true;如果{@code searchStrings}为null或不包含匹配项,则返回false
+ */
+ public static boolean equalsAny(final CharSequence string, final CharSequence... searchStrings)
+ {
+ return Strings.CS.equalsAny(string, searchStrings);
+ }
+
+ /**
+ * 检查一个字符串是否以任意提供的区分大小写的后缀结尾。
+ *
+ * @param sequence 要检查的字符串
+ * @param searchStrings 要查找的区分大小写的字符串数组
+ * @return 如果输入参数{@code sequence}为null且未提供任何{@code searchStrings},或者输入{@code sequence}以任意提供的区分大小写的{@code searchStrings}结尾,则返回{@code true}。
+ */
+ public static boolean endsWithAny(final CharSequence sequence, final CharSequence... searchStrings)
+ {
+ return Strings.CS.endsWithAny(sequence, searchStrings);
+ }
+
+ /**
+ * 不区分大小写地检查字符序列是否以指定的后缀结尾
+ *
+ * @param str 要检查的字符序列
+ * @param suffix 要查找的后缀
+ * @return 如果字符序列以该后缀结尾(不区分大小写),或两者均为{@code null},则返回{@code true}
+ */
+ public static boolean endsWithIgnoreCase(final CharSequence str, final CharSequence suffix)
+ {
+ return Strings.CI.endsWith(str, suffix);
+ }
+
+ /**
+ * 指定范围内查找字符串,忽略大小写
+ *
+ * @param str 要检查的字符串
+ * @param searchStr 要查找的字符串
+ * @return 搜索字符串的第一个索引,如果未找到匹配项则返回 -1
+ */
+ public static int indexOfIgnoreCase(final CharSequence str, final CharSequence searchStr)
+ {
+ return Strings.CI.indexOf(str, searchStr);
+ }
+
+ /**
+ * Compares given {@code string} to a CharSequences vararg of {@code searchStrings},
+ * returning {@code true} if the {@code string} is equal to any of the {@code searchStrings}, ignoring case.
+ *
+ * @param string to compare, may be {@code null}.
+ * @param searchStrings a vararg of strings, may be {@code null}.
+ * @return {@code true} if the string is equal (case-insensitive) to any other element of {@code searchStrings};
+ */
+ public static boolean equalsAnyIgnoreCase(final CharSequence string, final CharSequence... searchStrings)
+ {
+ return Strings.CI.equalsAny(string, searchStrings);
+ }
+
/**
* 驼峰转下划线命名
*/
@@ -514,6 +735,22 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
return false;
}
+ /**
+ * 删除最后一个字符串
+ *
+ * @param str 输入字符串
+ * @param spit 以什么类型结尾的
+ * @return 截取后的字符串
+ */
+ public static String lastStringDel(String str, String spit)
+ {
+ if (!StringUtils.isEmpty(str) && str.endsWith(spit))
+ {
+ return str.subSequence(0, str.length() - 1).toString();
+ }
+ return str;
+ }
+
/**
* 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
*
@@ -681,4 +918,4 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
}
return sb.toString();
}
-}
+}
\ No newline at end of file
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/Threads.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/Threads.java
index 3713da2..05dc312 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/Threads.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/Threads.java
@@ -11,7 +11,7 @@ import org.slf4j.LoggerFactory;
/**
* 线程相关工具类.
*
- * @author cmvrIot
+ * @author ruoyi
*/
public class Threads
{
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/bean/BeanUtils.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/bean/BeanUtils.java
index 8541109..ce3b0c1 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/bean/BeanUtils.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/bean/BeanUtils.java
@@ -9,7 +9,7 @@ import java.util.regex.Pattern;
/**
* Bean 工具类
*
- * @author cmvrIot
+ * @author ruoyi
*/
public class BeanUtils extends org.springframework.beans.BeanUtils
{
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/bean/BeanValidators.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/bean/BeanValidators.java
index 4f24a78..57205cb 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/bean/BeanValidators.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/bean/BeanValidators.java
@@ -1,14 +1,14 @@
package com.cmvr.common.utils.bean;
import java.util.Set;
-import javax.validation.ConstraintViolation;
-import javax.validation.ConstraintViolationException;
-import javax.validation.Validator;
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.ConstraintViolationException;
+import jakarta.validation.Validator;
/**
* bean对象属性验证
*
- * @author cmvrIot
+ * @author ruoyi
*/
public class BeanValidators
{
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/FileTypeUtils.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/FileTypeUtils.java
index 8fb6325..5574d89 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/FileTypeUtils.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/FileTypeUtils.java
@@ -6,14 +6,14 @@ import org.apache.commons.lang3.StringUtils;
/**
* 文件类型工具类
*
- * @author cmvrIot
+ * @author ruoyi
*/
public class FileTypeUtils
{
/**
* 获取文件类型
*
- * 例如: cmvrIot.txt, 返回: txt
+ * 例如: ruoyi.txt, 返回: txt
*
* @param file 文件名
* @return 后缀(不含".")
@@ -30,7 +30,7 @@ public class FileTypeUtils
/**
* 获取文件类型
*
- * 例如: cmvrIot.txt, 返回: txt
+ * 例如: ruoyi.txt, 返回: txt
*
* @param fileName 文件名
* @return 后缀(不含".")
@@ -73,4 +73,4 @@ public class FileTypeUtils
}
return strFileExtendName;
}
-}
+}
\ No newline at end of file
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/FileUploadUtils.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/FileUploadUtils.java
index bb7c0b3..e2bae16 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/FileUploadUtils.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/FileUploadUtils.java
@@ -13,12 +13,13 @@ import com.cmvr.common.exception.file.FileSizeLimitExceededException;
import com.cmvr.common.exception.file.InvalidExtensionException;
import com.cmvr.common.utils.DateUtils;
import com.cmvr.common.utils.StringUtils;
+import com.cmvr.common.utils.uuid.IdUtils;
import com.cmvr.common.utils.uuid.Seq;
/**
* 文件上传工具类
- *
- * @author cmvr-iot
+ *
+ * @author ruoyi
*/
public class FileUploadUtils
{
@@ -102,15 +103,35 @@ public class FileUploadUtils
throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
InvalidExtensionException
{
- int fileNamelength = Objects.requireNonNull(file.getOriginalFilename()).length();
- if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
+ return upload(baseDir, file, allowedExtension, false);
+ }
+
+ /**
+ * 文件上传
+ *
+ * @param baseDir 相对应用的基目录
+ * @param file 上传的文件
+ * @param useCustomNaming 系统自定义文件名
+ * @param allowedExtension 上传文件类型
+ * @return 返回上传成功的文件名
+ * @throws FileSizeLimitExceededException 如果超出最大大小
+ * @throws FileNameLengthLimitExceededException 文件名太长
+ * @throws IOException 比如读写文件出错时
+ * @throws InvalidExtensionException 文件校验异常
+ */
+ public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension, boolean useCustomNaming)
+ throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
+ InvalidExtensionException
+ {
+ int fileNameLength = Objects.requireNonNull(file.getOriginalFilename()).length();
+ if (fileNameLength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
{
throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
}
assertAllowed(file, allowedExtension);
- String fileName = extractFilename(file);
+ String fileName = useCustomNaming ? uuidFilename(file) : extractFilename(file);
String absPath = getAbsoluteFile(baseDir, fileName).getAbsolutePath();
file.transferTo(Paths.get(absPath));
@@ -118,12 +139,19 @@ public class FileUploadUtils
}
/**
- * 编码文件名
+ * 编码文件名(日期格式目录 + 原文件名 + 序列值 + 后缀)
*/
public static final String extractFilename(MultipartFile file)
{
- return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(),
- FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
+ return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(), FilenameUtils.getBaseName(file.getOriginalFilename()), Seq.getId(Seq.uploadSeqType), getExtension(file));
+ }
+
+ /**
+ * 编编码文件名(日期格式目录 + UUID + 后缀)
+ */
+ public static final String uuidFilename(MultipartFile file)
+ {
+ return StringUtils.format("{}/{}.{}", DateUtils.datePath(), IdUtils.fastSimpleUUID(), getExtension(file));
}
public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
@@ -216,7 +244,7 @@ public class FileUploadUtils
/**
* 获取文件名的后缀
- *
+ *
* @param file 表单文件
* @return 后缀名
*/
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/FileUtils.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/FileUtils.java
index 8755beb..ed87b64 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/FileUtils.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/FileUtils.java
@@ -9,20 +9,21 @@ import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import com.cmvr.common.config.CmvrIotConfig;
+import com.cmvr.common.constant.Constants;
import com.cmvr.common.utils.DateUtils;
import com.cmvr.common.utils.StringUtils;
import com.cmvr.common.utils.uuid.IdUtils;
-import org.apache.commons.io.FilenameUtils;
/**
* 文件处理工具类
*
- * @author cmvrIot
+ * @author ruoyi
*/
public class FileUtils
{
@@ -103,6 +104,17 @@ public class FileUtils
return FileUploadUtils.getPathFileName(uploadDir, pathName);
}
+ /**
+ * 移除路径中的请求前缀片段
+ *
+ * @param filePath 文件路径
+ * @return 移除后的文件路径
+ */
+ public static String stripPrefix(String filePath)
+ {
+ return StringUtils.substringAfter(filePath, Constants.RESOURCE_PREFIX);
+ }
+
/**
* 删除文件
*
@@ -256,7 +268,7 @@ public class FileUtils
}
/**
- * 获取文件名称 /profile/upload/2022/04/16/cmvrIot.png -- cmvrIot.png
+ * 获取文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi.png
*
* @param fileName 路径名称
* @return 没有文件路径的名称
@@ -274,7 +286,7 @@ public class FileUtils
}
/**
- * 获取不带后缀文件名称 /profile/upload/2022/04/16/cmvrIot.png -- cmvrIot
+ * 获取不带后缀文件名称 /profile/upload/2022/04/16/ruoyi.png -- ruoyi
*
* @param fileName 路径名称
* @return 没有文件路径和后缀的名称
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/ImageUtils.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/ImageUtils.java
index ce9c8ad..35df54c 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/ImageUtils.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/ImageUtils.java
@@ -16,7 +16,7 @@ import com.cmvr.common.utils.StringUtils;
/**
* 图片处理工具类
*
- * @author cmvrIot
+ * @author ruoyi
*/
public class ImageUtils
{
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/MimeTypeUtils.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/MimeTypeUtils.java
index 70ade72..8310f91 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/MimeTypeUtils.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/file/MimeTypeUtils.java
@@ -3,7 +3,7 @@ package com.cmvr.common.utils.file;
/**
* 媒体类型工具类
*
- * @author cmvrIot
+ * @author ruoyi
*/
public class MimeTypeUtils
{
@@ -30,7 +30,7 @@ public class MimeTypeUtils
// 图片
"bmp", "gif", "jpg", "jpeg", "png",
// word excel powerpoint
- "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
+ "doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt",
// 压缩文件
"rar", "zip", "gz", "bz2",
// 视频格式
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/html/EscapeUtil.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/html/EscapeUtil.java
index ac287a5..02477d1 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/html/EscapeUtil.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/html/EscapeUtil.java
@@ -5,7 +5,7 @@ import com.cmvr.common.utils.StringUtils;
/**
* 转义和反转义工具类
*
- * @author cmvrIot
+ * @author ruoyi
*/
public class EscapeUtil
{
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/html/HTMLFilter.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/html/HTMLFilter.java
index a638191..8622baa 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/html/HTMLFilter.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/html/HTMLFilter.java
@@ -13,7 +13,7 @@ import java.util.regex.Pattern;
/**
* HTML过滤器,用于去除XSS漏洞隐患。
*
- * @author cmvrIot
+ * @author ruoyi
*/
public final class HTMLFilter
{
@@ -567,4 +567,4 @@ public final class HTMLFilter
{
return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName));
}
-}
+}
\ No newline at end of file
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/http/HttpHelper.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/http/HttpHelper.java
index 5a78e7c..e1458cd 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/http/HttpHelper.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/http/HttpHelper.java
@@ -5,7 +5,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
-import javax.servlet.ServletRequest;
+import jakarta.servlet.ServletRequest;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -13,7 +13,7 @@ import org.slf4j.LoggerFactory;
/**
* 通用http工具封装
*
- * @author cmvrIot
+ * @author ruoyi
*/
public class HttpHelper
{
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/http/HttpUtils.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/http/HttpUtils.java
index 784d138..2168a9e 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/http/HttpUtils.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/http/HttpUtils.java
@@ -1,6 +1,5 @@
package com.cmvr.common.utils.http;
-import cn.hutool.json.JSONUtil;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -26,11 +25,13 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.cmvr.common.constant.Constants;
import com.cmvr.common.utils.StringUtils;
+import org.springframework.http.MediaType;
+import cn.hutool.json.JSONUtil;
/**
* 通用http发送方法
*
- * @author cmvrIot
+ * @author ruoyi
*/
public class HttpUtils
{
@@ -130,6 +131,19 @@ public class HttpUtils
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, String param)
+ {
+ return sendPost(url, param, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
+ }
+
+ /**
+ * 向指定 URL 发送POST方法的请求
+ *
+ * @param url 发送请求的 URL
+ * @param param 请求参数
+ * @param contentType 内容类型
+ * @return 所代表远程资源的响应结果
+ */
+ public static String sendPost(String url, String param, String contentType)
{
PrintWriter out = null;
BufferedReader in = null;
@@ -143,7 +157,7 @@ public class HttpUtils
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
conn.setRequestProperty("Accept-Charset", "utf-8");
- conn.setRequestProperty("contentType", "utf-8");
+ conn.setRequestProperty("Content-Type", contentType);
conn.setDoOutput(true);
conn.setDoInput(true);
out = new PrintWriter(conn.getOutputStream());
@@ -195,6 +209,11 @@ public class HttpUtils
}
public static String sendSSLPost(String url, String param)
+ {
+ return sendSSLPost(url, param, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
+ }
+
+ public static String sendSSLPost(String url, String param, String contentType)
{
StringBuilder result = new StringBuilder();
String urlNameString = url + "?" + param;
@@ -209,7 +228,7 @@ public class HttpUtils
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
conn.setRequestProperty("Accept-Charset", "utf-8");
- conn.setRequestProperty("contentType", "utf-8");
+ conn.setRequestProperty("Content-Type", contentType);
conn.setDoOutput(true);
conn.setDoInput(true);
@@ -249,6 +268,54 @@ public class HttpUtils
return result.toString();
}
+ public static byte[] sendPostReturnBytes(String url, Map params)
+ {
+ HttpURLConnection conn = null;
+ try
+ {
+ log.info("sendPostReturnBytes - {}", url);
+ conn = (HttpURLConnection) new URL(url).openConnection();
+ conn.setRequestMethod("POST");
+ conn.setRequestProperty("accept", "*/*");
+ conn.setRequestProperty("connection", "Keep-Alive");
+ conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
+ conn.setDoOutput(true);
+ conn.setDoInput(true);
+ conn.setConnectTimeout(30000);
+ conn.setReadTimeout(60000);
+ try (OutputStream os = conn.getOutputStream())
+ {
+ os.write(JSONUtil.toJsonStr(params).getBytes(StandardCharsets.UTF_8));
+ }
+ int responseCode = conn.getResponseCode();
+ if (responseCode != HttpURLConnection.HTTP_OK)
+ {
+ throw new IOException("HTTP error code: " + responseCode);
+ }
+ try (InputStream is = conn.getInputStream(); ByteArrayOutputStream output = new ByteArrayOutputStream())
+ {
+ byte[] buffer = new byte[4096];
+ int length;
+ while ((length = is.read(buffer)) != -1)
+ {
+ output.write(buffer, 0, length);
+ }
+ return output.toByteArray();
+ }
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException("调用外部服务失败: " + url, e);
+ }
+ finally
+ {
+ if (conn != null)
+ {
+ conn.disconnect();
+ }
+ }
+ }
+
private static class TrustAnyTrustManager implements X509TrustManager
{
@Override
@@ -276,90 +343,4 @@ public class HttpUtils
return true;
}
}
-
- /**
- * 向指定 URL 发送POST方法的请求,返回字节数组(用于接收文件流)
- *
- * @param url 发送请求的 URL
- * @param params 请求参数
- * @return 所代表远程资源的响应结果(字节数组)
- */
- public static byte[] sendPostReturnBytes(String url, Map params)
- {
- HttpURLConnection conn = null;
- try
- {
- log.info("sendPostReturnBytes - {}", url);
- URL realUrl = new URL(url);
- conn = (HttpURLConnection) realUrl.openConnection();
- conn.setRequestMethod("POST");
- conn.setRequestProperty("accept", "*/*");
- conn.setRequestProperty("connection", "Keep-Alive");
- conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
- conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
- conn.setDoOutput(true);
- conn.setDoInput(true);
- conn.setConnectTimeout(30000);
- conn.setReadTimeout(60000);
-
- // 发送请求参数
- String jsonParams = JSONUtil.toJsonStr(params);
- try (OutputStream os = conn.getOutputStream())
- {
- os.write(jsonParams.getBytes(StandardCharsets.UTF_8));
- os.flush();
- }
-
- // 读取响应
- int responseCode = conn.getResponseCode();
- if (responseCode == HttpURLConnection.HTTP_OK)
- {
- try (InputStream is = conn.getInputStream();
- ByteArrayOutputStream baos = new ByteArrayOutputStream())
- {
- byte[] buffer = new byte[1024];
- int len;
- while ((len = is.read(buffer)) != -1)
- {
- baos.write(buffer, 0, len);
- }
- byte[] result = baos.toByteArray();
- log.info("recv bytes length: {}", result.length);
- return result;
- }
- }
- else
- {
- log.error("HTTP error code: {}", responseCode);
- throw new RuntimeException("HTTP error code: " + responseCode);
- }
- }
- catch (ConnectException e)
- {
- log.error("调用HttpUtils.sendPostReturnBytes ConnectException, url=" + url, e);
- throw new RuntimeException("连接外部TTS服务失败", e);
- }
- catch (SocketTimeoutException e)
- {
- log.error("调用HttpUtils.sendPostReturnBytes SocketTimeoutException, url=" + url, e);
- throw new RuntimeException("外部TTS服务超时", e);
- }
- catch (IOException e)
- {
- log.error("调用HttpUtils.sendPostReturnBytes IOException, url=" + url, e);
- throw new RuntimeException("IO异常", e);
- }
- catch (Exception e)
- {
- log.error("调用HttpUtils.sendPostReturnBytes Exception, url=" + url, e);
- throw new RuntimeException("调用外部TTS服务异常", e);
- }
- finally
- {
- if (conn != null)
- {
- conn.disconnect();
- }
- }
- }
}
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/http/UserAgentUtils.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/http/UserAgentUtils.java
new file mode 100644
index 0000000..2ff3bdb
--- /dev/null
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/http/UserAgentUtils.java
@@ -0,0 +1,254 @@
+package com.cmvr.common.utils.http;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import com.cmvr.common.utils.StringUtils;
+import nl.basjes.parse.useragent.UserAgent;
+import nl.basjes.parse.useragent.UserAgentAnalyzer;
+
+/**
+ * UserAgent解析工具类
+ *
+ * @author ruoyi
+ */
+public class UserAgentUtils
+{
+ public static final String UNKNOWN = "";
+
+ // 浏览器正则表达式模式
+ private static final Pattern CHROME_PATTERN = Pattern.compile("Chrome/(\\d+)(?:\\.\\d+)*");
+ private static final Pattern FIREFOX_PATTERN = Pattern.compile("Firefox/(\\d+)(?:\\.\\d+)*");
+ private static final Pattern EDGE_PATTERN = Pattern.compile("Edg(?:e)?/(\\d+)(?:\\.\\d+)*");
+ private static final Pattern SAFARI_PATTERN = Pattern.compile("Version/(\\d+)(?:\\.\\d+)*");
+ private static final Pattern OPERA_PATTERN = Pattern.compile("Opera/(\\d+)(?:\\.\\d+)*");
+ private static final Pattern IE_PATTERN = Pattern.compile("(?:MSIE |Trident/.*rv:)(\\d+)(?:\\.\\d+)*");
+ private static final Pattern SAMSUNG_PATTERN = Pattern.compile("SamsungBrowser/(\\d+)(?:\\.\\d+)*");
+ private static final Pattern UC_PATTERN = Pattern.compile("UCBrowser/(\\d+)(?:\\.\\d+)*");
+ private static final Pattern QQ_PATTERN = Pattern.compile("QQBrowser/(\\d+)(?:\\.\\d+)*");
+ private static final Pattern WECHAT_PATTERN = Pattern.compile("MicroMessenger/(\\d+)(?:\\.\\d+)*");
+ private static final Pattern BAIDU_PATTERN = Pattern.compile("baidubrowser/(\\d+)(?:\\.\\d+)*");
+
+ // 操作系统正则表达式模式
+ private static final Pattern WINDOWS_PATTERN = Pattern.compile("Windows NT (\\d+\\.\\d+)");
+ private static final Pattern MACOS_PATTERN = Pattern.compile("Mac OS X (\\d+[_\\d]*)");
+ private static final Pattern ANDROID_PATTERN = Pattern.compile("Android (\\d+)(?:\\.\\d+)*");
+ private static final Pattern IOS_PATTERN = Pattern.compile("OS[\\s_](\\d+)(?:_\\d+)*");
+ private static final Pattern LINUX_PATTERN = Pattern.compile("Linux");
+ private static final Pattern CHROMEOS_PATTERN = Pattern.compile("CrOS");
+
+ private static final UserAgentAnalyzer userAgentAnalyzer = UserAgentAnalyzer
+ .newBuilder().hideMatcherLoadStats()
+ .withCache(5000)
+ .showMinimalVersion()
+ .withField(UserAgent.AGENT_NAME_VERSION)
+ .withField(UserAgent.OPERATING_SYSTEM_NAME_VERSION)
+ .build();
+
+ /**
+ * 获取客户端浏览器
+ */
+ public static String getBrowser(String userAgent)
+ {
+ UserAgent.ImmutableUserAgent iua = userAgentAnalyzer.parse(userAgent);
+ String agentNameVersion = iua.get(UserAgent.AGENT_NAME_VERSION).getValue();
+ if (StringUtils.isBlank(agentNameVersion) || agentNameVersion.contains("??"))
+ {
+ return formatBrowser(userAgent);
+ }
+ return agentNameVersion;
+ }
+
+ /**
+ * 获取客户端操作系统
+ */
+ public static String getOperatingSystem(String userAgent)
+ {
+ UserAgent.ImmutableUserAgent iua = userAgentAnalyzer.parse(userAgent);
+ String operatingSystemNameVersion = iua.get(UserAgent.OPERATING_SYSTEM_NAME_VERSION).getValue();
+ if (StringUtils.isBlank(operatingSystemNameVersion) || operatingSystemNameVersion.contains("??"))
+ {
+ return formatOperatingSystem(userAgent);
+ }
+ return operatingSystemNameVersion;
+ }
+
+ /**
+ * 全面浏览器检测
+ */
+ private static String formatBrowser(String browser)
+ {
+ // Chrome系列浏览器
+ Matcher chromeMatcher = CHROME_PATTERN.matcher(browser);
+ if (chromeMatcher.find() && (browser.contains("Chrome") || browser.contains("CriOS")))
+ {
+ return "Chrome" + chromeMatcher.group(1);
+ }
+ // Firefox
+ Matcher firefoxMatcher = FIREFOX_PATTERN.matcher(browser);
+ if (firefoxMatcher.find())
+ {
+ return "Firefox" + firefoxMatcher.group(1);
+ }
+ // Edge浏览器
+ Matcher edgeMatcher = EDGE_PATTERN.matcher(browser);
+ if (edgeMatcher.find())
+ {
+ return "Edge" + edgeMatcher.group(1);
+ }
+ // Safari浏览器(需排除Chrome)
+ Matcher safariMatcher = SAFARI_PATTERN.matcher(browser);
+ if (safariMatcher.find() && !browser.contains("Chrome"))
+ {
+ return "Safari" + safariMatcher.group(1);
+ }
+ // 微信内置浏览器
+ Matcher wechatMatcher = WECHAT_PATTERN.matcher(browser);
+ if (wechatMatcher.find())
+ {
+ return "WeChat" + wechatMatcher.group(1);
+ }
+ // UC浏览器
+ Matcher ucMatcher = UC_PATTERN.matcher(browser);
+ if (ucMatcher.find())
+ {
+ return "UC Browser" + ucMatcher.group(1);
+ }
+ // QQ浏览器
+ Matcher qqMatcher = QQ_PATTERN.matcher(browser);
+ if (qqMatcher.find())
+ {
+ return "QQ Browser" + qqMatcher.group(1);
+ }
+ // 百度浏览器
+ Matcher baiduMatcher = BAIDU_PATTERN.matcher(browser);
+ if (baiduMatcher.find())
+ {
+ return "Baidu Browser" + baiduMatcher.group(1);
+ }
+ // Samsung浏览器
+ Matcher samsungMatcher = SAMSUNG_PATTERN.matcher(browser);
+ if (samsungMatcher.find())
+ {
+ return "Samsung Browser" + samsungMatcher.group(1);
+ }
+ // Opera浏览器
+ Matcher operaMatcher = OPERA_PATTERN.matcher(browser);
+ if (operaMatcher.find())
+ {
+ return "Opera" + operaMatcher.group(1);
+ }
+ // IE浏览器
+ Matcher ieMatcher = IE_PATTERN.matcher(browser);
+ if (ieMatcher.find())
+ {
+ return "Internet Explorer" + ieMatcher.group(1);
+ }
+ return UNKNOWN;
+ }
+
+ /**
+ * 检测操作系统
+ */
+ private static String formatOperatingSystem(String operatingSystem)
+ {
+ // Windows系统
+ Matcher windowsMatcher = WINDOWS_PATTERN.matcher(operatingSystem);
+ if (windowsMatcher.find())
+ {
+ return "Windows" + getWindowsVersionDisplay(windowsMatcher.group(1));
+ }
+ // macOS系统
+ Matcher macMatcher = MACOS_PATTERN.matcher(operatingSystem);
+ if (macMatcher.find())
+ {
+ String version = macMatcher.group(1).replace("_", ".");
+ return "macOS" + extractMajorVersion(version);
+ }
+ // Android系统
+ Matcher androidMatcher = ANDROID_PATTERN.matcher(operatingSystem);
+ if (androidMatcher.find())
+ {
+ return "Android" + extractMajorVersion(androidMatcher.group(1));
+ }
+ // iOS系统
+ Matcher iosMatcher = IOS_PATTERN.matcher(operatingSystem);
+ if (iosMatcher.find() && (operatingSystem.contains("iPhone") || operatingSystem.contains("iPad")))
+ {
+ return "iOS" + extractMajorVersion(iosMatcher.group(1));
+ }
+ // Linux系统
+ if (LINUX_PATTERN.matcher(operatingSystem).find() && !operatingSystem.contains("Android"))
+ {
+ return "Linux";
+ }
+ // Chrome OS
+ if (CHROMEOS_PATTERN.matcher(operatingSystem).find())
+ {
+ return "Chrome OS";
+ }
+ return UNKNOWN;
+ }
+
+ /**
+ * 提取优化的主版本号
+ */
+ private static String extractMajorVersion(String fullVersion)
+ {
+ if (StringUtils.isEmpty(fullVersion))
+ {
+ return StringUtils.EMPTY;
+ }
+ try
+ {
+ // 清理版本号中的非数字字符
+ String cleanVersion = fullVersion.replaceAll("[^0-9.]", "");
+ String[] parts = cleanVersion.split("\\.");
+ if (parts.length > 0)
+ {
+ String firstPart = parts[0];
+ if (firstPart.matches("\\d+"))
+ {
+ int version = Integer.parseInt(firstPart);
+
+ // 处理三位数版本号(如142 -> 14)
+ if (version >= 100)
+ {
+ return String.valueOf(version / 10);
+ }
+ return firstPart;
+ }
+ }
+ }
+ catch (NumberFormatException e)
+ {
+ // 版本号解析失败,返回原始值
+ }
+ return fullVersion;
+ }
+
+ /**
+ * Windows版本号显示优化
+ */
+ private static String getWindowsVersionDisplay(String version)
+ {
+ switch (version)
+ {
+ case "10.0":
+ return "10";
+ case "6.3":
+ return "8.1";
+ case "6.2":
+ return "8";
+ case "6.1":
+ return "7";
+ case "6.0":
+ return "Vista";
+ case "5.1":
+ return "XP";
+ case "5.0":
+ return "2000";
+ default:
+ return extractMajorVersion(version);
+ }
+ }
+}
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/ip/AddressUtils.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/ip/AddressUtils.java
index 7d7759f..4513936 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/ip/AddressUtils.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/ip/AddressUtils.java
@@ -12,14 +12,14 @@ import com.cmvr.common.utils.http.HttpUtils;
/**
* 获取地址类
*
- * @author cmvrIot
+ * @author ruoyi
*/
public class AddressUtils
{
private static final Logger log = LoggerFactory.getLogger(AddressUtils.class);
// IP地址查询
- public static final String IP_URL = "http://whois.pconline.com.cn/ipJson.jsp";
+ public static final String IP_URL = "https://whois.pconline.com.cn/ipJson.jsp";
// 未知地址
public static final String UNKNOWN = "XX XX";
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/ip/IpUtils.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/ip/IpUtils.java
index 7780d3e..59e8888 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/ip/IpUtils.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/ip/IpUtils.java
@@ -2,14 +2,14 @@ package com.cmvr.common.utils.ip;
import java.net.InetAddress;
import java.net.UnknownHostException;
-import javax.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletRequest;
import com.cmvr.common.utils.ServletUtils;
import com.cmvr.common.utils.StringUtils;
/**
* 获取IP方法
*
- * @author cmvrIot
+ * @author ruoyi
*/
public class IpUtils
{
@@ -379,4 +379,4 @@ public class IpUtils
}
return false;
}
-}
+}
\ No newline at end of file
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/poi/ExcelHandlerAdapter.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/poi/ExcelHandlerAdapter.java
index 0ea0a11..47fadb0 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/poi/ExcelHandlerAdapter.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/poi/ExcelHandlerAdapter.java
@@ -6,7 +6,7 @@ import org.apache.poi.ss.usermodel.Workbook;
/**
* Excel数据格式处理适配器
*
- * @author cmvrIot
+ * @author ruoyi
*/
public interface ExcelHandlerAdapter
{
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/poi/ExcelSheet.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/poi/ExcelSheet.java
new file mode 100644
index 0000000..fb790bd
--- /dev/null
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/poi/ExcelSheet.java
@@ -0,0 +1,85 @@
+package com.cmvr.common.utils.poi;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 多 Sheet 导出时的数据信息
+ *
+ * 使用示例:
+ *
+ * List> sheets = new ArrayList<>();
+ * sheets.add(new ExcelSheet<>("参数数据", configList, Config.class, "参数信息"));
+ * sheets.add(new ExcelSheet<>("岗位数据", postList, Post.class, "岗位信息"));
+ * return ExcelUtil.exportMultiSheet(sheets);
+ *
+ *
+ * @author ruoyi
+ */
+public class ExcelSheet
+{
+ /** Sheet 名称 */
+ private String sheetName;
+
+ /** 导出数据集合 */
+ private List list;
+
+ /** 数据对应的实体 Class */
+ private Class clazz;
+
+ /** Sheet 顶部大标题(可为空) */
+ private String title;
+
+ public ExcelSheet(String sheetName, List list, Class clazz)
+ {
+ this(sheetName, list, clazz, "");
+ }
+
+ public ExcelSheet(String sheetName, List list, Class clazz, String title)
+ {
+ this.sheetName = sheetName;
+ this.list = list != null ? list : new ArrayList<>();
+ this.clazz = clazz;
+ this.title = title != null ? title : "";
+ }
+
+ public String getSheetName()
+ {
+ return sheetName;
+ }
+
+ public List getList()
+ {
+ return list;
+ }
+
+ public Class getClazz()
+ {
+ return clazz;
+ }
+
+ public String getTitle()
+ {
+ return title;
+ }
+
+ public void setSheetName(String sheetName)
+ {
+ this.sheetName = sheetName;
+ }
+
+ public void setList(List list)
+ {
+ this.list = list;
+ }
+
+ public void setClazz(Class clazz)
+ {
+ this.clazz = clazz;
+ }
+
+ public void setTitle(String title)
+ {
+ this.title = title;
+ }
+}
diff --git a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/poi/ExcelUtil.java b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/poi/ExcelUtil.java
index b232ad3..b12c71f 100644
--- a/cmvr-iot-common/src/main/java/com/cmvr/common/utils/poi/ExcelUtil.java
+++ b/cmvr-iot-common/src/main/java/com/cmvr/common/utils/poi/ExcelUtil.java
@@ -23,7 +23,7 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
-import javax.servlet.http.HttpServletResponse;
+import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
@@ -89,12 +89,14 @@ import com.cmvr.common.utils.reflect.ReflectUtils;
/**
* Excel相关处理
*
- * @author cmvr-iot
+ * @author ruoyi
*/
public class ExcelUtil
{
private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
+ public static final String SEPARATOR = ",";
+
public static final String FORMULA_REGEX_STR = "=|-|\\+|@";
public static final String[] FORMULA_STR = { "=", "-", "+", "@" };
@@ -104,6 +106,11 @@ public class ExcelUtil
*/
public Map sysDictMap = new HashMap();
+ /**
+ * 单元格样式缓存
+ */
+ private Map cellStyleCache = new HashMap();
+
/**
* Excel sheet最大行数,默认65536
*/
@@ -172,23 +179,18 @@ public class ExcelUtil
/**
* 对象的子列表方法
*/
- private Method subMethod;
+ private Map subMethods;
/**
* 对象的子列表属性
*/
- private List subFields;
+ private Map> subFieldsMap;
/**
* 统计列表
*/
private Map statistics = new HashMap();
- /**
- * 数字格式
- */
- private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
-
/**
* 实体对象
*/
@@ -255,7 +257,10 @@ public class ExcelUtil
int titleLastCol = this.fields.size() - 1;
if (isSubList())
{
- titleLastCol = titleLastCol + subFields.size() - 1;
+ for (List currentSubFields : subFieldsMap.values())
+ {
+ titleLastCol = titleLastCol + currentSubFields.size() - 1;
+ }
}
Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0);
titleRow.setHeightInPoints(30);
@@ -275,16 +280,17 @@ public class ExcelUtil
{
Row subRow = sheet.createRow(rownum);
int column = 0;
- int subFieldSize = subFields != null ? subFields.size() : 0;
for (Object[] objects : fields)
{
Field field = (Field) objects[0];
Excel attr = (Excel) objects[1];
+ CellStyle cellStyle = styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()));
if (Collection.class.isAssignableFrom(field.getType()))
{
Cell cell = subRow.createCell(column);
cell.setCellValue(attr.name());
- cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
+ cell.setCellStyle(cellStyle);
+ int subFieldSize = subFieldsMap != null ? subFieldsMap.get(field.getName()).size() : 0;
if (subFieldSize > 1)
{
CellRangeAddress cellAddress = new CellRangeAddress(rownum, rownum, column, column + subFieldSize - 1);
@@ -296,7 +302,7 @@ public class ExcelUtil
{
Cell cell = subRow.createCell(column++);
cell.setCellValue(attr.name());
- cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
+ cell.setCellStyle(cellStyle);
}
}
rownum++;
@@ -360,7 +366,7 @@ public class ExcelUtil
throw new IOException("文件sheet不存在");
}
boolean isXSSFWorkbook = !(wb instanceof HSSFWorkbook);
- Map pictures;
+ Map> pictures = null;
if (isXSSFWorkbook)
{
pictures = getSheetPictures07((XSSFSheet) sheet, (XSSFWorkbook) wb);
@@ -377,7 +383,11 @@ public class ExcelUtil
Map cellMap = new HashMap();
// 获取表头
Row heard = sheet.getRow(titleNum);
- for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++)
+ if (heard == null)
+ {
+ throw new UtilException("文件标题行为空,请检查Excel文件格式");
+ }
+ for (int i = 0; i < heard.getLastCellNum(); i++)
{
Cell cell = heard.getCell(i);
if (StringUtils.isNotNull(cell))
@@ -385,10 +395,6 @@ public class ExcelUtil
String value = this.getCellValue(heard, i).toString();
cellMap.put(value, i);
}
- else
- {
- cellMap.put(null, i);
- }
}
// 有数据时才处理 得到类的所有field.
List