diff --git a/CHANGELOG.md b/CHANGELOG.md index 381188e2a..8073a66c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ * 【core 】 修正DateUtil.betweenXXX注释错误(issue#I28XGW@Gitee) * 【core 】 增加NioUtil * 【core 】 增加GanymedUtil +* 【poi 】 增加OFD支持,OfdWriter ### Bug修复 * 【cache 】 修复Cache中get重复misCount计数问题(issue#1281@Github) @@ -32,6 +33,7 @@ * 【poi 】 修复xdr:row标签导致的问题(issue#1297@Github) * 【core 】 修复FileUtil.loopFiles使用FileFilter无效问题(issue#I28V48@Gitee) * 【extra 】 修复JschUtil.execByShell返回空的问题(issue#1067@Github) +* 【poi 】 修复特殊的excel使用sax读取时未读到值的问题(issue#1303@Github) ------------------------------------------------------------------------------------------------------------- @@ -72,7 +74,7 @@ * 【core 】 修复HexUtil.format问题(issue#I268XT@Gitee) * 【core 】 修复ZipUtil判断压缩文件是否位于压缩目录内的逻辑有误的问题(issue#1251@Github) * 【json 】 修复JSONObject.accumulate问题 -* 【core 】 修复部分xlsx文件sax方式解析空指针问题(issue#1265@Github) +* 【poi 】 修复部分xlsx文件sax方式解析空指针问题(issue#1265@Github) * 【core 】 修复PatternPool中邮编的正则(issue#1274@Github) ------------------------------------------------------------------------------------------------------------- diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/BeanUtil.java b/hutool-core/src/main/java/cn/hutool/core/bean/BeanUtil.java index a87de2f4f..33fafbd4d 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/BeanUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/BeanUtil.java @@ -745,11 +745,11 @@ public class BeanUtil { } /** - * 判断Bean是否为非空对象,非空对象表示本身不为null或者含有非null属性的对象 + * 判断Bean是否为非空对象,非空对象表示本身不为{@code null}或者含有非{@code null}属性的对象 * * @param bean Bean对象 * @param ignoreFiledNames 忽略检查的字段名 - * @return 是否为空,true - 空 / false - 非空 + * @return 是否为空,{@code true} - 空 / {@code false} - 非空 * @since 5.0.7 */ public static boolean isNotEmpty(Object bean, String... ignoreFiledNames) { @@ -757,12 +757,12 @@ public class BeanUtil { } /** - * 判断Bean是否为空对象,空对象表示本身为null或者所有属性都为null
+ * 判断Bean是否为空对象,空对象表示本身为{@code null}或者所有属性都为{@code null}
* 此方法不判断static属性 * * @param bean Bean对象 * @param ignoreFiledNames 忽略检查的字段名 - * @return 是否为空,true - 空 / false - 非空 + * @return 是否为空,{@code true} - 空 / {@code false} - 非空 * @since 4.1.10 */ public static boolean isEmpty(Object bean, String... ignoreFiledNames) { @@ -781,12 +781,12 @@ public class BeanUtil { } /** - * 判断Bean是否包含值为null的属性
- * 对象本身为null也返回true + * 判断Bean是否包含值为{@code null}的属性
+ * 对象本身为{@code null}也返回true * * @param bean Bean对象 * @param ignoreFiledNames 忽略检查的字段名 - * @return 是否包含值为null的属性,true - 包含 / false - 不包含 + * @return 是否包含值为null的属性,{@code true} - 包含 / {@code false} - 不包含 * @since 4.1.10 */ public static boolean hasNullField(Object bean, String... ignoreFiledNames) { diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java index 48f116ea1..ec6606321 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java @@ -140,7 +140,7 @@ public class ReflectUtil { } /** - * 查找指定类中的指定name的字段(包括非public字段),也包括父类和Object类的字段, 字段不存在则返回null + * 查找指定类中的指定name的字段(包括非public字段),也包括父类和Object类的字段, 字段不存在则返回{@code null} * * @param beanClass 被查找字段的类,不能为null * @param name 字段名 @@ -422,7 +422,7 @@ public class ReflectUtil { } /** - * 查找指定Public方法 如果找不到对应的方法或方法不为public的则返回null + * 查找指定Public方法 如果找不到对应的方法或方法不为public的则返回{@code null} * * @param clazz 类 * @param methodName 方法名 @@ -442,7 +442,7 @@ public class ReflectUtil { * 查找指定对象中的所有方法(包括非public方法),也包括父对象和Object类的方法 * *

- * 此方法为精准获取方法名,即方法名和参数数量和类型必须一致,否则返回null。 + * 此方法为精准获取方法名,即方法名和参数数量和类型必须一致,否则返回{@code null}。 *

* * @param obj 被查找的对象,如果为{@code null}返回{@code null} @@ -459,10 +459,10 @@ public class ReflectUtil { } /** - * 忽略大小写查找指定方法,如果找不到对应的方法则返回null + * 忽略大小写查找指定方法,如果找不到对应的方法则返回{@code null} * *

- * 此方法为精准获取方法名,即方法名和参数数量和类型必须一致,否则返回null。 + * 此方法为精准获取方法名,即方法名和参数数量和类型必须一致,否则返回{@code null}。 *

* * @param clazz 类,如果为{@code null}返回{@code null} @@ -477,10 +477,10 @@ public class ReflectUtil { } /** - * 查找指定方法 如果找不到对应的方法则返回null + * 查找指定方法 如果找不到对应的方法则返回{@code null} * *

- * 此方法为精准获取方法名,即方法名和参数数量和类型必须一致,否则返回null。 + * 此方法为精准获取方法名,即方法名和参数数量和类型必须一致,否则返回{@code null}。 *

* * @param clazz 类,如果为{@code null}返回{@code null} @@ -494,10 +494,10 @@ public class ReflectUtil { } /** - * 查找指定方法 如果找不到对应的方法则返回null + * 查找指定方法 如果找不到对应的方法则返回{@code null} * *

- * 此方法为精准获取方法名,即方法名和参数数量和类型必须一致,否则返回null。 + * 此方法为精准获取方法名,即方法名和参数数量和类型必须一致,否则返回{@code null}。 *

* * @param clazz 类,如果为{@code null}返回{@code null} @@ -527,7 +527,7 @@ public class ReflectUtil { } /** - * 按照方法名查找指定方法名的方法,只返回匹配到的第一个方法,如果找不到对应的方法则返回null + * 按照方法名查找指定方法名的方法,只返回匹配到的第一个方法,如果找不到对应的方法则返回{@code null} * *

* 此方法只检查方法名是否一致,并不检查参数的一致性。 @@ -544,7 +544,7 @@ public class ReflectUtil { } /** - * 按照方法名查找指定方法名的方法,只返回匹配到的第一个方法,如果找不到对应的方法则返回null + * 按照方法名查找指定方法名的方法,只返回匹配到的第一个方法,如果找不到对应的方法则返回{@code null} * *

* 此方法只检查方法名是否一致(忽略大小写),并不检查参数的一致性。 @@ -561,7 +561,7 @@ public class ReflectUtil { } /** - * 按照方法名查找指定方法名的方法,只返回匹配到的第一个方法,如果找不到对应的方法则返回null + * 按照方法名查找指定方法名的方法,只返回匹配到的第一个方法,如果找不到对应的方法则返回{@code null} * *

* 此方法只检查方法名是否一致,并不检查参数的一致性。 @@ -842,7 +842,7 @@ public class ReflectUtil { * * * @param 返回对象类型 - * @param obj 对象,如果执行静态方法,此值为null + * @param obj 对象,如果执行静态方法,此值为{@code null} * @param method 方法(对象方法或static方法都可) * @param args 参数对象 * @return 结果 @@ -878,7 +878,7 @@ public class ReflectUtil { * * * @param 返回对象类型 - * @param obj 对象,如果执行静态方法,此值为null + * @param obj 对象,如果执行静态方法,此值为{@code null} * @param method 方法(对象方法或static方法都可) * @param args 参数对象 * @return 结果 diff --git a/hutool-poi/pom.xml b/hutool-poi/pom.xml index 8e67a85d7..d82e04e0e 100644 --- a/hutool-poi/pom.xml +++ b/hutool-poi/pom.xml @@ -18,7 +18,6 @@ 4.1.2 - 2.12.0 @@ -42,9 +41,9 @@ true - xerces - xercesImpl - ${xerces.version} + org.ofdrw + ofdrw-full + 1.7.2 compile true diff --git a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/SheetDataSaxHandler.java b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/SheetDataSaxHandler.java index b6d63ee7b..c703691e9 100644 --- a/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/SheetDataSaxHandler.java +++ b/hutool-poi/src/main/java/cn/hutool/poi/excel/sax/SheetDataSaxHandler.java @@ -137,9 +137,6 @@ public class SheetDataSaxHandler extends DefaultHandler { // 其它标签忽略 } - /** - * s标签结束的回调处理方法 - */ @Override public void characters(char[] ch, int start, int length) { if (false == this.isInSheetData) { @@ -159,8 +156,11 @@ public class SheetDataSaxHandler extends DefaultHandler { lastFormula.append(ch, start, length); break; } + } else{ + // 按理说内容应该为"内容",但是某些特别的XML内容不在v或f标签中,此处做一些兼容 + // issue#1303@Github + lastContent.append(ch, start, length); } - // 其它标签忽略 } // --------------------------------------------------------------------------------------- Private method start diff --git a/hutool-poi/src/main/java/cn/hutool/poi/ofd/OfdWriter.java b/hutool-poi/src/main/java/cn/hutool/poi/ofd/OfdWriter.java new file mode 100644 index 000000000..cd264faaf --- /dev/null +++ b/hutool-poi/src/main/java/cn/hutool/poi/ofd/OfdWriter.java @@ -0,0 +1,85 @@ +package cn.hutool.poi.ofd; + +import cn.hutool.core.io.IoUtil; +import org.ofdrw.font.Font; +import org.ofdrw.layout.OFDDoc; +import org.ofdrw.layout.element.Div; +import org.ofdrw.layout.element.Paragraph; + +import java.io.Closeable; +import java.io.File; +import java.io.OutputStream; +import java.io.Serializable; +import java.nio.file.Path; + +/** + * OFD文件生成器 + * + * @author looly + * @since 5.5.3 + */ +public class OfdWriter implements Serializable, Closeable { + private static final long serialVersionUID = 1L; + + private final OFDDoc doc; + + /** + * 构造 + * + * @param file 生成的文件 + */ + public OfdWriter(File file){ + this(file.toPath()); + } + + /** + * 构造 + * + * @param file 生成的文件 + */ + public OfdWriter(Path file){ + this.doc = new OFDDoc(file); + } + + /** + * 构造 + * + * @param out 需要输出的流 + */ + public OfdWriter(OutputStream out){ + this.doc = new OFDDoc(out); + } + + /** + * 增加文本内容 + * + * @param font 字体 + * @param texts 文本 + * @return this + */ + public OfdWriter addText(Font font, String... texts){ + final Paragraph paragraph = new Paragraph(); + if(null != font){ + paragraph.setDefaultFont(font); + } + for (String text : texts) { + paragraph.add(text); + } + return add(paragraph); + } + + /** + * 增加节点, + * @param div 节点,可以是段落、Canvas、Img或者填充 + * @return this + */ + public OfdWriter add(Div div){ + this.doc.add(div); + return this; + } + + @Override + public void close() { + IoUtil.close(this.doc); + } +} diff --git a/hutool-poi/src/main/java/cn/hutool/poi/ofd/package-info.java b/hutool-poi/src/main/java/cn/hutool/poi/ofd/package-info.java new file mode 100644 index 000000000..e6e362122 --- /dev/null +++ b/hutool-poi/src/main/java/cn/hutool/poi/ofd/package-info.java @@ -0,0 +1,6 @@ +/** + * 开放版式文档(Open Fixed-layout Document )封装,基于ofdrw(https://gitee.com/Trisia/ofdrw) + * + * @author looly + */ +package cn.hutool.poi.ofd; \ No newline at end of file diff --git a/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelSaxReadTest.java b/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelSaxReadTest.java index 4b07c60af..4d5ef39f8 100644 --- a/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelSaxReadTest.java +++ b/hutool-poi/src/test/java/cn/hutool/poi/excel/ExcelSaxReadTest.java @@ -64,7 +64,7 @@ public class ExcelSaxReadTest { @Test @Ignore public void readBySaxTest2() { - ExcelUtil.readBySax("d:/test/default.xlsx", -1, (sheetIndex, rowIndex, rowList) -> Console.log(rowList)); + ExcelUtil.readBySax("d:/test/456789.xlsx", "0", (sheetIndex, rowIndex, rowList) -> Console.log(rowList)); } private RowHandler createRowHandler() { @@ -140,9 +140,7 @@ public class ExcelSaxReadTest { public void dateReadXlsTest() { List rows = new ArrayList<>(); ExcelUtil.readBySax("data_for_sax_test.xls", 0, - (i, i1, list) ->{ - rows.add(StrUtil.toString(list.get(0))); - } + (i, i1, list) -> rows.add(StrUtil.toString(list.get(0))) ); Assert.assertEquals("2020-10-09 00:00:00", rows.get(1)); @@ -179,8 +177,7 @@ public class ExcelSaxReadTest { @Test @Ignore public void readXlsmTest(){ - ExcelUtil.readBySax("d:/test/WhiteListTemplate.xlsm", -1, (sheetIndex, rowIndex, rowlist) -> { - Console.log("[{}] [{}] {}", sheetIndex, rowIndex, rowlist); - }); + ExcelUtil.readBySax("d:/test/WhiteListTemplate.xlsm", -1, + (sheetIndex, rowIndex, rowlist) -> Console.log("[{}] [{}] {}", sheetIndex, rowIndex, rowlist)); } } diff --git a/hutool-poi/src/test/java/cn/hutool/poi/ofd/OfdWriterTest.java b/hutool-poi/src/test/java/cn/hutool/poi/ofd/OfdWriterTest.java new file mode 100644 index 000000000..da24b5b8a --- /dev/null +++ b/hutool-poi/src/test/java/cn/hutool/poi/ofd/OfdWriterTest.java @@ -0,0 +1,16 @@ +package cn.hutool.poi.ofd; + +import cn.hutool.core.io.FileUtil; +import org.junit.Ignore; +import org.junit.Test; + +public class OfdWriterTest { + + @Test + @Ignore + public void writeTest(){ + final OfdWriter ofdWriter = new OfdWriter(FileUtil.file("d:/test/test.ofd")); + ofdWriter.addText(null, "测试文本"); + ofdWriter.close(); + } +}