繁体   English   中英

使用Apache POI从java中的excel表中读取数据

[英]Read data from excel sheet in java with Apache POI

我在 excel 表中有一个数据需要在 java 中读取,我能够读取普通字符串但是当我尝试读取包含日期和时间的单元格时 (28/5/2018 10:00) 我只得到日期为 2018 年 5 月 28 日。

这是excel单元格

在此处输入图片说明

此代码读取:28-May-2018

在此处输入图片说明

row.getCell(6).toString()

此代码引发异常:

row.getCell(6).getStringCellValue()

我怎样才能读懂时间?

如何正确读取日期?

tl;博士

row                              // Starting with a Poi `Row` object.
.getCell(6)                      // Extract a Poi `Cell` object.
.getDateCellValue()              // Extract value from spreadsheet as a `java.util.Date` object. This terrible class is now legacy. Immediately convert to java.time.Instant as seen on next line.
.toInstant()                     // Convert from legacy `java.util.Date` class to modern `java.time.Instant`. Both represent a moment in UTC.
.atZone(                         // Adjusting from UTC to a time zone.
    ZoneId.of( "Asia/Tokyo" )    // Specify a time zone to adjust from UTC (an offset of zero hours-minutes-seconds). 
)                                // Returns a `ZonedDateTime` object. Same moment, different wall-clock time.
.toLocalDate()                   // Extract the date-only portion. Or call `toLocalTime` for the time-of-day portion.

细节

其他答案正确显示了如何获取java.util.Date对象。 但是那个类(a)很糟糕,并且(b)现在是遗留的,多年前被现代java.time类取代。 您需要走得更远才能找到合适的解决方案。

得到你的java.util.Date对象后:

java.util.Date javaUtilDate = row.getCell(6).getDateCellValue() ;

...您有一个 UTC 时间。 不幸的是,按照建议调用Date::toString

row.getCell(6).getDateCellValue().toString() 

...造成了令人困惑的结果。 该方法应用 JVM 的当前默认时区,从 UTC 调整到某个时区。 这造成了这个时区是java.util.Date一部分的错觉,但事实并非如此。 这种行为意味着您的结果在运行时会有所不同,具体取决于当前的默认时区可能是什么。 请注意,不仅用户可以更改默认时区,在该 JVM 中运行的任何应用程序的任何线程中的任何代码也可以更改。

对于可预测的结果,您应该指定所需/预期的时区。

为此,请立即将您的java.util.Date转换为它的替代品Instant类。 两者都代表 UTC 中的一个时刻。 请注意添加到旧遗留类中的新转换方法。

Instant instant = javaUtilDate.toInstant() ;

Continent/Region格式指定正确的时区名称,例如America/MontrealAfrica/CasablancaPacific/Auckland 永远不要使用ESTIST等 2-4 个字母的缩写,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId zoneId = ZoneId.of( "Africa/Tunis" ) ;

如果您想使用 JVM 的当前默认时区,请明确要求并作为参数传递。 如果省略,代码读起来会变得模棱两可,因为我们不确定您是否打算使用默认值,或者您是否像许多程序员一样没有意识到这个问题。

ZoneId zoneId = ZoneId.systemDefault() ;  // Get JVM’s current default time zone.

将该时区应用于您的 UTC 时刻。

ZonedDateTime zdt = instant.atZone( zoneId ) ;

生成的ZonedDateTime对象表示与Instant相同的时刻,时间线上的相同同时点。 但它的挂钟时间已调整为特定地区(时区)的人们使用的时间。

你问:

我怎样才能读懂时间?

如何正确读取日期?

您可以使用DateTimeFormatter以您想要的任何格式打印其中一种或两种格式,甚至可以自动本地化为Locale对象中定义的人类语言和文化规范。

或者,您可以将日期和时间值提取为单独的对象。

LocalDate localDate = zdt.toLocalDate() ;
LocalTime localTime = zdt.toLocalTime() ;

Java 中的日期时间类型表,现代和传统


关于java.time

java.time框架内置于 Java 8 及更高版本中。 这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar ,和SimpleDateFormat

要了解更多信息,请参阅Oracle 教程 并在 Stack Overflow 上搜索许多示例和解释。 规范是JSR 310

现在处于维护模式Joda-Time项目建议迁移到java.time类。

您可以直接与您的数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC 驱动程序 不需要字符串,不需要java.sql.*类。

从哪里获得 java.time 类?

ThreeTen-Extra项目用额外的类扩展了 java.time。 该项目是未来可能添加到 java.time 的试验场。 您可以在这里找到一些有用的类,比如IntervalYearWeekYearQuarter ,和更多

尝试

row.getCell(6).getDateCellValue();

如果你仍然需要它是一个字符串,试试

row.getCell(6).getDateCellValue().toString();

我希望这会有所帮助

try (FileInputStream fis = new FileInputStream(filename)) {
        HSSFWorkbook workbook = new HSSFWorkbook(fis);
        HSSFSheet sheet = workbook.getSheetAt(0);

        // Read a cell the first row and sixth cell.
        HSSFCell cell = sheet.getRow(0).getCell(6);


        // Using HSSFDateUtil to check if a cell contains a date.
        if (HSSFDateUtil.isCellDateFormatted(cell)) {
            System.out.println("The cell contains a date value: "
                + cell.getDateCellValue());
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }

要将单元格值作为Excel单元格中所示的格式化字符串获取,请使用DataFormatter

例子:

...
DataFormatter formatter = new DataFormatter(); 
...
Row row = ...;
...
Cell cell = row.getCell(6);
String value = formatter.formatCellValue(cell);
System.out.println(value);
...

并且因为该值可能是公式的结果,所以使用DataFormatterFormulaEvaluator

...
DataFormatter formatter = new DataFormatter(); 
...
Workbook workbook = ...;
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); 
...
Row row = ...;
...
Cell cell = row.getCell(6);
String value = formatter.formatCellValue(cell, evaluator);
System.out.println(value);
...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM