commit
3afdea9d5d
@ -33,7 +33,7 @@ easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>easyexcel</artifactId>
|
||||
<version>4.0.2</version>
|
||||
<version>4.0.3</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
|
@ -1,3 +1,20 @@
|
||||
/* ====================================================================
|
||||
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
contributor license agreements. See the NOTICE file distributed with
|
||||
this work for additional information regarding copyright ownership.
|
||||
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
(the "License"); you may not use this file except in compliance with
|
||||
the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
==================================================================== */
|
||||
|
||||
package com.alibaba.excel.util;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@ -9,13 +26,16 @@ import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.poi.ss.usermodel.DateUtil;
|
||||
import org.apache.poi.util.LocaleUtil;
|
||||
|
||||
/**
|
||||
* Date utils
|
||||
@ -63,6 +83,15 @@ public class DateUtils {
|
||||
|
||||
public static String defaultLocalDateFormat = DATE_FORMAT_10;
|
||||
|
||||
public static final int SECONDS_PER_MINUTE = 60;
|
||||
public static final int MINUTES_PER_HOUR = 60;
|
||||
public static final int HOURS_PER_DAY = 24;
|
||||
public static final int SECONDS_PER_DAY = (HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
|
||||
|
||||
// used to specify that date is invalid
|
||||
private static final int BAD_DATE = -1;
|
||||
public static final long DAY_MILLISECONDS = SECONDS_PER_DAY * 1000L;
|
||||
|
||||
private DateUtils() {}
|
||||
|
||||
/**
|
||||
@ -301,13 +330,75 @@ public class DateUtils {
|
||||
* @return Java representation of the date, or null if date is not a valid Excel date
|
||||
*/
|
||||
public static Date getJavaDate(double date, boolean use1904windowing) {
|
||||
//To calculate the Date, in the use of `org.apache.poi.ss.usermodel.DateUtil.getJavaDate(double, boolean,
|
||||
// java.util.TimeZone, boolean), Date when similar `2023-01-01 00:00:00.500`, returns the`2023-01-01
|
||||
// 00:00:01`, but excel in fact shows the `2023-01-01 00:00:00`.
|
||||
// `org.apache.poi.ss.usermodel.DateUtil.getLocalDateTime(double, boolean, boolean)` There is no problem.
|
||||
return Date.from(getLocalDateTime(date, use1904windowing).atZone(ZoneId.systemDefault()).toInstant());
|
||||
Calendar calendar = getJavaCalendar(date, use1904windowing, null, true);
|
||||
return calendar == null ? null : calendar.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get EXCEL date as Java Calendar with given time zone.
|
||||
* @param date The Excel date.
|
||||
* @param use1904windowing true if date uses 1904 windowing,
|
||||
* or false if using 1900 date windowing.
|
||||
* @param timeZone The TimeZone to evaluate the date in
|
||||
* @param roundSeconds round to closest second
|
||||
* @return Java representation of the date, or null if date is not a valid Excel date
|
||||
*/
|
||||
public static Calendar getJavaCalendar(double date, boolean use1904windowing, TimeZone timeZone, boolean roundSeconds) {
|
||||
if (!isValidExcelDate(date)) {
|
||||
return null;
|
||||
}
|
||||
int wholeDays = (int)Math.floor(date);
|
||||
int millisecondsInDay = (int)((date - wholeDays) * DAY_MILLISECONDS + 0.5);
|
||||
Calendar calendar;
|
||||
if (timeZone != null) {
|
||||
calendar = LocaleUtil.getLocaleCalendar(timeZone);
|
||||
} else {
|
||||
calendar = LocaleUtil.getLocaleCalendar(); // using default time-zone
|
||||
}
|
||||
setCalendar(calendar, wholeDays, millisecondsInDay, use1904windowing, roundSeconds);
|
||||
return calendar;
|
||||
}
|
||||
|
||||
|
||||
public static void setCalendar(Calendar calendar, int wholeDays,
|
||||
int millisecondsInDay, boolean use1904windowing, boolean roundSeconds) {
|
||||
int startYear = 1900;
|
||||
int dayAdjust = -1; // Excel thinks 2/29/1900 is a valid date, which it isn't
|
||||
if (use1904windowing) {
|
||||
startYear = 1904;
|
||||
dayAdjust = 1; // 1904 date windowing uses 1/2/1904 as the first day
|
||||
}
|
||||
else if (wholeDays < 61) {
|
||||
// Date is prior to 3/1/1900, so adjust because Excel thinks 2/29/1900 exists
|
||||
// If Excel date == 2/29/1900, will become 3/1/1900 in Java representation
|
||||
dayAdjust = 0;
|
||||
}
|
||||
calendar.set(startYear, Calendar.JANUARY, wholeDays + dayAdjust, 0, 0, 0);
|
||||
calendar.set(Calendar.MILLISECOND, millisecondsInDay);
|
||||
if (calendar.get(Calendar.MILLISECOND) == 0) {
|
||||
calendar.clear(Calendar.MILLISECOND);
|
||||
}
|
||||
if (roundSeconds) {
|
||||
// This is different from poi where you need to change 500 to 499
|
||||
calendar.add(Calendar.MILLISECOND, 499);
|
||||
calendar.clear(Calendar.MILLISECOND);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given a double, checks if it is a valid Excel date.
|
||||
*
|
||||
* @return true if valid
|
||||
* @param value the double value
|
||||
*/
|
||||
|
||||
public static boolean isValidExcelDate(double value)
|
||||
{
|
||||
return (value > -Double.MIN_VALUE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Given an Excel date with either 1900 or 1904 date windowing,
|
||||
* converts it to a java.time.LocalDateTime.
|
||||
|
@ -3,10 +3,12 @@ package com.alibaba.easyexcel.test.core.dataformat;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.alibaba.easyexcel.test.util.TestFileUtil;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
@ -22,6 +24,7 @@ import org.junit.jupiter.api.TestMethodOrder;
|
||||
@Slf4j
|
||||
public class DateFormatTest {
|
||||
|
||||
private static File file07V2;
|
||||
private static File file07;
|
||||
private static File file03;
|
||||
|
||||
@ -29,6 +32,8 @@ public class DateFormatTest {
|
||||
public static void init() {
|
||||
file07 = TestFileUtil.readFile("dataformat" + File.separator + "dataformat.xlsx");
|
||||
file03 = TestFileUtil.readFile("dataformat" + File.separator + "dataformat.xls");
|
||||
file07V2 = TestFileUtil.readFile("dataformat" + File.separator + "dataformatv2.xlsx");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -43,6 +48,19 @@ public class DateFormatTest {
|
||||
readUs(file03);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void t03Read() {
|
||||
List<Map<Integer, String>> dataMap = EasyExcel.read(file07V2).headRowNumber(0).doReadAllSync();
|
||||
log.info("dataMap:{}", JSON.toJSONString(dataMap));
|
||||
Assertions.assertEquals("15:00", dataMap.get(0).get(0));
|
||||
Assertions.assertEquals("2023-1-01 00:00:00", dataMap.get(1).get(0));
|
||||
Assertions.assertEquals("2023-1-01 00:00:00", dataMap.get(2).get(0));
|
||||
Assertions.assertEquals("2023-1-01 00:00:01", dataMap.get(3).get(0));
|
||||
Assertions.assertEquals("2023-1-01 00:00:00", dataMap.get(4).get(0));
|
||||
Assertions.assertEquals("2023-1-01 00:00:00", dataMap.get(5).get(0));
|
||||
Assertions.assertEquals("2023-1-01 00:00:01", dataMap.get(6).get(0));
|
||||
}
|
||||
|
||||
private void readCn(File file) {
|
||||
List<DateFormatData> list =
|
||||
EasyExcel.read(file, DateFormatData.class, null).locale(Locale.CHINA).sheet().doReadSync();
|
||||
|
BIN
easyexcel-test/src/test/resources/dataformat/dataformatv2.xlsx
Normal file
BIN
easyexcel-test/src/test/resources/dataformat/dataformatv2.xlsx
Normal file
Binary file not shown.
2
pom.xml
2
pom.xml
@ -20,7 +20,7 @@
|
||||
|
||||
|
||||
<properties>
|
||||
<revision>4.0.2</revision>
|
||||
<revision>4.0.3</revision>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<jdk.version>1.8</jdk.version>
|
||||
<gpg.skip>true</gpg.skip>
|
||||
|
Loading…
x
Reference in New Issue
Block a user