fix double bug

This commit is contained in:
Looly 2019-11-09 17:35:38 +08:00
parent b5297bd7e6
commit a3b3743f3f
7 changed files with 122 additions and 64 deletions

View File

@ -11,12 +11,14 @@
* 【core】 修正DateUtil.thisWeekOfMonth注释错误issue#614@Github * 【core】 修正DateUtil.thisWeekOfMonth注释错误issue#614@Github
* 【core】 DateUtil增加toLocalDate等方法DateTime更好的支持时区 * 【core】 DateUtil增加toLocalDate等方法DateTime更好的支持时区
* 【core】 BeanUtil.getProperty返回泛型对象issue#I14PIW@Gitee * 【core】 BeanUtil.getProperty返回泛型对象issue#I14PIW@Gitee
* 【core】 FileTypeUtil使用扩展名辅助判断类型issue#I14JBH@Gitee
### Bug修复 ### Bug修复
* 【db】 修复MetaUtil.getTableMeta()方法未释放ResultSet的bugissue#I148GH@Gitee * 【db】 修复MetaUtil.getTableMeta()方法未释放ResultSet的bugissue#I148GH@Gitee
* 【core】 修复DateUtil.age闰年导致的问题issue#I14BVN@Gitee * 【core】 修复DateUtil.age闰年导致的问题issue#I14BVN@Gitee
* 【extra】 修复ServletUtil.getCookie大小写问题pr#79@Gitee * 【extra】 修复ServletUtil.getCookie大小写问题pr#79@Gitee
* 【core】 修复IdcardUtil.isValidCard18报错问题issue#I14LTJ@Gitee * 【core】 修复IdcardUtil.isValidCard18报错问题issue#I14LTJ@Gitee
* 【poi】 修复double值可能存在的精度问题issue#I14FG1@Gitee
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------

View File

