This commit is contained in:
Looly 2020-02-19 19:26:16 +08:00
parent 653ba7ff1d
commit 545c20912a
8 changed files with 158 additions and 154 deletions

View File

@ -7,6 +7,7 @@
### 新特性 ### 新特性
### Bug修复 ### Bug修复
* 【core 】 修复CombinationAnnotationElement数组判断问题issue#752@Github
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------

View File

@ -1,5 +1,7 @@
package cn.hutool.core.annotation; package cn.hutool.core.annotation;
import cn.hutool.core.collection.CollUtil;
import java.io.Serializable; import java.io.Serializable;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
@ -7,14 +9,12 @@ import java.lang.annotation.Inherited;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.lang.reflect.AnnotatedElement; import java.lang.reflect.AnnotatedElement;
import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
/** /**
* 组合注解 对JDK的原生注解机制做一个增强支持类似Spring的组合注解<br> * 组合注解 对JDK的原生注解机制做一个增强支持类似Spring的组合注解<br>
* 核心实现使用了递归获取指定元素上的注解以及注解的注解以实现复合注解的获取 * 核心实现使用了递归获取指定元素上的注解以及注解的注解以实现复合注解的获取
@ -65,13 +65,13 @@ public class CombinationAnnotationElement implements AnnotatedElement, Serializa
@Override @Override
public Annotation[] getAnnotations() { public Annotation[] getAnnotations() {
final Collection<Annotation> annotations = this.annotationMap.values(); final Collection<Annotation> annotations = this.annotationMap.values();
return annotations.toArray(new Annotation[annotations.size()]); return annotations.toArray(new Annotation[0]);
} }
@Override @Override
public Annotation[] getDeclaredAnnotations() { public Annotation[] getDeclaredAnnotations() {
final Collection<Annotation> annotations = this.declaredAnnotationMap.values(); final Collection<Annotation> annotations = this.declaredAnnotationMap.values();
return annotations.toArray(new Annotation[annotations.size()]); return annotations.toArray(new Annotation[0]);
} }
/** /**
@ -85,7 +85,7 @@ public class CombinationAnnotationElement implements AnnotatedElement, Serializa
parseDeclared(declaredAnnotations); parseDeclared(declaredAnnotations);
final Annotation[] annotations = element.getAnnotations(); final Annotation[] annotations = element.getAnnotations();
if(ObjectUtil.equal(declaredAnnotations, annotations)) { if(Arrays.equals(declaredAnnotations, annotations)) {
this.annotationMap = this.declaredAnnotationMap; this.annotationMap = this.declaredAnnotationMap;
}else { }else {
this.annotationMap = new HashMap<>(); this.annotationMap = new HashMap<>();

View File

@ -2700,8 +2700,7 @@ public class ArrayUtil {
* @since 3.0.9 * @since 3.0.9
*/ */
public static <T> T[] toArray(Collection<T> collection, Class<T> componentType) { public static <T> T[] toArray(Collection<T> collection, Class<T> componentType) {
final T[] array = newArray(componentType, collection.size()); return collection.toArray(newArray(componentType, 0));
return collection.toArray(array);
} }
// ---------------------------------------------------------------------- remove // ---------------------------------------------------------------------- remove

View File

