POI sax从Cell获取日期

时间:2015-08-11 13:17:06

标签: apache-poi sax

我正在用sax阅读excel文件,所有工作都在预期日期。日期读作“41751”,这是从1900年开始的天数。应该有一些formatString,我可以用它来格式化,但它是null。

起始元素()

Meteor.Error

结束元素()

this.nextDataType = xssfDataType.NUMBER;
        this.formatIndex = -1;
        this.formatString = null;
        String cellType = attributes.getValue("t");
        String cellStyleStr = attributes.getValue("s");
        if ("b".equals(cellType))
            nextDataType = xssfDataType.BOOL;
        else if ("e".equals(cellType))
            nextDataType = xssfDataType.ERROR;
        else if ("inlineStr".equals(cellType))
            nextDataType = xssfDataType.INLINESTR;
        else if ("s".equals(cellType))
            nextDataType = xssfDataType.SSTINDEX;
        else if ("str".equals(cellType))
            nextDataType = xssfDataType.FORMULA;
        else if (cellType == null) {
            maybeNull=true;
        } else if (cellStyleStr != null) {
            // It's a number, but almost certainly one
            //  with a special style or format
            int styleIndex = Integer.parseInt(cellStyleStr);
            XSSFCellStyle style = stylesTable.getStyleAt(styleIndex);
            this.formatIndex = style.getDataFormat();
            this.formatString = style.getDataFormatString();
            if (this.formatString == null)
                this.formatString = BuiltinFormats.getBuiltinFormat(this.formatIndex);
        }

如何获取该日期或如何找到该单元格包含日期而不是某个整数。完整的处理程序代码在这里http://pastebin.com/GveeMf4n 感谢

1 个答案:

答案 0 :(得分:3)

如果你查看Apache POI Example for converting a .xlsx file to .csv with SAX event parsing,就会看到你需要做什么

基本上,当您读取单元格时,不仅需要捕获类型和内容,还需要捕获s样式索引属性,然后从加载的样式表中查找类似DOM的方式(它很小),例如

public void startElement(String uri, String localName, String name,
                             Attributes attributes) throws SAXException {
   this.formatIndex = -1;
   this.formatString = null;
   String cellStyleStr = attributes.getValue("s");
   if (cellStyleStr != null) {
       // It's a number, but almost certainly one
       //  with a special style or format 
       XSSFCellStyle style = null;
       if (cellStyleStr != null) {
           int styleIndex = Integer.parseInt(cellStyleStr);
           style = stylesTable.getStyleAt(styleIndex);
       } else if (stylesTable.getNumCellStyles() > 0) {
           style = stylesTable.getStyleAt(0);
       }
       if (style != null) {
           this.formatIndex = style.getDataFormat();
           this.formatString = style.getDataFormatString();
           if (this.formatString == null)
               this.formatString = BuiltinFormats.getBuiltinFormat(this.formatIndex);
       }
    }

    // Rest of start element logic here

然后,当您到达单元格的结束标记时,您可以使用DataFormatter根据样式格式化单元格的数字内容(即日期,%或类似内容)你之前发现的,例如

public void endElement(String uri, String localName, String name)
            throws SAXException {
        String thisStr = null;

    // v => contents of a cell
    if ("v".equals(name)) {
        // Process the value contents as required.
        // Do now, as characters() may be called more than once
        switch (nextDataType) {
                case NUMBER:
                    String n = value.toString();
                    if (this.formatString != null)
                        thisStr = formatter.formatRawCellContents(Double.parseDouble(n), this.formatIndex, this.formatString);
                    else
                        thisStr = n;
                    break;

基本上,技巧是读取StylesTable,在读取单元格开始时捕获格式字符串,然后在有单元格内容时用DataFormatter格式化数字字符串。

查看source code to the XLSX2CSV example以了解该

的有效实施情况