2016-11-30 3 views
1

У меня было требование проанализировать очень большие файлы excel с использованием apache poi с ограниченной памятью. После googling я узнал, что poi предоставляет SAX-парсер для эффективного анализа большого файла, не потребляя много памяти.Apache POI SAX Parsing - Как получить фактическое значение ячейки

Apache POI SAX Parser example

private class SheetToCSV implements SheetContentsHandler { 
    private boolean firstCellOfRow = false; 
    private int currentRow = -1; 
    private int currentCol = -1; 

    private void outputMissingRows(int number) { 
     for (int i=0; i<number; i++) { 
      for (int j=0; j<minColumns; j++) { 
       output.append(','); 
      } 
      output.append('\n'); 
     } 
    } 

    @Override 
    public void startRow(int rowNum) { 
     // If there were gaps, output the missing rows 
     outputMissingRows(rowNum-currentRow-1); 
     // Prepare for this row 
     firstCellOfRow = true; 
     currentRow = rowNum; 
     currentCol = -1; 
    } 

    @Override 
    public void endRow(int rowNum) { 
     // Ensure the minimum number of columns 
     for (int i=currentCol; i<minColumns; i++) { 
      output.append(','); 
     } 
     output.append('\n'); 
    } 

    @Override 
    public void cell(String cellReference, String formattedValue, 
      XSSFComment comment) { 
     if (firstCellOfRow) { 
      firstCellOfRow = false; 
     } else { 
      output.append(','); 
     } 

     // gracefully handle missing CellRef here in a similar way as XSSFCell does 
     if(cellReference == null) { 
      cellReference = new CellAddress(currentRow, currentCol).formatAsString(); 
     } 

     // Did we miss any cells? 
     int thisCol = (new CellReference(cellReference)).getCol(); 
     int missedCols = thisCol - currentCol - 1; 
     for (int i=0; i<missedCols; i++) { 
      output.append(','); 
     } 
     currentCol = thisCol; 

     // Number or string? 
     try { 
      Double.parseDouble(formattedValue); 
      output.append(formattedValue); 
     } catch (NumberFormatException e) { 
      output.append('"'); 
      output.append(formattedValue); 
      output.append('"'); 
     } 
    } 

    @Override 
    public void headerFooter(String text, boolean isHeader, String tagName) { 
     // Skip, no headers or footers in CSV 
    } 
} 

В приведенном примере в приведенной выше ссылке, метод «клетка» имеет доступ только к форматированному значению, однако мне нужно, чтобы получить доступ фактического значения ячейки.

+0

Напишите свой собственный обработчик SAX для передачи? – Gagravarr

ответ

2

Текущая реализация потокового интерфейса не предусматривает этого. Поэтому для этого вам необходимо скопировать код базового XSSFSheetXMLHandler и настроить его так, чтобы содержимое ячейки не форматировалось.

+0

Спасибо большое @centic – Arul