@ -17,7 +17,6 @@ import cn.hutool.core.util.StrUtil;
* <p>需要注意的是xlsxdocx等Office2007格式全部识别为zip因为新版采用了OpenXML格式这些格式本质上是XML文件打包为zip</p> * <p>需要注意的是xlsxdocx等Office2007格式全部识别为zip因为新版采用了OpenXML格式这些格式本质上是XML文件打包为zip</p>
* *
* @author Looly * @author Looly
*
*/ */
public class FileTypeUtil { public class FileTypeUtil {
@ -38,7 +37,6 @@ public class FileTypeUtil {
fileTypeMap.put("7b5c727466315c616e73", "rtf"); // Rich Text Format (rtf) fileTypeMap.put("7b5c727466315c616e73", "rtf"); // Rich Text Format (rtf)
fileTypeMap.put("38425053000100000000", "psd"); // Photoshop (psd) fileTypeMap.put("38425053000100000000", "psd"); // Photoshop (psd)
fileTypeMap.put("46726f6d3a203d3f6762", "eml"); // Email [Outlook Express 6] (eml) fileTypeMap.put("46726f6d3a203d3f6762", "eml"); // Email [Outlook Express 6] (eml)
fileTypeMap.put("d0cf11e0a1b11ae10000", "doc"); // MS Excel 注意wordmsi excel的文件头一样
fileTypeMap.put("5374616E64617264204A", "mdb"); // MS Access (mdb) fileTypeMap.put("5374616E64617264204A", "mdb"); // MS Access (mdb)
fileTypeMap.put("252150532D41646F6265", "ps"); fileTypeMap.put("252150532D41646F6265", "ps");
fileTypeMap.put("255044462d312e", "pdf"); // Adobe Acrobat (pdf) fileTypeMap.put("255044462d312e", "pdf"); // Adobe Acrobat (pdf)
@ -55,7 +53,8 @@ public class FileTypeUtil {
fileTypeMap.put("235468697320636f6e66", "ini"); fileTypeMap.put("235468697320636f6e66", "ini");
fileTypeMap.put("504B03040a0000000000", "jar"); fileTypeMap.put("504B03040a0000000000", "jar");
fileTypeMap.put("504B0304140008000800", "jar"); fileTypeMap.put("504B0304140008000800", "jar");
fileTypeMap.put("D0CF11E0A1B11AE10", "xls");// xls文件 // MS Excel 注意wordmsi excel的文件头一样
fileTypeMap.put("d0cf11e0a1b11ae10", "xls");
fileTypeMap.put("504B0304", "zip"); fileTypeMap.put("504B0304", "zip");
fileTypeMap.put("4d5a9000030000000400", "exe");// 可执行文件 fileTypeMap.put("4d5a9000030000000400", "exe");// 可执行文件
fileTypeMap.put("3c25402070616765206c", "jsp");// jsp文件 fileTypeMap.put("3c25402070616765206c", "jsp");// jsp文件
@ -106,7 +105,7 @@ public class FileTypeUtil {
*/ */
public static String getType(String fileStreamHexHead) { public static String getType(String fileStreamHexHead) {
for (Entry<String, String> fileTypeEntry : fileTypeMap.entrySet()) { for (Entry<String, String> fileTypeEntry : fileTypeMap.entrySet()) {
if(StrUtil.startWithIgnoreCase(fileStreamHexHead, fileTypeEntry.getKey())) { if (StrUtil.startWithIgnoreCase(fileStreamHexHead, fileTypeEntry.getKey())) {
return fileTypeEntry.getValue(); return fileTypeEntry.getValue();
} }
} }
@ -127,18 +126,53 @@ public class FileTypeUtil {
/** /**
* 根据文件流的头部信息获得文件类型 * 根据文件流的头部信息获得文件类型
* *
* <pre>
* 1无法识别类型默认按照扩展名识别
* 2xlsdocmsi头信息无法区分按照扩展名区分
* 3zip可能为docxxlsxpptxjarwar头信息无法区分按照扩展名区分
* </pre>
*
* @param file 文件 {@link File} * @param file 文件 {@link File}
* @return 类型文件的扩展名未找到为<code>null</code> * @return 类型文件的扩展名未找到为<code>null</code>
* @throws IORuntimeException 读取文件引起的异常 * @throws IORuntimeException 读取文件引起的异常
*/ */
public static String getType(File file) throws IORuntimeException { public static String getType(File file) throws IORuntimeException {
String typeName;
FileInputStream in = null; FileInputStream in = null;
try { try {
in = IoUtil.toStream(file); in = IoUtil.toStream(file);
return getType(in); typeName = getType(in);
} finally { } finally {
IoUtil.close(in); IoUtil.close(in);
} }
if (null == typeName) {
// 未成功识别类型扩展名辅助识别
typeName = FileUtil.extName(file);
} else if ("xls".equals(typeName)) {
// xlsdocmsi的头一样使用扩展名辅助判断
final String extName = FileUtil.extName(file);
if ("doc".equalsIgnoreCase(extName)) {
typeName = "doc";
} else if ("msi".equalsIgnoreCase(extName)) {
typeName = "msi";
}
} else if ("zip".equals(typeName)) {
// zip可能为docxxlsxpptxjarwar等格式扩展名辅助判断
final String extName = FileUtil.extName(file);
if ("docx".equalsIgnoreCase(extName)) {
typeName = "docx";
} else if ("xlsx".equalsIgnoreCase(extName)) {
typeName = "xlsx";
} else if ("pptx".equalsIgnoreCase(extName)) {
typeName = "pptx";
} else if ("jar".equalsIgnoreCase(extName)) {
typeName = "jar";
} else if ("war".equalsIgnoreCase(extName)) {
typeName = "war";
}
}
return typeName;
} }
/** /**

View File

@ -1551,7 +1551,7 @@ public class FileUtil {
pathToUse = StrUtil.removePrefixIgnoreCase(pathToUse, URLUtil.FILE_URL_PREFIX); pathToUse = StrUtil.removePrefixIgnoreCase(pathToUse, URLUtil.FILE_URL_PREFIX);
// 识别home目录形式并转换为绝对路径 // 识别home目录形式并转换为绝对路径
if(pathToUse.startsWith("~")){ if (pathToUse.startsWith("~")) {
pathToUse = pathToUse.replace("~", getUserHomePath()); pathToUse = pathToUse.replace("~", getUserHomePath());
} }
@ -1875,6 +1875,12 @@ public class FileUtil {
/** /**
* 根据文件流的头部信息获得文件类型 * 根据文件流的头部信息获得文件类型
* *
* <pre>
* 1无法识别类型默认按照扩展名识别
* 2xlsdocmsi头信息无法区分按照扩展名区分
* 3zip可能为docxxlsxpptxjarwar头信息无法区分按照扩展名区分
* </pre>
*
* @param file 文件 {@link File} * @param file 文件 {@link File}
* @return 类型文件的扩展名未找到为<code>null</code> * @return 类型文件的扩展名未找到为<code>null</code>
* @throws IORuntimeException IO异常 * @throws IORuntimeException IO异常

View File

@ -781,20 +781,6 @@ public class IoUtil {
return toStream(content, CharsetUtil.CHARSET_UTF_8); return toStream(content, CharsetUtil.CHARSET_UTF_8);
} }
/**
* String 转为流
*
* @param content 内容bytes
* @return 字节流
* @since 4.1.8
*/
public static ByteArrayInputStream toStream(byte[] content) {
if (content == null) {
return null;
}
return new ByteArrayInputStream(content);
}
/** /**
* 文件转为流 * 文件转为流
* *
@ -809,6 +795,20 @@ public class IoUtil {
} }
} }
/**
* String 转为流
*
* @param content 内容bytes
* @return 字节流
* @since 4.1.8
*/
public static ByteArrayInputStream toStream(byte[] content) {
if (content == null) {
return null;
}
return new ByteArrayInputStream(content);
}
/** /**
* 转换为{@link BufferedInputStream} * 转换为{@link BufferedInputStream}
* *

View File

@ -1,14 +1,11 @@
package cn.hutool.core.io; package cn.hutool.core.io;
import java.io.File; import cn.hutool.core.lang.Console;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import cn.hutool.core.io.FileTypeUtil; import java.io.File;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Console;
/** /**
* 文件类型判断单元测试 * 文件类型判断单元测试
@ -36,4 +33,12 @@ public class FileTypeUtilTest {
String type = FileTypeUtil.getType(file); String type = FileTypeUtil.getType(file);
Console.log(type); Console.log(type);
} }
@Test
@Ignore
public void docTest() {
File file = FileUtil.file("f:/test/test.doc");
String type = FileTypeUtil.getType(file);
Console.log(type);
}
} }

View File

@ -1,10 +1,9 @@
package cn.hutool.poi.excel.cell; package cn.hutool.poi.excel.cell;
import java.math.BigDecimal; import cn.hutool.core.date.DateUtil;
import java.util.Calendar; import cn.hutool.core.util.StrUtil;
import java.util.Date; import cn.hutool.poi.excel.StyleSet;
import java.util.List; import cn.hutool.poi.excel.editors.TrimEditor;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellType;
@ -13,13 +12,14 @@ import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.NumberToTextConverter;
import org.apache.poi.ss.util.RegionUtil; import org.apache.poi.ss.util.RegionUtil;
import org.apache.poi.ss.util.SheetUtil; import org.apache.poi.ss.util.SheetUtil;
import cn.hutool.core.date.DateUtil; import java.math.BigDecimal;
import cn.hutool.core.util.StrUtil; import java.util.Calendar;
import cn.hutool.poi.excel.StyleSet; import java.util.Date;
import cn.hutool.poi.excel.editors.TrimEditor; import java.util.List;
/** /**
* Excel表格中单元格工具类 * Excel表格中单元格工具类
@ -27,6 +27,7 @@ import cn.hutool.poi.excel.editors.TrimEditor;
* @author looly * @author looly
* @since 4.0.7 * @since 4.0.7
*/ */
@SuppressWarnings("deprecation")
public class CellUtil { public class CellUtil {
/** /**
@ -283,10 +284,7 @@ public class CellUtil {
final double value = cell.getNumericCellValue(); final double value = cell.getNumericCellValue();
final CellStyle style = cell.getCellStyle(); final CellStyle style = cell.getCellStyle();
if (null == style) { if (null != style) {
return value;
}
final short formatIndex = style.getDataFormat(); final short formatIndex = style.getDataFormat();
// 判断是否为日期 // 判断是否为日期
if (isDateType(cell, formatIndex)) { if (isDateType(cell, formatIndex)) {
@ -297,12 +295,15 @@ public class CellUtil {
// 普通数字 // 普通数字
if (null != format && format.indexOf(StrUtil.C_DOT) < 0) { if (null != format && format.indexOf(StrUtil.C_DOT) < 0) {
final long longPart = (long) value; final long longPart = (long) value;
if (longPart == value) { if (((double) longPart) == value) {
// 对于无小数部分的数字类型转为Long // 对于无小数部分的数字类型转为Long
return longPart; return longPart;
} }
} }
return value; }
// 某些Excel单元格值为double计算结果可能导致精度问题通过转换解决精度问题
return Double.parseDouble(NumberToTextConverter.toText(value));
} }
/** /**

View File

@ -190,4 +190,14 @@ public class ExcelReadTest {
return "Person [name=" + name + ", gender=" + gender + ", age=" + age + "]"; return "Person [name=" + name + ", gender=" + gender + ", age=" + age + "]";
} }
} }
@Test
@Ignore
public void readDoubleTest(){
ExcelReader reader = ExcelUtil.getReader("f:/test/doubleTest.xls");
final List<List<Object>> read = reader.read();
for (List<Object> list : read) {
Console.log(list.get(8));
}
}
} }