Browse Source

fix excel sax

Looly 6 years ago
parent
commit
0837363931

+ 1 - 0
CHANGELOG.md

@@ -14,6 +14,7 @@
 * 【core】       修复DateUtil.format使用DateTime时区失效问题(issue#I150I7@Gitee)
 * 【core】       修复ZipUtil解压目录遗留问题(issue#I14NO3@Gitee)
 * 【core】       修复等比缩放给定背景色无效问题(pr#625@Github)
+* 【poi 】       修复sax方式读取excel中无样式表导致的空指针问题
 
 -------------------------------------------------------------------------------------------------------------
 

+ 8 - 8
hutool-core/src/main/java/cn/hutool/core/img/Img.java

@@ -277,16 +277,16 @@ public class Img implements Serializable {
 		int srcWidth = srcImage.getWidth(null);
 		double heightRatio = NumberUtil.div(height, srcHeight);
 		double widthRatio = NumberUtil.div(width, srcWidth);
-		if (heightRatio == widthRatio) {
+
+		if (widthRatio == heightRatio) {
 			// 长宽都按照相同比例缩放时,返回缩放后的图片
 			scale(width, height);
-		} else{
-			// 宽缩放比例多就按照宽缩放,否则按照高缩放
-			if (widthRatio < heightRatio) {
-				scale(width, (int) (srcHeight * widthRatio));
-			} else {
-				scale((int) (srcWidth * heightRatio), height);
-			}
+		} else if (widthRatio < heightRatio) {
+			// 宽缩放比例多就按照宽缩放
+			scale(width, (int) (srcHeight * widthRatio));
+		} else {
+			// 否则按照高缩放
+			scale((int) (srcWidth * heightRatio), height);
 		}
 
 		// 获取缩放后的新的宽和高

+ 13 - 24
hutool-core/src/main/java/cn/hutool/core/util/XmlUtil.java

@@ -681,30 +681,19 @@ public class XmlUtil {
 	 * @since 4.0.8
 	 */
 	public static String escape(String string) {
-		final StringBuilder sb = new StringBuilder(string.length());
-		for (int i = 0, length = string.length(); i < length; i++) {
-			char c = string.charAt(i);
-			switch (c) {
-				case '&':
-					sb.append("&amp;");
-					break;
-				case '<':
-					sb.append("&lt;");
-					break;
-				case '>':
-					sb.append("&gt;");
-					break;
-				case '"':
-					sb.append("&quot;");
-					break;
-				case '\'':
-					sb.append("&apos;");
-					break;
-				default:
-					sb.append(c);
-			}
-		}
-		return sb.toString();
+		return EscapeUtil.escape(string);
+	}
+
+	/**
+	 * 反转义XML特殊字符:
+	 *
+	 * @param string 被替换的字符串
+	 * @return 替换后的字符串
+	 * @since 5.0.6
+	 * @see EscapeUtil#unescape(String)
+	 */
+	public static String unescape(String string) {
+		return EscapeUtil.unescape(string);
 	}
 
 	/**

+ 25 - 1
hutool-http/src/test/java/cn/hutool/http/webservice/SoapClientTest.java

@@ -3,6 +3,8 @@ package cn.hutool.http.webservice;
 import javax.xml.soap.SOAPException;
 import javax.xml.soap.SOAPMessage;
 
+import cn.hutool.core.util.XmlUtil;
+import cn.hutool.http.HtmlUtil;
 import org.junit.Ignore;
 import org.junit.Test;
 
@@ -40,5 +42,27 @@ public class SoapClientTest {
 		SOAPMessage message = client.sendForMessage();
 		Console.log(message.getSOAPBody().getTextContent());
 	}
-	
+
+
+	@Test
+	public void test(){
+		final SoapClient soapClient = SoapClient.create("http://117.132.161.47:6403/services/JybgService")
+				.setMethod("ser:zzjRequest", "http://service.jfsoft.com/")
+				.setParam("arg0", "<![CDATA[\n" +
+						"<Request>\n" +
+						"<CardType>3</CardType>\n" +
+						"<CardNo>C00002347</CardNo>\n" +
+						"<BeginDate>20191101</BeginDate>\n" +
+						"<EndDate>20191115</EndDate>\n" +
+						"<TerminalNo>JKGCOnline000001</TerminalNo>\n" +
+						"<BusinessCode>GetLisReport</BusinessCode>\n" +
+						"<OperName>自助机01</OperName>\n" +
+						"<OperCode>zzj01</OperCode>\n" +
+						"<OperTime>20191116153748</OperTime>\n" +
+						"</Request>\n" +
+						"]]>", false);
+
+		final String send = soapClient.send();
+		Console.log(HtmlUtil.unescape(send));
+	}
 }

+ 33 - 29
hutool-poi/src/main/java/cn/hutool/poi/excel/sax/Excel07SaxReader.java

@@ -1,12 +1,10 @@
 package cn.hutool.poi.excel.sax;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
+import cn.hutool.core.exceptions.DependencyException;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.poi.excel.sax.handler.RowHandler;
+import cn.hutool.poi.exceptions.POIException;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.ss.usermodel.BuiltinFormats;
 import org.apache.poi.xssf.eventusermodel.XSSFReader;
@@ -21,12 +19,12 @@ import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
 import org.xml.sax.helpers.XMLReaderFactory;
 
-import cn.hutool.core.exceptions.DependencyException;
-import cn.hutool.core.exceptions.ExceptionUtil;
-import cn.hutool.core.io.IoUtil;
-import cn.hutool.core.util.StrUtil;
-import cn.hutool.poi.excel.sax.handler.RowHandler;
-import cn.hutool.poi.exceptions.POIException;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
 
 /**
  * Sax方式读取Excel文件<br>
@@ -129,10 +127,10 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
 	public Excel07SaxReader read(InputStream in, int rid) throws POIException {
 		try {
 			return read(OPCPackage.open(in), rid);
-		} catch (DependencyException e) {
+		} catch (RuntimeException e) {
 			throw e;
 		} catch (Exception e) {
-			throw ExceptionUtil.wrap(e, POIException.class);
+			throw new POIException(e);
 		}
 	}
 
@@ -150,7 +148,11 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
 			final XSSFReader xssfReader = new XSSFReader(opcPackage);
 
 			// 获取共享样式表
-			stylesTable = xssfReader.getStylesTable();
+			try{
+				stylesTable = xssfReader.getStylesTable();
+			} catch (Exception e){
+				//ignore
+			}
 			// 获取共享字符串表
 			this.sharedStringsTable = xssfReader.getSharedStringsTable();
 
@@ -171,10 +173,10 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
 					parse(sheetInputStream);
 				}
 			}
-		} catch (DependencyException e) {
+		} catch (RuntimeException e) {
 			throw e;
 		} catch (Exception e) {
-			throw ExceptionUtil.wrap(e, POIException.class);
+			throw new POIException(e);
 		} finally {
 			IoUtil.close(sheetInputStream);
 			IoUtil.close(opcPackage);
@@ -222,17 +224,19 @@ public class Excel07SaxReader extends AbstractExcelSaxReader<Excel07SaxReader> i
 		this.cellDataType = CellDataType.of(attribute.getValue(T_ATTR_VALUE));
 
 		// 获取单元格的xf索引,对应style.xml中cellXfs的子元素xf
-		final String xfIndexStr = attribute.getValue(S_ATTR_VALUE);
-		if (xfIndexStr != null) {
-			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;
+		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;
+				}
 			}
 		}
 

+ 16 - 29
hutool-poi/src/test/java/cn/hutool/poi/excel/test/ExcelSaxReadTest.java

@@ -25,15 +25,11 @@ public class ExcelSaxReadTest {
 	@Test
 	@Ignore
 	public void readBlankLineTest() {
-		ExcelUtil.readBySax("e:/ExcelBlankLine.xlsx", 0, new RowHandler() {
-
-			@Override
-			public void handle(int sheetIndex, int rowIndex, List<Object> rowList) {
-				if (StrUtil.isAllEmpty(Convert.toStrArray(rowList))) {
-					return;
-				}
-				Console.log(rowList);
+		ExcelUtil.readBySax("e:/ExcelBlankLine.xlsx", 0, (sheetIndex, rowIndex, rowList) -> {
+			if (StrUtil.isAllEmpty(Convert.toStrArray(rowList))) {
+				return;
 			}
+			Console.log(rowList);
 		});
 	}
 
@@ -45,24 +41,13 @@ public class ExcelSaxReadTest {
 	@Test
 	@Ignore
 	public void readBySaxTest2() {
-		ExcelUtil.readBySax("e:/B23_20180404164901240.xlsx", 2, new RowHandler() {
-			@Override
-			public void handle(int sheetIndex, int rowIndex, List<Object> rowList) {
-				Console.log(rowList);
-			}
-		});
+		ExcelUtil.readBySax("e:/B23_20180404164901240.xlsx", 2, (sheetIndex, rowIndex, rowList) -> Console.log(rowList));
 	}
 
 	@Test
 	@Ignore
 	public void readBySaxTest3() {
-		ExcelUtil.readBySax("e:/excel/writeMapTest.xlsx", 0, new RowHandler() {
-
-			@Override
-			public void handle(int sheetIndex, int rowIndex, List<Object> rowList) {
-				Console.log(rowList);
-			}
-		});
+		ExcelUtil.readBySax("e:/excel/writeMapTest.xlsx", 0, (sheetIndex, rowIndex, rowList) -> Console.log(rowList));
 	}
 
 	@Test
@@ -91,16 +76,18 @@ public class ExcelSaxReadTest {
 		ExcelUtil.readBySax("f:\\test\\222.xlsx", 0, createRowHandler());
 	}
 
-	private RowHandler createRowHandler() {
-		return new RowHandler() {
+	@Test
+	@Ignore
+	public void readBySaxTest6() {
+		ExcelUtil.readBySax("f:\\test\\sax_test.xlsx", 0, createRowHandler());
+	}
 
-			@Override
-			public void handle(int sheetIndex, int rowIndex, List<Object> rowlist) {
+	private RowHandler createRowHandler() {
+		return (sheetIndex, rowIndex, rowlist) -> {
 //				Console.log("[{}] [{}] {}", sheetIndex, rowIndex, rowlist);
-				if (5 != rowIndex && 6 != rowIndex) {
-					// 测试样例中除第五行、第六行都为非空行
-					Assert.assertTrue(CollUtil.isNotEmpty(rowlist));
-				}
+			if (5 != rowIndex && 6 != rowIndex) {
+				// 测试样例中除第五行、第六行都为非空行
+				Assert.assertTrue(CollUtil.isNotEmpty(rowlist));
 			}
 		};
 	}