diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java index b74f0c3a2..bab0b19c5 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/BeanUtil.java @@ -77,11 +77,14 @@ public class BeanUtil { * @see #hasPublicField(Class) */ public static boolean isReadableBean(final Class> clazz) { + if(null == clazz){ + return false; + } return hasGetter(clazz) || hasPublicField(clazz); } /** - * 判断是否为Bean对象,判定方法是: + * 判断是否为可写Bean对象,判定方法是: * *
* 1、是否存在只有一个参数的setXXX方法
@@ -93,7 +96,10 @@ public class BeanUtil {
* @see #hasSetter(Class)
* @see #hasPublicField(Class)
*/
- public static boolean isBean(final Class> clazz) {
+ public static boolean isWritableBean(final Class> clazz) {
+ if(null == clazz){
+ return false;
+ }
return hasSetter(clazz) || hasPublicField(clazz);
}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/bean/copier/MapToBeanCopier.java b/hutool-core/src/main/java/org/dromara/hutool/core/bean/copier/MapToBeanCopier.java
index ce1243f94..e50193f46 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/bean/copier/MapToBeanCopier.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/bean/copier/MapToBeanCopier.java
@@ -15,6 +15,7 @@ package org.dromara.hutool.core.bean.copier;
import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.bean.PropDesc;
import org.dromara.hutool.core.lang.Assert;
+import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.core.lang.mutable.MutableEntry;
import org.dromara.hutool.core.map.CaseInsensitiveMap;
import org.dromara.hutool.core.map.MapWrapper;
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java
index 5c4f4358d..dc92bc867 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/collection/CollUtil.java
@@ -15,6 +15,7 @@ package org.dromara.hutool.core.collection;
import org.dromara.hutool.core.array.ArrayUtil;
import org.dromara.hutool.core.bean.BeanUtil;
import org.dromara.hutool.core.codec.hash.Hash32;
+import org.dromara.hutool.core.collection.iter.ArrayIter;
import org.dromara.hutool.core.collection.iter.IterUtil;
import org.dromara.hutool.core.collection.iter.IteratorEnumeration;
import org.dromara.hutool.core.collection.queue.BoundedPriorityQueue;
@@ -1553,6 +1554,10 @@ public class CollUtil {
// String按照逗号分隔的列表对待
final String arrayStr = StrUtil.unWrap((CharSequence) value, '[', ']');
iter = SplitUtil.splitTrim(arrayStr, StrUtil.COMMA).iterator();
+ } else if(value instanceof Map && BeanUtil.isWritableBean(TypeUtil.getClass(elementType))){
+ //https://github.com/dromara/hutool/issues/3139
+ // 如果值为Map,而目标为一个Bean,则Map应整体转换为Bean,而非拆分成Entry转换
+ iter = new ArrayIter<>(new Object[]{value});
} else {
iter = IterUtil.getIter(value);
}
@@ -2032,7 +2037,7 @@ public class CollUtil {
@Override
public int hash32(final T t) {
- if (null == t || !BeanUtil.isBean(t.getClass())) {
+ if (null == t || !BeanUtil.isWritableBean(t.getClass())) {
// 非Bean放在同一子分组中
return 0;
}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/CompositeConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/CompositeConverter.java
index 73689c5b4..e95d3251e 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/CompositeConverter.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/CompositeConverter.java
@@ -148,7 +148,7 @@ public class CompositeConverter extends RegisterConverter {
}
// 尝试转Bean
- if (BeanUtil.isBean(rowType)) {
+ if (BeanUtil.isWritableBean(rowType)) {
return (T) BeanConverter.INSTANCE.convert(type, value);
}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/BeanConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/BeanConverter.java
index 65112f1a8..db9b1d4f9 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/BeanConverter.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/BeanConverter.java
@@ -23,7 +23,6 @@ import org.dromara.hutool.core.lang.Assert;
import org.dromara.hutool.core.map.MapProxy;
import org.dromara.hutool.core.reflect.ConstructorUtil;
import org.dromara.hutool.core.reflect.TypeUtil;
-import org.dromara.hutool.core.reflect.kotlin.KClassUtil;
import java.io.Serializable;
import java.lang.reflect.Type;
@@ -87,7 +86,7 @@ public class BeanConverter implements Converter, Serializable {
private Object convertInternal(final Type targetType, final Class> targetClass, final Object value) {
if (value instanceof Map ||
value instanceof ValueProvider ||
- BeanUtil.isBean(value.getClass())) {
+ BeanUtil.isWritableBean(value.getClass())) {
if (value instanceof Map && targetClass.isInterface()) {
// 将Map动态代理为Bean
return MapProxy.of((Map, ?>) value).toProxyBean(targetClass);
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/EntryConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/EntryConverter.java
index 68bebf473..a0799818f 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/EntryConverter.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/EntryConverter.java
@@ -77,7 +77,7 @@ public class EntryConverter implements Converter {
} else if (value instanceof CharSequence) {
final CharSequence str = (CharSequence) value;
map = strToMap(str);
- } else if (BeanUtil.isBean(value.getClass())) {
+ } else if (BeanUtil.isWritableBean(value.getClass())) {
map = BeanUtil.beanToMap(value);
}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/KBeanConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/KBeanConverter.java
index 1ca2c1c99..bafd2ca6a 100755
--- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/KBeanConverter.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/KBeanConverter.java
@@ -69,7 +69,7 @@ public class KBeanConverter implements Converter, Serializable {
valueProvider = (ValueProvider) value;
} else if(value instanceof Map){
valueProvider = new MapValueProvider((Map) value);
- } else if(BeanUtil.isBean(value.getClass())){
+ } else if(BeanUtil.isWritableBean(value.getClass())){
valueProvider = new BeanValueProvider(value);
}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/MapConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/MapConverter.java
index 690cf1a39..0867852ae 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/MapConverter.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/MapConverter.java
@@ -84,7 +84,7 @@ public class MapConverter implements Converter, Serializable {
map = MapUtil.createMap(TypeUtil.getClass(targetType), LinkedHashMap::new);
convertMapToMap(keyType, valueType, (Map) value, map);
- } else if (BeanUtil.isBean(value.getClass())) {
+ } else if (BeanUtil.isWritableBean(value.getClass())) {
map = BeanUtil.beanToMap(value);
// 二次转换,转换键值类型
map = convert(targetType, keyType, valueType, map);
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/RecordConverter.java b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/RecordConverter.java
index 06521d465..bd9db80ca 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/RecordConverter.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/convert/impl/RecordConverter.java
@@ -46,7 +46,7 @@ public class RecordConverter extends AbstractConverter {
valueProvider = (ValueProvider) value;
} else if (value instanceof Map) {
valueProvider = new MapValueProvider((Map) value);
- } else if (BeanUtil.isBean(value.getClass())) {
+ } else if (BeanUtil.isWritableBean(value.getClass())) {
valueProvider = new BeanValueProvider(value);
}
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/io/file/FileUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/io/file/FileUtil.java
index 81f2791e5..04d7356cc 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/io/file/FileUtil.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/io/file/FileUtil.java
@@ -23,6 +23,7 @@ import org.dromara.hutool.core.io.resource.ResourceUtil;
import org.dromara.hutool.core.io.stream.BOMInputStream;
import org.dromara.hutool.core.io.unit.DataSizeUtil;
import org.dromara.hutool.core.lang.Assert;
+import org.dromara.hutool.core.lang.Console;
import org.dromara.hutool.core.net.url.URLUtil;
import org.dromara.hutool.core.reflect.ClassUtil;
import org.dromara.hutool.core.regex.ReUtil;
@@ -142,6 +143,7 @@ public class FileUtil extends PathUtil {
}
// region ----- loop and walk
+
/**
* 递归遍历目录以及子目录中的所有文件
* 如果提供file为文件,直接返回过滤结果
@@ -273,6 +275,7 @@ public class FileUtil extends PathUtil {
// endregion
// region ----- file and newFile
+
/**
* 创建File对象,相当于调用new File(),不做任何处理
*
@@ -419,6 +422,7 @@ public class FileUtil extends PathUtil {
}
// region ----- exists
+
/**
* 判断文件是否存在,如果path为null,则返回false
*
@@ -468,6 +472,7 @@ public class FileUtil extends PathUtil {
// endregion
// region ----- lastModifiedTime
+
/**
* 指定文件最后修改时间
*
@@ -590,6 +595,7 @@ public class FileUtil extends PathUtil {
}
// region ----- touch
+
/**
* 创建文件及其父目录,如果这个文件存在,直接返回这个文件
* 此方法不对File对象类型做判断,如果File不存在,无法判断其类型
@@ -803,6 +809,7 @@ public class FileUtil extends PathUtil {
}
// region ----- createTempFile
+
/**
* 创建临时文件
* 创建后的文件名为 prefix[Random].tmp
@@ -939,10 +946,10 @@ public class FileUtil extends PathUtil {
Assert.notNull(src, "Src file must be not null!");
Assert.notNull(target, "target file must be not null!");
return copy(
- src.toPath(),
- target.toPath(),
- isOverride ? new CopyOption[]{StandardCopyOption.REPLACE_EXISTING} : new CopyOption[]{})
- .toFile();
+ src.toPath(),
+ target.toPath(),
+ isOverride ? new CopyOption[]{StandardCopyOption.REPLACE_EXISTING} : new CopyOption[]{})
+ .toFile();
}
/**
@@ -965,10 +972,10 @@ public class FileUtil extends PathUtil {
Assert.notNull(src, "Src file must be not null!");
Assert.notNull(target, "target file must be not null!");
return copyContent(
- src.toPath(),
- target.toPath(),
- isOverride ? new CopyOption[]{StandardCopyOption.REPLACE_EXISTING} : new CopyOption[]{})
- .toFile();
+ src.toPath(),
+ target.toPath(),
+ isOverride ? new CopyOption[]{StandardCopyOption.REPLACE_EXISTING} : new CopyOption[]{})
+ .toFile();
}
/**
@@ -1210,8 +1217,8 @@ public class FileUtil extends PathUtil {
if (!file1.exists() || !file2.exists()) {
// 两个文件都不存在判断其路径是否相同, 对于一个存在一个不存在的情况,一定不相同
return !file1.exists()//
- && !file2.exists()//
- && pathEquals(file1, file2);
+ && !file2.exists()//
+ && pathEquals(file1, file2);
}
return equals(file1.toPath(), file2.toPath());
}
@@ -1501,6 +1508,7 @@ public class FileUtil extends PathUtil {
}
// region ----- in
+
/**
* 获得输入流
*
@@ -1598,6 +1606,7 @@ public class FileUtil extends PathUtil {
// endregion
// region ----- read
+
/**
* 读取文件所有数据
* 文件的长度不能超过Integer.MAX_VALUE
@@ -2101,6 +2110,7 @@ public class FileUtil extends PathUtil {
// endregion
// region ----- write and append
+
/**
* 将String写入文件,覆盖模式,字符集为UTF-8
*
@@ -2638,13 +2648,25 @@ public class FileUtil extends PathUtil {
*/
public static File checkSlip(final File parentFile, final File file) throws IllegalArgumentException {
if (null != parentFile && null != file) {
- if(!file.toPath().startsWith(parentFile.toPath())){
+ if (!startsWith(parentFile, file)) {
throw new IllegalArgumentException("New file is outside of the parent dir: " + file.getName());
}
}
return file;
}
+ /**
+ * 检查父文件是否为文件真正的父目录
+ *
+ * @param parentFile 父目录
+ * @param file 文件
+ * @return 是否为文件真正的父目录
+ */
+ public static boolean startsWith(final File parentFile, final File file) {
+ return PathUtil.toAbsNormal(parentFile.toPath())
+ .startsWith(PathUtil.toAbsNormal(file.toPath()));
+ }
+
/**
* 根据文件扩展名获得MimeType
*
@@ -2664,7 +2686,7 @@ public class FileUtil extends PathUtil {
* @since 4.1.15
*/
public static String getMimeType(final String filePath) {
- if(StrUtil.isBlank(filePath)){
+ if (StrUtil.isBlank(filePath)) {
return null;
}
@@ -2790,8 +2812,8 @@ public class FileUtil extends PathUtil {
// 替换Windows路径分隔符为Linux路径分隔符,便于统一处理
fileName = fileName.replace(CharUtil.BACKSLASH, CharUtil.SLASH);
if (!isWindows()
- // 检查文件名中是否包含"/",不考虑以"/"结尾的情况
- && fileName.lastIndexOf(CharUtil.SLASH, fileName.length() - 2) > 0) {
+ // 检查文件名中是否包含"/",不考虑以"/"结尾的情况
+ && fileName.lastIndexOf(CharUtil.SLASH, fileName.length() - 2) > 0) {
// 在Linux下多层目录创建存在问题,/会被当成文件名的一部分,此处做处理
// 使用/拆分路径(zip中无\),级联创建父目录
final List pathParts = SplitUtil.split(fileName, StrUtil.SLASH, false, true);
diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/io/file/PathUtil.java b/hutool-core/src/main/java/org/dromara/hutool/core/io/file/PathUtil.java
index 684307910..c9791a989 100644
--- a/hutool-core/src/main/java/org/dromara/hutool/core/io/file/PathUtil.java
+++ b/hutool-core/src/main/java/org/dromara/hutool/core/io/file/PathUtil.java
@@ -32,6 +32,7 @@ import java.util.List;
* @since 5.4.1
*/
public class PathUtil {
+
/**
* 目录是否为空
*
@@ -559,10 +560,30 @@ public class PathUtil {
* @since 5.5.5
*/
public static Path toAbsNormal(final Path path) {
- Assert.notNull(path);
+ if (null == path) {
+ return null;
+ }
return path.toAbsolutePath().normalize();
}
+ /**
+ * 获取实际路径,路径文件必须存在
+ *
+ * @param path 路径
+ * @return 实际路径
+ * @throws IORuntimeException IO异常,如文件不存在等
+ */
+ public static Path toRealPath(Path path) throws IORuntimeException{
+ if (null != path) {
+ try {
+ path = path.toRealPath();
+ } catch (final IOException e) {
+ throw new IORuntimeException(e);
+ }
+ }
+ return path;
+ }
+
/**
* 获得文件的MimeType
*
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java
index f4a35dd40..7f718bea5 100644
--- a/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/bean/BeanUtilTest.java
@@ -39,7 +39,7 @@ public class BeanUtilTest {
public void isBeanTest() {
// HashMap不包含setXXX方法,不是bean
- final boolean isBean = BeanUtil.isBean(HashMap.class);
+ final boolean isBean = BeanUtil.isWritableBean(HashMap.class);
Assertions.assertFalse(isBean);
}
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/io/FileUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/io/FileUtilTest.java
index 86ff80dc8..5d4649139 100644
--- a/hutool-core/src/test/java/org/dromara/hutool/core/io/FileUtilTest.java
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/io/FileUtilTest.java
@@ -24,15 +24,16 @@ import java.util.List;
public class FileUtilTest {
@Test
- public void fileTest() {
+ void fileTest1() {
+ final File file = FileUtil.file("d:/aaa", "bbb");
+ Assertions.assertNotNull(file);
+ }
+
+ @Test
+ public void fileTest2() {
Assertions.assertThrows(IllegalArgumentException.class, ()->{
- final File file = FileUtil.file("d:/aaa", "bbb");
- Assertions.assertNotNull(file);
-
// 构建目录中出现非子目录抛出异常
- FileUtil.file(file, "../ccc");
-
- FileUtil.file("E:/");
+ FileUtil.file("d:/aaa/bbb", "../ccc");
});
}
diff --git a/hutool-core/src/test/java/org/dromara/hutool/core/util/XmlUtilTest.java b/hutool-core/src/test/java/org/dromara/hutool/core/util/XmlUtilTest.java
index 27f0f2518..cb3ea50dd 100644
--- a/hutool-core/src/test/java/org/dromara/hutool/core/util/XmlUtilTest.java
+++ b/hutool-core/src/test/java/org/dromara/hutool/core/util/XmlUtilTest.java
@@ -32,6 +32,7 @@ import org.xml.sax.helpers.DefaultHandler;
import javax.xml.xpath.XPathConstants;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -380,4 +381,29 @@ public class XmlUtilTest {
private String age;
private String email;
}
+
+ @Test
+ public void issue3139Test() {
+ final String xml = "\n" +
+ " \n" +
+ " 1\n" +
+ " str
\n" +
+ " \n" +
+ " ";
+
+ final R r = XmlUtil.xmlToBean(XmlUtil.parseXml(xml), R.class);
+ Assertions.assertEquals("1", r.getC().get(0).getS());
+ Assertions.assertEquals("str", r.getC().get(0).getP());
+ }
+
+ @Data
+ static class C {
+ String s;
+ String p;
+ }
+
+ @Data
+ static class R {
+ List c;
+ }
}
diff --git a/hutool-json/src/main/java/org/dromara/hutool/json/convert/JSONConverter.java b/hutool-json/src/main/java/org/dromara/hutool/json/convert/JSONConverter.java
index aaf723107..44e8a0866 100644
--- a/hutool-json/src/main/java/org/dromara/hutool/json/convert/JSONConverter.java
+++ b/hutool-json/src/main/java/org/dromara/hutool/json/convert/JSONConverter.java
@@ -211,7 +211,7 @@ public class JSONConverter implements Converter {
}
// 尝试转Bean
- if (BeanUtil.isBean(rawType)) {
+ if (BeanUtil.isWritableBean(rawType)) {
// issue#I5WDP0 对于Kotlin对象,由于参数可能非空限制,导致无法创建一个默认的对象再赋值
if(KClassUtil.isKotlinClass(rawType) && json instanceof JSONGetter){
return KClassUtil.newInstance(rawType, new JSONGetterValueProvider<>((JSONGetter)json));
diff --git a/hutool-json/src/test/java/org/dromara/hutool/json/Issue3139Test.java b/hutool-json/src/test/java/org/dromara/hutool/json/Issue3139Test.java
new file mode 100755
index 000000000..1e59a597a
--- /dev/null
+++ b/hutool-json/src/test/java/org/dromara/hutool/json/Issue3139Test.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2023 looly(loolly@aliyun.com)
+ * Hutool is licensed under Mulan PSL v2.
+ * You can use this software according to the terms and conditions of the Mulan PSL v2.
+ * You may obtain a copy of Mulan PSL v2 at:
+ * http://license.coscl.org.cn/MulanPSL2
+ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
+ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
+ * See the Mulan PSL v2 for more details.
+ */
+
+package org.dromara.hutool.json;
+
+import lombok.Data;
+import org.dromara.hutool.core.lang.Console;
+import org.dromara.hutool.core.util.XmlUtil;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+public class Issue3139Test {
+ @Test
+ public void toBeanTest() {
+ final String xml = "\n" +
+ " \n" +
+ " 1\n" +
+ " str
\n" +
+ " \n" +
+ " ";
+
+ final JSONObject jsonObject = XmlUtil.xmlToBean(XmlUtil.parseXml(xml).getDocumentElement(), JSONObject.class);
+ final R bean = jsonObject.toBean(R.class);
+ Assertions.assertNotNull(bean);
+
+ final List c = bean.getC();
+ Assertions.assertEquals(1, c.size());
+ Assertions.assertEquals("1", c.get(0).getS());
+ Assertions.assertEquals("str", c.get(0).getP());
+ }
+
+ @Data
+ static class C {
+ String s;
+ String p;
+ }
+
+ @Data
+ static class R {
+ List c;
+ }
+}
diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelWriter.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelWriter.java
index 6105f5b6e..34c69f68f 100644
--- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelWriter.java
+++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelWriter.java
@@ -991,7 +991,7 @@ public class ExcelWriter extends ExcelBase {
} else if (rowBean instanceof Hyperlink) {
// Hyperlink当成一个值
return writeRow(ListUtil.of(rowBean), isWriteKeyAsHead);
- } else if (BeanUtil.isBean(rowBean.getClass())) {
+ } else if (BeanUtil.isWritableBean(rowBean.getClass())) {
if (MapUtil.isEmpty(this.headerAlias)) {
rowMap = BeanUtil.beanToMap(rowBean, new LinkedHashMap<>(), false, false);
} else {
diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/word/TableUtil.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/word/TableUtil.java
index 602939075..b2448d790 100644
--- a/hutool-poi/src/main/java/org/dromara/hutool/poi/word/TableUtil.java
+++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/word/TableUtil.java
@@ -102,7 +102,7 @@ public class TableUtil {
final Map rowMap;
if(rowBean instanceof Map) {
rowMap = (Map) rowBean;
- } else if (BeanUtil.isBean(rowBean.getClass())) {
+ } else if (BeanUtil.isWritableBean(rowBean.getClass())) {
rowMap = BeanUtil.beanToMap(rowBean, new LinkedHashMap<>(), false, false);
} else {
// 其它转为字符串默认输出