【问题标题】:Excel Cell Style issueExcel 单元格样式问题
【发布时间】:2016-01-20 12:52:20
【问题描述】:

我正在使用以下代码从 XLSX 文件中获取日期值。对于某些 XLSX 文件,这绝对可以正常工作,但它没有给出 XLSX 文件中的确切日期格式。此问题适用于某些文件。

例如,我有这样的日期21/01/2016 (dd/mm/yyyy),但在阅读后,它给出的日期为01/21/16(mm/dd/yy)

有没有其他方法可以获得cellstyle?

是XLSX文件的问题吗?

String dateFmt = cell.getCellStyle().getDataFormatString();
                
if (DateUtil.isCellDateFormatted(cell)) {
    double val = cell.getNumericCellValue();
    Date date = DateUtil.getJavaDate(val);

    String dateFmt = cell.getCellStyle().getDataFormatString();
                                    
    System.out.println("dateFmt "+dateFmt);

    value = new CellDateFormatter(dateFmt).format(date);
                                    
    System.out.println("Date "+value);
                                
}

【问题讨论】:

    标签: java excel apache-poi xssf


    【解决方案1】:

    如果包含日期的单元格被格式化为默认日期格式 (Short Date),则只有格式 id 0xE (14) 存储在文件中。见https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/BuiltinFormats.html*.xlsx 文件只包含

    <xf numFmtId="14" ... applyNumberFormat="1"/>

    styles.xml。没有为此 numFmtId 保存特殊的 formatCode

    所以Excel 中的显示方式取决于系统的区域设置。

    例如,在我的德国 Windows 系统中,numFmtId="14" 将显示为 TT.MM.JJJJ,这是在 Region and Language 设置中设置的:

    在英国英语 Windows 系统中,默认情况下为 DD/MM/YYYY

    但如果你将系统设置中Short Date的设置更改为JJJJ-MM-TT,那么这种格式也会在Excel中显示为numFmtId="14"

    因此,要知道 Excel 将如何准确地显示带有 numFmtId="14" 的日期,需要知道 Region and Language 中的确切 Windows 系统设置。

    所以 apache POI 在不知道系统的区域设置的情况下也无法知道应该如何显示,因为该文件不包含有关此的信息。所以它将假定en-us 语言环境。这导致m/d/yy 日期。

    您可以检查是否使用了格式 id 14,如果是,请定义您自己的默认日期格式。

       if (DateUtil.isCellDateFormatted(cell)) {
        Date date = cell.getDateCellValue();
    
        System.out.println(date);
    
        String dateFmt = "";
    
        if (cell.getCellStyle().getDataFormat() == 14) { //default short date without explicit formatting
         dateFmt = "dd/mm/yyyy"; //default date format for this
        } else { //other data formats with explicit formatting
         dateFmt = cell.getCellStyle().getDataFormatString();
        }
    
        System.out.println("dateFmt " + dateFmt);
    
        String value = new CellDateFormatter(dateFmt).format(date);
    
        System.out.println("Date " + value);
    
       }
    

    要明确:这一切都只适用于numFmtId="14"cell.getCellStyle().getDataFormat() == 14。所有其他日期格式都有明确的数据格式字符串cell.getCellStyle().getDataFormatString(),因此 POI 可以像在 Excel 中一样显示它们。


    请参阅POI DataFormatter returns 2 digits year instead of 4 digits year for date cells,了解如何使用DataFormatter 解决此问题。

    【讨论】:

    • @AxelRitcher 感谢您提供这些有用的信息。我正在寻找它,但没有得到任何解释。
    • @AxelRitcher 您的解决方案有效。谢谢你。但还有一个问题。有没有办法从 excel 中获取现有格式或阅读日期?
    • "有没有办法从 excel 中获取现有格式或读取日期?"不,如果日期格式为 numFmtId="14" 并且我们不知道运行 Excel 的 Windows 系统的 Region and Language 设置,则不会。
    • 除 14 之外的所有其他日期格式都将具有明确的数据格式字符串 cell.getCellStyle().getDataFormatString()。因此,对于 14 岁以外的人,无需阅读 cell.getCellStyle().getDataFormat()
    • 请参阅stackoverflow.com/questions/53228302/…,了解如何使用DataFormatter 解决此问题。
    猜你喜欢
    • 1970-01-01
    • 2021-12-06
    • 2010-12-23
    • 1970-01-01
    • 1970-01-01
    • 2022-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多