如何使用 Apache POI 将此 "strange" 单元格值检索解析 Excel 正确转换为日期对象?

How to correctly convert into a Date object this "strange" cell value retrieve parsing an Excel using Apache POI?

我正在尝试使用 Apache POI 从 Java 解析 Excel 并且我发现以下问题解析包含日期的特定列.

这是我的 Excel 文件中的列:

如您所见,此列包含日期字段,但此列的某些单元格包含 number 值,其他一些单元格包含 text 值(我可以使用 TYPE() Excel 函数看到它)。我真的不知道这怎么可能,因为所有单元格都包含日期字段。有什么想法吗?

无论如何,在我的代码中,我试图以这种方式处理这种奇怪的情况:

if(currentRow.getCell(20) != null && !currentRow.getCell(20).toString().trim().isEmpty()) {
    
    if(currentRow.getCell(20).getCellType().toString().equals("STRING")) {
        System.out.println("Data sottoscrizione contratto è STRING: " + currentRow.getCell(20).toString());
        
    }
    else if(currentRow.getCell(20).getCellType().toString().equals("NUMERIC")) {
        System.out.println("Data sottoscrizione contratto è NUMERIC");
        String dateAsString = currentRow.getCell(20).toString();
        System.out.println("DATA SOTTOSCRIZIONE CONTRATTO: " + currentRow.getCell(20).toString());
        
        
    }
}

通过这种方式,我可以处理尝试转换为日期的两种情况。

这是我的问题。当它在 if NUMERIC case

中找到 Excel 数值时

并通过以下方式打印单元格值:

System.out.println("DATA SOTTOSCRIZIONE CONTRATTO: " + currentRow.getCell(20).toString());

我打印了与日期值 16/10/2017

相关的值 16-ott-2017

还有一些疑问:为什么我要以这种格式获取而不是 16/10/2017.

16-ott-2017 应该是日期的意大利语格式。我怎样才能将它转换成合适的 Date 对象?

布翁乔尔诺!

您当前使用的是单元格的toString()方法,该方法在返回数值甚至日期时都不会很准确。它有时可能会起作用,但不会总是起作用。

使用获得真实价值的方法,例如 Cell.getNumericCellValue(), Cell.getDateCellValue() (outdated because it returns a java.util.Date) or Cell.getLocalDateTimeCellValue(). If your cell just contains text, like "16-ott-2020", use the getStringCellValue() 并将返回的值转换为 LocalDate(或 LocalDateTime 取决于 时间天对你很重要)。

这是一个转换示例(到 LocalDate):

public static void main(String[] args) {
    // assuming you alread received the value as String
    String cellStringValue = "16-ott-2020";
    // provice a formatter that can parse Italian month names (or days of week)
    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MMM-uuuu", Locale.ITALIAN);
    // parse the String to a LocalDate
    LocalDate sediciOttobreDuemilaEVenti = LocalDate.parse(cellStringValue, dtf);
    // and print its default value
    System.out.println(sediciOttobreDuemilaEVenti);
    // alternatively use the same formatter for output
    System.out.println(sediciOttobreDuemilaEVenti.format(dtf));
}

该代码的输出是

2020-10-16
16-ott-2020
case NUMERIC:
                if(Cell.getLocalDateTimeCellValue()!=null) {
                    LocalDateTime actualdate = Cell.getLocalDateTimeCellValue();
                    String formattedDate = actualdate.format(DateTimeFormatter.ofPattern("MM/dd/yyyy"));
                    System.out.println(formattedDate);

                }
                break;
switch (Cell.getCellType()) {
            case STRING: 
                 System.out.print(Cell.getStringCellValue());
                 break;
            case NUMERIC:
                DataFormatter df = new DataFormatter();
                String CellValue = df.formatCellValue(Cell);
                System.out.println(CellValue);
                break;
            case BOOLEAN: 
                System.out.print(Cell.getBooleanCellValue());
                break;          
            
            case BLANK:
                System.out.println("");
            }   
            System.out.print(" | ");
        }