Apache POI - 使用 HSSFListener 解析日期

Apache POI - Parsing Dates with HSSFListener

首先,我正在使用 Apache POI 的事件 API 使用 HSSFListener 和 XSSFSheetXMLHandler.SheetContentsHandler 来读取大文件。所以我没有使用可以使用一些方便方法的工作簿。我已经用这种方法实现了它并出现了 OOM 错误。

对于 XLS 文件,我无法弄清楚如何根据 NumberRecord 确定格式是日期格式还是数字格式。我看过这个旧的 link (Using Apache POI HSSFListener how to identify date type),但只有 Tika link 有效,因为另一个已不存在。似乎一些修改可以与 FormatTrackingHSSFListener 一起使用,但我在那里遗漏了一些东西。

我看到有人提到使用 DateUtil 来检查值是否在如下所示的 InternalDateFormat 中,但这没有用。

case NumberRecord.sid:
    NumberRecord numrec = (NumberRecord) record;
    if (DateUtil.isInternalDateFormat(numrec.getXFIndex())) {
        System.out.println("Cell found with date value " + DateUtil.getJavaDate(numrec.getValue())
                + " at row " + numrec.getRow() + " and column " + numrec.getColumn());
    } else {
        System.out.println("Cell found with value " + numrec.getValue()
                + " at row " + numrec.getRow() + " and column " + numrec.getColumn());
    }

我想知道 isADateFormat 方法是否有效 (https://poi.apache.org/apidocs/dev/org/apache/poi/ss/usermodel/DateUtil.html#isADateFormat-int-java.lang.String-),但我不知道 formatString 是什么。

想法?非常感激。文档有点在那里,但通过它是“有趣的”。

如果其他人对此有疑问,我已经在另一个问题中的 TIKA extractor link 的帮助下解决了这个问题。我建议实现一个 HSSFListener,它本身有一个 FormatTrackingHSSFListener 作为成员变量。这将是您的初始侦听器并将捕获所有格式(如果我理解正确的话),并且它本身将具有您的实现的子侦听器。

public class YourListener implements HSSFListener {

    private SSTRecord sstRecord;
    private FormatTrackingHSSFListener formatListener;
    private List<String> sheetNames = new ArrayList<>();
    private Integer currentSheetIndex = -1;
    private Integer rowCount = 0;

    public YourListener() {
        this.formatListener = new FormatTrackingHSSFListener(this);
    }
}

当您覆盖 processRecord 时,NumberRecord.sid 的开关可以调用 formatListener 的 formatNumberDateCell。所以像:

case NumberRecord.sid: // Contains a numeric cell value
     NumberRecord number = (NumberRecord) record;
     System.out.println(record, formatListener.formatNumberDateCell(number));
     break;