簡體   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