2013-06-26 61 views
1

我正在使用POI的事件API来处理大量的记录而没有任何内存足迹问题。 Here是它的推荐。POI XSSF和SAX(事件API)的日期格式问题

当我处理XLSX表,我得到不同的格式的日期值比Excel表中的指定格式。 excel表格中列的日期格式为'dd-mm-yyyy',其中以'mm/dd/yy'格式获取值。

有人可以告诉我如何获得在Excel表中给出的实际格式。代码片段的参考如下。

ContentHandler handler = new XSSFSheetXMLHandler(styles, strings, 
      new SheetContentsHandler() { 
      public void startRow(int rowNum) { 
      } 
      public void endRow() { 
      } 
      public void cell(String cellReference, String formattedValue) { 
        System.out.println(formattedValue); 
       } catch (IOException e) { 
        System.out.println(
         "Exception during file writing"); 
       } 
       } 

获取formmatedValue在细胞的方法对于日期列就像是“MM/DD/YY”,因此我不能能够正确执行的验证在我的PL/SQL程序。

回答

2

Excel使用区域设置存储一些日期。例如,在Excel中的数字格式对话框中,您将看到如下警告:

根据您指定的类型和区域设置(位置),将日期和时间序列号显示为日期值。以星号(*)开头的日期格式响应“控制面板”中指定的区域日期和时间设置中的更改。没有星号的格式不受控制面板设置的影响。

您正在阅读的Excel文件可能正在使用其中一个*日期。在这种情况下,POI可能使用美国默认值。

您可能需要添加一些变通办法代码来将日期格式字符串映射为所需的格式。

关于regional date settings in Excel的讨论,另请参阅以下内容。

+0

那么;这是绝对好的。当我手动将语言环境更改为英国时,获得预期的价值(dd-mm-yyyy)。不过,我想用宏替换区域设置,因为我的工作表正在使用另一个宏表生成。有什么想法? – hemanth

4

我有同样的问题。经过几天的搜索和研究,我想出了一个解决方案。不幸的是,它不好,但它的工作原理:

  1. 在您的项目中复制org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler类。
  2. 查找类中的接口SheetContentsHandler
  3. 添加新的方法定义:String overriddenFormat(String cellRef, int formatIndex, String formatString);
  4. 在该类中查找此方法:public void endElement(String uri, String localName, String name) throws SAXException
  5. 它有一个很长的切换单元格类型。
  6. 在这种情况下NUMBER有一个,如果这样的语句:if (this.formatString != null) {...
  7. 在此之前,粘贴此代码:

    String overriddenFormat = output.overriddenFormat(cellRef, formatIndex, formatString); 
    if (overriddenFormat != null) { 
        this.formatIndex = -1; 
        this.formatString = overriddenFormat; 
    } 
    
  8. 按照本文/回答:https://stackoverflow.com/a/11345859但使用新的类和接口。

  9. 现在,如果需要,您可以使用唯一的日期格式。

我的使用情况是: 在一个给定的表我有G,H日期值,和我列,所以我实施SheetContentsHandler.overriddenFormat是:

@Override 
public String overriddenFormat(String cellRef, int formatIndex, String formatString) { 
    if (cellRef.matches("(G|H|I)\\d+")) { //matches all cells in G, H, and I columns 
     return "yyyy-mm-dd;@"; //this is the hungarian date format in excel 
    } 
    return null; 
} 

正如你所看到的,在endElement方法我已经重写了formatIndex和formatString。格式索引的可能值在org.apache.poi.ss.usermodel.DateUtil.isInternalDateFormat(int format)中描述。如果给定的值不适合这些(并且-1不适合),那么将通过格式化时间戳值来使用formatString。 (时间戳值从约1900.01.01开始计算并且具有日分辨率。)