2015-09-04 7 views
0

Я разбираю листы excel (xlsx) в веб-приложении. Я использую Apache POI, Streaming API, потому что у меня большие файлы. Теперь Excel внутренне сохраняет даты как число, например, например. Я получаю 42035 вместо 31.01.2012. Поскольку я использую разбор XML, я не могу получить доступ к методам dateformatting, предоставляемым POI. Есть идеи?Как извлечь дату как дату не как текст из Excel с помощью потоковой передачи POI (SAX XML)

Вот анализатор (из этого примера https://poi.apache.org/spreadsheet/how-to.html#xssf_sax_api, но изменилось):

/** 
* See org.xml.sax.helpers.DefaultHandler javadocs 
*/ 
private static class SheetHandler extends DefaultHandler { 

    private SharedStringsTable table; 
    private String lastContents; 
    private boolean nextIsString; 
    boolean isFirstRow = true; 
    private int quantityOfColumns; 
    private int currentColumnNumber = 1; 
    int currentRowNumber = 1; 
    private int rowNumberOfLastCell = 1; 
    private DataSet data = new DataSet(); 
    private Tuple tuple; 

    static final Logger LOG = LoggerFactory.getLogger(SheetHandler.class); 

    private SheetHandler(SharedStringsTable sst) { 
     this.table = sst; 
     LOG.debug("Sheethandler created"); 
    } 

    @Override 
    public void startElement(String uri, String localName, String name, 
      Attributes attributes) throws SAXException { 
     // c => cell 
     LOG.debug("Reading element of type {} ", name); 
     if (name.equals("c")) { 
      rowNumberOfLastCell = currentRowNumber; 
      String cellType = attributes.getValue("t"); 
      LOG.debug("Extracting cell {} with type {}", attributes.getValue("r"), cellType); 
      currentRowNumber = extractIntFromString(attributes.getValue("r")); 
      if (isFinishedRowHeaderRow()) { 
       extractHeaders(); 
      } 
      // Figure out if the value is an index in the SST (Static String Table) 
      if (cellType != null && cellType.equals("s")) { 
       System.out.println("We have content!"); 
       nextIsString = true; 
      } else { 
       nextIsString = false; 
      } 
     } 
     // Clear contents cache 
     lastContents = ""; 
    } 

    private boolean isFinishedRowHeaderRow() { 
     return (rowNumberOfLastCell != currentRowNumber) && isFirstRow; 
    } 

    private void extractHeaders() { 
     quantityOfColumns = data.getHeaders().size(); 
     LOG.debug("{} rows detected", quantityOfColumns); 
     LOG.debug("{} headers parsed", data.getHeaders().size()); 
     isFirstRow = false; 
     currentColumnNumber = 1; 
     tuple = new Tuple(quantityOfColumns); 
    } 

    @Override 
    public void characters(char[] ch, int start, int length) 
      throws SAXException { 
     lastContents += new String(ch, start, length); 
     LOG.debug("Extracted value \"{}\"", lastContents); 
    } 

    @Override 
    public void endElement(String uri, String localName, String name) 
      throws SAXException { 
     // Process the last contents as required. 
     // Do now, as characters() may be called more than once 
     if (nextIsString) { 
      extractStringFromCell(); 
     } 
     // v => contents of a cell 
     // Output after we've seen the string contents 
     if (name.equals("v")) { 
      addExtractedValueToDataSet(); 
      LOG.debug("Ended parsing of column {}", currentColumnNumber); 
      if (currentColumnNumber == (quantityOfColumns)) { 
       concludeRow(); 
      } else { 
       currentColumnNumber++; 
      } 
     } 
    } 

    private void concludeRow() { 
     data.addRow(tuple); 
     LOG.debug("Row added to DataSet"); 
     tuple = new Tuple(quantityOfColumns); 
     currentColumnNumber = 1; 
     LOG.debug("Row {} parsed", rowNumberOfLastCell); 
    } 

    private void addExtractedValueToDataSet() { 
     if (isFirstRow) { 
      data.getHeaders().add(lastContents); 
     } else { 
      tuple.getRowEntries()[currentColumnNumber - 1] = lastContents; 
     } 
    } 

    private void extractStringFromCell() throws NumberFormatException { 
     int idx = Integer.parseInt(lastContents); 
     lastContents = new XSSFRichTextString(table.getEntryAt(idx)).toString(); 
     LOG.debug("Extracted value \"{}\"", lastContents); 
     nextIsString = false; 
    } 

    public int extractIntFromString(String original) { 
     char[] chars = original.toCharArray(); 
     for (int i = 0; i < chars.length; i++) { 
      try { 
       return Integer.valueOf(original.substring(i, original.length())); 
      } catch (NumberFormatException ex) { 
      } 
     } 
     return 0; 
    } 

    public DataSet getData() { 
     return data; 
    } 
} 
+1

Вы пробовали [DateUtil.getJavaDate (double)] (https://poi.apache.org/apidocs/org/apache/poi/ss/usermodel/DateUtil.html#getJavaDate (double)) (просто гадать)? – agad

+1

Пробовал ли вы читать какие-либо потоковые примеры Apache POI xlsx, большинство из которых показывают, как использовать даты? – Gagravarr

ответ

 Смежные вопросы

  • Нет связанных вопросов^_^