@ -1,11 +1,14 @@
package cn.hutool.core.util; package cn.hutool.core.util;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Editor; import cn.hutool.core.lang.Editor;
import cn.hutool.core.lang.Filter; import cn.hutool.core.lang.Filter;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import java.util.Objects;
/** /**
* {@link ArrayUtil} 数组工具单元测试 * {@link ArrayUtil} 数组工具单元测试
@ -20,8 +23,10 @@ public class ArrayUtilTest {
Assert.assertTrue(ArrayUtil.isEmpty(a)); Assert.assertTrue(ArrayUtil.isEmpty(a));
Assert.assertTrue(ArrayUtil.isEmpty((Object) a)); Assert.assertTrue(ArrayUtil.isEmpty((Object) a));
int[] b = null; int[] b = null;
//noinspection ConstantConditions
Assert.assertTrue(ArrayUtil.isEmpty(b)); Assert.assertTrue(ArrayUtil.isEmpty(b));
Object c = null; Object c = null;
//noinspection ConstantConditions
Assert.assertTrue(ArrayUtil.isEmpty(c)); Assert.assertTrue(ArrayUtil.isEmpty(c));
Object d = new Object[]{"1", "2", 3, 4D}; Object d = new Object[]{"1", "2", 3, 4D};
@ -31,7 +36,9 @@ public class ArrayUtilTest {
isEmpty = ArrayUtil.isEmpty(d); isEmpty = ArrayUtil.isEmpty(d);
Assert.assertTrue(isEmpty); Assert.assertTrue(isEmpty);
d = null; d = null;
//noinspection ConstantConditions
isEmpty = ArrayUtil.isEmpty(d); isEmpty = ArrayUtil.isEmpty(d);
//noinspection ConstantConditions
Assert.assertTrue(isEmpty); Assert.assertTrue(isEmpty);
} }
@ -117,7 +124,7 @@ public class ArrayUtilTest {
String[] keys = {"a", "b", "c"}; String[] keys = {"a", "b", "c"};
Integer[] values = {1, 2, 3}; Integer[] values = {1, 2, 3};
Map<String, Integer> map = ArrayUtil.zip(keys, values, true); Map<String, Integer> map = ArrayUtil.zip(keys, values, true);
Assert.assertEquals(map.toString(), "{a=1, b=2, c=3}"); Assert.assertEquals(Objects.requireNonNull(map).toString(), "{a=1, b=2, c=3}");
} }
@Test @Test
@ -248,4 +255,14 @@ public class ArrayUtilTest {
String[] array = {"aa", "bb", "cc", "dd", "bb", "dd"}; String[] array = {"aa", "bb", "cc", "dd", "bb", "dd"};
Assert.assertEquals("[aa, bb, cc, dd, bb, dd]", ArrayUtil.toString(array)); Assert.assertEquals("[aa, bb, cc, dd, bb, dd]", ArrayUtil.toString(array));
} }
@Test
public void toArrayTest(){
final ArrayList<String> list = CollUtil.newArrayList("A", "B", "C", "D");
final String[] array = ArrayUtil.toArray(list, String.class);
Assert.assertEquals("A", array[0]);
Assert.assertEquals("B", array[1]);
Assert.assertEquals("C", array[2]);
Assert.assertEquals("D", array[3]);
}
} }

View File

@ -17,9 +17,8 @@
<properties> <properties>
<!-- versions --> <!-- versions -->
<poi.version>4.1.1</poi.version> <poi.version>4.1.2</poi.version>
<xerces.version>2.12.0</xerces.version> <xerces.version>2.12.0</xerces.version>
<easyexcel.version>2.1.6</easyexcel.version>
</properties> </properties>
<dependencies> <dependencies>
@ -49,12 +48,5 @@
<scope>compile</scope> <scope>compile</scope>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>${easyexcel.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,6 +1,5 @@
package cn.hutool.poi.excel.sax; package cn.hutool.poi.excel.sax;
import cn.hutool.core.exceptions.DependencyException;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.sax.handler.RowHandler; import cn.hutool.poi.excel.sax.handler.RowHandler;
@ -13,14 +12,9 @@ import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler; import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.Locator; import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
@ -35,8 +29,6 @@ import java.util.List;
*/ */
public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> implements ContentHandler { public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> implements ContentHandler {
// saxParser
private static final String CLASS_SAXPARSER = "org.apache.xerces.parsers.SAXParser";
/** /**
* Cell单元格元素 * Cell单元格元素
*/ */
@ -46,7 +38,7 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
*/ */
private static final String ROW_ELEMENT = "row"; private static final String ROW_ELEMENT = "row";
/** /**
* Cell中的行列号 * Cell中的行列号(Reference)行模式下此为行号属性名列模式下为列号属性名
*/ */
private static final String R_ATTR = "r"; private static final String R_ATTR = "r";
/** /**
@ -54,7 +46,7 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
*/ */
private static final String T_ELEMENT = "t"; private static final String T_ELEMENT = "t";
/** /**
* SSTSharedStringsTable 的索引 * SSTSharedStringsTable 的索引样式index
*/ */
private static final String S_ATTR_VALUE = "s"; private static final String S_ATTR_VALUE = "s";
// 列中属性值 // 列中属性值
@ -69,7 +61,7 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
// 当前列 // 当前列
private int curCell; private int curCell;
// 上一次的内容 // 上一次的内容
private String lastContent; private StringBuilder lastContent = new StringBuilder(64);
// 单元数据类型 // 单元数据类型
private CellDataType cellDataType; private CellDataType cellDataType;
// 当前列坐标 如A1B5 // 当前列坐标 如A1B5
@ -160,7 +152,7 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
this.sheetIndex = rid; this.sheetIndex = rid;
// 根据 rId# rSheet# 查找sheet // 根据 rId# rSheet# 查找sheet
sheetInputStream = xssfReader.getSheet(RID_PREFIX + (rid + 1)); sheetInputStream = xssfReader.getSheet(RID_PREFIX + (rid + 1));
parse(sheetInputStream); ExcelSaxUtil.readFrom(sheetInputStream, this);
} else { } else {
this.sheetIndex = -1; this.sheetIndex = -1;
// 遍历所有sheet // 遍历所有sheet
@ -170,7 +162,7 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
curRow = 0; curRow = 0;
this.sheetIndex++; this.sheetIndex++;
sheetInputStream = sheetInputStreams.next(); sheetInputStream = sheetInputStreams.next();
parse(sheetInputStream); ExcelSaxUtil.readFrom(sheetInputStream, this);
} }
} }
} catch (RuntimeException e) { } catch (RuntimeException e) {
@ -191,8 +183,7 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
@Override @Override
public void startElement(String uri, String localName, String qName, Attributes attributes) { public void startElement(String uri, String localName, String qName, Attributes attributes) {
// 单元格元素 // 单元格元素
if (C_ELEMENT.equals(qName)) { if (C_ELEMENT.equals(localName)) {
// 获取当前列坐标 // 获取当前列坐标
String tempCurCoordinate = attributes.getValue(R_ATTR); String tempCurCoordinate = attributes.getValue(R_ATTR);
// 前一列为null则将其设置为"@",A为第一列ascii码为65前一列即为@ascii码64 // 前一列为null则将其设置为"@",A为第一列ascii码为65前一列即为@ascii码64
@ -208,38 +199,7 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
setCellType(attributes); setCellType(attributes);
} }
lastContent = ""; lastContent.setLength(0);
}
/**
* 设置单元格的类型
*
* @param attribute 属性
*/
private void setCellType(Attributes attribute) {
// 单元格存储格式的索引对应style.xml中的numFmts元素的子元素索引
int numFmtIndex;
// numFmtString的值
numFmtString = "";
this.cellDataType = CellDataType.of(attribute.getValue(T_ATTR_VALUE));
// 获取单元格的xf索引对应style.xml中cellXfs的子元素xf
if(null != this.stylesTable){
final String xfIndexStr = attribute.getValue(S_ATTR_VALUE);
if (null != xfIndexStr) {
int xfIndex = Integer.parseInt(xfIndexStr);
XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(xfIndex);
numFmtIndex = xssfCellStyle.getDataFormat();
numFmtString = xssfCellStyle.getDataFormatString();
if (numFmtString == null) {
numFmtString = BuiltinFormats.getBuiltinFormat(numFmtIndex);
} else if (CellDataType.NUMBER == this.cellDataType && org.apache.poi.ss.usermodel.DateUtil.isADateFormat(numFmtIndex, numFmtString)) {
cellDataType = CellDataType.DATE;
}
}
}
} }
/** /**
@ -253,13 +213,13 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
// // type标签 // // type标签
// // rowCellList.add(curCell++, contentStr); // // rowCellList.add(curCell++, contentStr);
// } else // } else
if (C_ELEMENT.equals(qName)) { if (C_ELEMENT.equals(localName)) {
// cell标签 // cell标签
Object value = ExcelSaxUtil.getDataValue(this.cellDataType, contentStr, this.sharedStringsTable, this.numFmtString); Object value = ExcelSaxUtil.getDataValue(this.cellDataType, contentStr, this.sharedStringsTable, this.numFmtString);
// 补全单元格之间的空格 // 补全单元格之间的空格
fillBlankCell(preCoordinate, curCoordinate, false); fillBlankCell(preCoordinate, curCoordinate, false);
rowCellList.add(curCell++, value); rowCellList.add(curCell++, value);
} else if (ROW_ELEMENT.equals(qName)) { } else if (ROW_ELEMENT.equals(localName)) {
// 如果是row标签说明已经到了一行的结尾 // 如果是row标签说明已经到了一行的结尾
// 最大列坐标以第一行的为准 // 最大列坐标以第一行的为准
if (curRow == 0) { if (curRow == 0) {
@ -292,7 +252,7 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
@Override @Override
public void characters(char[] ch, int start, int length) { public void characters(char[] ch, int start, int length) {
// 得到单元格内容的值 // 得到单元格内容的值
lastContent = lastContent.concat(new String(ch, start, length)); lastContent.append(ch, start, length);
} }
// --------------------------------------------------------------------------------------- Pass method start // --------------------------------------------------------------------------------------- Pass method start
@ -341,18 +301,6 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
// --------------------------------------------------------------------------------------- Pass method end // --------------------------------------------------------------------------------------- Pass method end
// --------------------------------------------------------------------------------------- Private method start // --------------------------------------------------------------------------------------- Private method start
/**
* 处理流中的Excel数据
*
* @param sheetInputStream sheet流
* @throws IOException IO异常
* @throws SAXException SAX异常
*/
private void parse(InputStream sheetInputStream) throws IOException, SAXException {
fetchSheetReader().parse(new InputSource(sheetInputStream));
}
/** /**
* 填充空白单元格如果前一个单元格大于后一个不需要填充<br> * 填充空白单元格如果前一个单元格大于后一个不需要填充<br>
* *
@ -373,24 +321,32 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
} }
/** /**
* 获取sheet的解析器 * 设置单元格的类型
* *
* @return {@link XMLReader} * @param attribute 属性
* @throws SAXException SAX异常
*/ */
private XMLReader fetchSheetReader() throws SAXException { private void setCellType(Attributes attribute) {
XMLReader xmlReader; // numFmtString的值
try { numFmtString = "";
xmlReader = XMLReaderFactory.createXMLReader(CLASS_SAXPARSER); this.cellDataType = CellDataType.of(attribute.getValue(T_ATTR_VALUE));
} catch (SAXException e) {
if (e.getMessage().contains("org.apache.xerces.parsers.SAXParser")) { // 获取单元格的xf索引对应style.xml中cellXfs的子元素xf
throw new DependencyException(e, "You need to add 'xerces:xercesImpl' to your project and version >= 2.11.0"); if(null != this.stylesTable){
} else { final String xfIndexStr = attribute.getValue(S_ATTR_VALUE);
throw e; if (null != xfIndexStr) {
int xfIndex = Integer.parseInt(xfIndexStr);
final XSSFCellStyle xssfCellStyle = stylesTable.getStyleAt(xfIndex);
numFmtString = xssfCellStyle.getDataFormatString();
// 单元格存储格式的索引对应style.xml中的numFmts元素的子元素索引
int numFmtIndex = xssfCellStyle.getDataFormat();
if (numFmtString == null) {
numFmtString = BuiltinFormats.getBuiltinFormat(numFmtIndex);
} else if (CellDataType.NUMBER == this.cellDataType && org.apache.poi.ss.usermodel.DateUtil.isADateFormat(numFmtIndex, numFmtString)) {
cellDataType = CellDataType.DATE;
}
} }
} }
xmlReader.setContentHandler(this);
return xmlReader;
} }
// --------------------------------------------------------------------------------------- Private method end // --------------------------------------------------------------------------------------- Private method end
} }

