fix date read for sax bug

This commit is contained in:
Looly 2020-12-05 17:13:05 +08:00
parent 7103adc02e
commit 897dea0b30
14 changed files with 83 additions and 67 deletions

View File

@ -12,6 +12,7 @@
### Bug修复 ### Bug修复
* 【cache 】 修复Cache中get重复misCount计数问题issue#1281@Github * 【cache 】 修复Cache中get重复misCount计数问题issue#1281@Github
* 【poi 】 修复sax读取自定义格式单元格无法识别日期类型的问题issue#1283@Github
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------

View File

@ -268,7 +268,7 @@ public class Excel03SaxReader implements HSSFListener, ExcelSaxReader<Excel03Sax
break; break;
case FormulaRecord.sid: case FormulaRecord.sid:
// 公式类型 // 公式类型
FormulaRecord formulaRec = (FormulaRecord) record; final FormulaRecord formulaRec = (FormulaRecord) record;
if (isOutputFormulaValues) { if (isOutputFormulaValues) {
if (Double.isNaN(formulaRec.getValue())) { if (Double.isNaN(formulaRec.getValue())) {
// Formula result is a string // Formula result is a string

View File

@ -4,6 +4,7 @@ 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.exceptions.DependencyException;
import cn.hutool.core.io.IORuntimeException; import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.util.CharUtil;
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;
import cn.hutool.poi.exceptions.POIException; import cn.hutool.poi.exceptions.POIException;
@ -34,6 +35,20 @@ public class ExcelSaxUtil {
// 列的最大位数 // 列的最大位数
public static final int MAX_CELL_BIT = 3; public static final int MAX_CELL_BIT = 3;
/**
* 创建 {@link ExcelSaxReader}
*
* @param isXlsx 是否为xlsx格式07格式
* @param rowHandler 行处理器
* @return {@link ExcelSaxReader}
* @since 5.4.4
*/
public static ExcelSaxReader<?> createSaxReader(boolean isXlsx, RowHandler rowHandler) {
return isXlsx
? new Excel07SaxReader(rowHandler)
: new Excel03SaxReader(rowHandler);
}
/** /**
* 根据数据类型获取数据 * 根据数据类型获取数据
* *
@ -175,6 +190,7 @@ public class ExcelSaxUtil {
/** /**
* 判断数字Record中是否为日期格式 * 判断数字Record中是否为日期格式
*
* @param cell 单元格记录 * @param cell 单元格记录
* @param formatListener {@link FormatTrackingHSSFListener} * @param formatListener {@link FormatTrackingHSSFListener}
* @return 是否为日期格式 * @return 是否为日期格式
@ -227,22 +243,9 @@ public class ExcelSaxUtil {
return DateUtil.date(org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value, false)); return DateUtil.date(org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value, false));
} }
/**
* 创建 {@link ExcelSaxReader}
*
* @param isXlsx 是否为xlsx格式07格式
* @param rowHandler 行处理器
* @return {@link ExcelSaxReader}
* @since 5.4.4
*/
public static ExcelSaxReader<?> createSaxReader(boolean isXlsx, RowHandler rowHandler) {
return isXlsx
? new Excel07SaxReader(rowHandler)
: new Excel03SaxReader(rowHandler);
}
/** /**
* 在Excel03 sax读取中获取日期或数字类型的结果值 * 在Excel03 sax读取中获取日期或数字类型的结果值
*
* @param cell 记录单元格 * @param cell 记录单元格
* @param value * @param value
* @param formatListener {@link FormatTrackingHSSFListener} * @param formatListener {@link FormatTrackingHSSFListener}
@ -251,19 +254,11 @@ public class ExcelSaxUtil {
*/ */
public static Object getNumberOrDateValue(CellValueRecordInterface cell, double value, FormatTrackingHSSFListener formatListener) { public static Object getNumberOrDateValue(CellValueRecordInterface cell, double value, FormatTrackingHSSFListener formatListener) {
Object result; Object result;
if(ExcelSaxUtil.isDateFormat(cell, formatListener)){ if (isDateFormat(cell, formatListener)) {
// 可能为日期格式 // 可能为日期格式
result = ExcelSaxUtil.getDateValue(value); return getDateValue(value);
} else {
final long longPart = (long) value;
// 对于无小数部分的数字类型转为Long否则保留原数字
if (((double) longPart) == value) {
result = longPart;
} else {
result = value;
} }
} return getNumberValue(value, formatListener.getFormatString(cell));
return result;
} }
/** /**
@ -278,9 +273,20 @@ public class ExcelSaxUtil {
if (StrUtil.isBlank(value)) { if (StrUtil.isBlank(value)) {
return null; return null;
} }
double numValue = Double.parseDouble(value); return getNumberValue(Double.parseDouble(value), numFmtString);
}
/**
* 获取数字类型值除非格式中明确数字保留小数否则无小数情况下按照long返回
*
* @param numValue
* @param numFmtString 格式
* @return 数字可以是DoubleLong
* @since 5.5.3
*/
private static Number getNumberValue(double numValue, String numFmtString) {
// 普通数字 // 普通数字
if (null != numFmtString && numFmtString.indexOf(StrUtil.C_DOT) < 0) { if (null != numFmtString && false == StrUtil.contains(numFmtString, CharUtil.DOT)) {
final long longPart = (long) numValue; final long longPart = (long) numValue;
//noinspection RedundantIfStatement //noinspection RedundantIfStatement
if (longPart == numValue) { if (longPart == numValue) {

View File

@ -1,13 +1,10 @@
package cn.hutool.poi.excel.test; package cn.hutool.poi.excel;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.BigExcelWriter;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.style.StyleUtil; import cn.hutool.poi.excel.style.StyleUtil;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.FillPatternType;
@ -163,21 +160,21 @@ public class BigExcelWriteTest {
@Test @Test
@Ignore @Ignore
public void writeBeanTest() { public void writeBeanTest() {
TestBean bean1 = new TestBean(); cn.hutool.poi.excel.TestBean bean1 = new cn.hutool.poi.excel.TestBean();
bean1.setName("张三"); bean1.setName("张三");
bean1.setAge(22); bean1.setAge(22);
bean1.setPass(true); bean1.setPass(true);
bean1.setScore(66.30); bean1.setScore(66.30);
bean1.setExamDate(DateUtil.date()); bean1.setExamDate(DateUtil.date());
TestBean bean2 = new TestBean(); cn.hutool.poi.excel.TestBean bean2 = new cn.hutool.poi.excel.TestBean();
bean2.setName("李四"); bean2.setName("李四");
bean2.setAge(28); bean2.setAge(28);
bean2.setPass(false); bean2.setPass(false);
bean2.setScore(38.50); bean2.setScore(38.50);
bean2.setExamDate(DateUtil.date()); bean2.setExamDate(DateUtil.date());
List<TestBean> rows = CollUtil.newArrayList(bean1, bean2); List<cn.hutool.poi.excel.TestBean> rows = CollUtil.newArrayList(bean1, bean2);
// 通过工具类创建writer // 通过工具类创建writer
String file = "e:/bigWriteBeanTest.xlsx"; String file = "e:/bigWriteBeanTest.xlsx";
FileUtil.del(file); FileUtil.del(file);

View File

@ -1,4 +1,4 @@
package cn.hutool.poi.excel.test; package cn.hutool.poi.excel;
import org.apache.poi.ss.usermodel.BuiltinFormats; import org.apache.poi.ss.usermodel.BuiltinFormats;
import org.junit.Ignore; import org.junit.Ignore;

View File

@ -1,11 +1,9 @@
package cn.hutool.poi.excel.test; package cn.hutool.poi.excel;
import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.lang.Console; import cn.hutool.core.lang.Console;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import lombok.Data; import lombok.Data;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Ignore; import org.junit.Ignore;

View File

@ -1,4 +1,4 @@
package cn.hutool.poi.excel.test; package cn.hutool.poi.excel;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
@ -6,7 +6,6 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Console; import cn.hutool.core.lang.Console;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.cell.FormulaCellValue; import cn.hutool.poi.excel.cell.FormulaCellValue;
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;
@ -138,15 +137,33 @@ public class ExcelSaxReadTest {
} }
@Test @Test
public void dateReadTest() { public void dateReadXlsTest() {
List<String> rows = new ArrayList<>(); List<String> rows = new ArrayList<>();
ExcelUtil.readBySax("data_for_sax_test.xls", 0, (i, i1, list) -> ExcelUtil.readBySax("data_for_sax_test.xls", 0,
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)); Assert.assertEquals("2020-10-09 00:00:00", rows.get(1));
// 非日期格式不做转换 // 非日期格式不做转换
Assert.assertEquals("112233", rows.get(2)); Assert.assertEquals("112233", rows.get(2));
Assert.assertEquals("1000", rows.get(3)); Assert.assertEquals("1000.0", rows.get(3));
Assert.assertEquals("2012-12-21 00:00:00", rows.get(4));
}
@Test
public void dateReadXlsxTest() {
List<String> rows = new ArrayList<>();
ExcelUtil.readBySax("data_for_sax_test.xlsx", 0,
(i, i1, list) -> rows.add(StrUtil.toString(list.get(0)))
);
Assert.assertEquals("2020-10-09 00:00:00", rows.get(1));
// 非日期格式不做转换
Assert.assertEquals("112233", rows.get(2));
Assert.assertEquals("1000.0", rows.get(3));
Assert.assertEquals("2012-12-21 00:00:00", rows.get(4));
} }
@Test @Test

View File

@ -1,6 +1,5 @@
package cn.hutool.poi.excel.test; package cn.hutool.poi.excel;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.cell.CellLocation; import cn.hutool.poi.excel.cell.CellLocation;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;

View File

@ -1,4 +1,4 @@
package cn.hutool.poi.excel.test; package cn.hutool.poi.excel;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
@ -6,8 +6,6 @@ import cn.hutool.core.io.FileUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.style.StyleUtil; import cn.hutool.poi.excel.style.StyleUtil;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.FillPatternType;
@ -340,21 +338,21 @@ public class ExcelWriteTest {
@Test @Test
@Ignore @Ignore
public void writeBeanTest() { public void writeBeanTest() {
TestBean bean1 = new TestBean(); cn.hutool.poi.excel.TestBean bean1 = new cn.hutool.poi.excel.TestBean();
bean1.setName("张三"); bean1.setName("张三");
bean1.setAge(22); bean1.setAge(22);
bean1.setPass(true); bean1.setPass(true);
bean1.setScore(66.30); bean1.setScore(66.30);
bean1.setExamDate(DateUtil.date()); bean1.setExamDate(DateUtil.date());
TestBean bean2 = new TestBean(); cn.hutool.poi.excel.TestBean bean2 = new cn.hutool.poi.excel.TestBean();
bean2.setName("李四"); bean2.setName("李四");
bean2.setAge(28); bean2.setAge(28);
bean2.setPass(false); bean2.setPass(false);
bean2.setScore(38.50); bean2.setScore(38.50);
bean2.setExamDate(DateUtil.date()); bean2.setExamDate(DateUtil.date());
List<TestBean> rows = CollUtil.newArrayList(bean1, bean2); List<cn.hutool.poi.excel.TestBean> rows = CollUtil.newArrayList(bean1, bean2);
// 通过工具类创建writer // 通过工具类创建writer
String file = "e:/writeBeanTest.xlsx"; String file = "e:/writeBeanTest.xlsx";
FileUtil.del(file); FileUtil.del(file);
@ -376,17 +374,17 @@ public class ExcelWriteTest {
@Test @Test
@Ignore @Ignore
public void writeBeanTest2() { public void writeBeanTest2() {
OrderExcel order1 = new OrderExcel(); cn.hutool.poi.excel.OrderExcel order1 = new cn.hutool.poi.excel.OrderExcel();
order1.setId("1"); order1.setId("1");
order1.setNum("123"); order1.setNum("123");
order1.setBody("body1"); order1.setBody("body1");
OrderExcel order2 = new OrderExcel(); cn.hutool.poi.excel.OrderExcel order2 = new cn.hutool.poi.excel.OrderExcel();
order1.setId("2"); order1.setId("2");
order1.setNum("456"); order1.setNum("456");
order1.setBody("body2"); order1.setBody("body2");
List<OrderExcel> rows = CollUtil.newArrayList(order1, order2); List<cn.hutool.poi.excel.OrderExcel> rows = CollUtil.newArrayList(order1, order2);
// 通过工具类创建writer // 通过工具类创建writer
String file = "f:/test/writeBeanTest2.xlsx"; String file = "f:/test/writeBeanTest2.xlsx";
FileUtil.del(file); FileUtil.del(file);

View File

@ -1,4 +1,4 @@
package cn.hutool.poi.excel.test; package cn.hutool.poi.excel;
import lombok.Data; import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.hutool.poi.excel.test; package cn.hutool.poi.excel;
import lombok.Data; import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.hutool.poi.word.test; package cn.hutool.poi.word;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;