View File

@ -1,18 +1,28 @@
package cn.hutool.poi.excel.sax; package cn.hutool.poi.excel.sax;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil; 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.core.util.StrUtil;
import cn.hutool.poi.exceptions.POIException;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
/** /**
* Sax方式读取Excel相关工具类 * Sax方式读取Excel相关工具类
*
* @author looly
* *
* @author looly
*/ */
public class ExcelSaxUtil { public class ExcelSaxUtil {
@ -23,67 +33,67 @@ public class ExcelSaxUtil {
/** /**
* 根据数据类型获取数据 * 根据数据类型获取数据
* *
* @param cellDataType 数据类型枚举 * @param cellDataType 数据类型枚举
* @param value 数据值 * @param value 数据值
* @param sharedStringsTable {@link SharedStringsTable} * @param sharedStringsTable {@link SharedStringsTable}
* @param numFmtString 数字格式名 * @param numFmtString 数字格式名
* @return 数据值 * @return 数据值
*/ */
public static Object getDataValue(CellDataType cellDataType, String value, SharedStringsTable sharedStringsTable, String numFmtString) { public static Object getDataValue(CellDataType cellDataType, String value, SharedStringsTable sharedStringsTable, String numFmtString) {
if (null == value) { if (null == value) {
return null; return null;
} }
if(null == cellDataType) { if (null == cellDataType) {
cellDataType = CellDataType.NULL; cellDataType = CellDataType.NULL;
} }
Object result; Object result;
switch (cellDataType) { switch (cellDataType) {
case BOOL: case BOOL:
result = (value.charAt(0) != '0'); result = (value.charAt(0) != '0');
break; break;
case ERROR: case ERROR:
result = StrUtil.format("\\\"ERROR: {} ", value); result = StrUtil.format("\\\"ERROR: {} ", value);
break; break;
case FORMULA: case FORMULA:
result = StrUtil.format("\"{}\"", value); result = StrUtil.format("\"{}\"", value);
break; break;
case INLINESTR: case INLINESTR:
result = new XSSFRichTextString(value).toString(); result = new XSSFRichTextString(value).toString();
break; break;
case SSTINDEX: case SSTINDEX:
try { try {
final int index = Integer.parseInt(value); final int index = Integer.parseInt(value);
//noinspection deprecation //noinspection deprecation
result = new XSSFRichTextString(sharedStringsTable.getEntryAt(index)).getString(); result = new XSSFRichTextString(sharedStringsTable.getEntryAt(index)).getString();
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
result = value;
}
break;
case NUMBER:
result = getNumberValue(value, numFmtString);
break;
case DATE:
try {
result = getDateValue(value);
} catch (Exception e) {
result = value;
}
break;
default:
result = value; result = value;
} break;
break;
case NUMBER:
result = getNumberValue(value, numFmtString);
break;
case DATE:
try {
result = getDateValue(value);
} catch (Exception e) {
result = value;
}
break;
default:
result = value;
break;
} }
return result; return result;
} }
/** /**
* 格式化数字或日期值 * 格式化数字或日期值
* *
* @param value * @param value
* @param numFmtIndex 数字格式索引 * @param numFmtIndex 数字格式索引
* @param numFmtString 数字格式名 * @param numFmtString 数字格式名
* @return 格式化后的值 * @return 格式化后的值
*/ */
@ -100,9 +110,9 @@ public class ExcelSaxUtil {
/** /**
* 计算两个单元格之间的单元格数目(同一行) * 计算两个单元格之间的单元格数目(同一行)
* *
* @param preRef 前一个单元格位置例如A1 * @param preRef 前一个单元格位置例如A1
* @param ref 当前单元格位置例如A8 * @param ref 当前单元格位置例如A8
* @return 同一行中两个单元格之间的空单元格数 * @return 同一行中两个单元格之间的空单元格数
*/ */
public static int countNullCell(String preRef, String ref) { public static int countNullCell(String preRef, String ref) {
@ -123,9 +133,41 @@ public class ExcelSaxUtil {
return res - 1; return res - 1;
} }
/**
* 从Excel的XML文档中读取内容并使用{@link ContentHandler}处理
*
* @param xmlDocStream Excel的XML文档流
* @param handler 文档内容处理接口实现此接口用于回调处理数据
* @throws DependencyException 依赖异常
* @throws POIException POI异常包装了SAXException
* @throws IORuntimeException IO异常如流关闭或异常等
* @since 5.1.4
*/
public static void readFrom(InputStream xmlDocStream, ContentHandler handler) throws DependencyException, POIException, IORuntimeException {
XMLReader xmlReader;
try {
//noinspection deprecation
xmlReader = SAXHelper.newXMLReader();
} catch (SAXException | ParserConfigurationException e) {
if (e.getMessage().contains("org.apache.xerces.parsers.SAXParser")) {
throw new DependencyException(e, "You need to add 'xerces:xercesImpl' to your project and version >= 2.11.0");
} else {
throw new POIException(e);
}
}
xmlReader.setContentHandler(handler);
try {
xmlReader.parse(new InputSource(xmlDocStream));
} catch (IOException e) {
throw new IORuntimeException(e);
} catch (SAXException e) {
throw new POIException(e);
}
}
/** /**
* 获取日期 * 获取日期
* *
* @param value 单元格值 * @param value 单元格值
* @return 日期 * @return 日期
* @since 4.1.0 * @since 4.1.0
@ -136,14 +178,14 @@ public class ExcelSaxUtil {
/** /**
* 获取数字类型值 * 获取数字类型值
* *
* @param value * @param value
* @param numFmtString 格式 * @param numFmtString 格式
* @return 数字可以是DoubleLong * @return 数字可以是DoubleLong
* @since 4.1.0 * @since 4.1.0
*/ */
private static Number getNumberValue(String value, String numFmtString) { private static Number getNumberValue(String value, String numFmtString) {
if(StrUtil.isBlank(value)) { if (StrUtil.isBlank(value)) {
return null; return null;
} }
double numValue = Double.parseDouble(value); double numValue = Double.parseDouble(value);

View File

@ -1,11 +1,5 @@
package cn.hutool.poi.excel.test; package cn.hutool.poi.excel.test;
import java.util.List;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Console; import cn.hutool.core.lang.Console;
@ -13,6 +7,9 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.sax.Excel03SaxReader; import cn.hutool.poi.excel.sax.Excel03SaxReader;
import cn.hutool.poi.excel.sax.handler.RowHandler; import cn.hutool.poi.excel.sax.handler.RowHandler;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
/** /**
* Excel sax方式读取 * Excel sax方式读取