2016-07-05 3 views
1

мне нужно проверить, если столбец пуст или не .xlsx файлов, но не могу найти что-нибудь более гладкое, чем это:Apache POI: Проверьте, если столбец пуст

public static boolean isColumnEmpty(int column, int firstRow, XSSFSheet sheet) { 


    XSSFRow row = sheet.getRow(firstRow); 

    while (row != null) { 
     Cell c = row.getCell(column, Row.RETURN_BLANK_AS_NULL); 
     if (c != null) { 
      return false; 
     } 
     row = sheet.getRow(firstRow++); 
    } 
    return true; 

} 

firstRow просто строка вам хотите начать (на самом деле мой столбец не полностью пуст, все равно есть заголовок).

Интересно, были ли у некоторых из вас лучшие идеи!

+0

http://stackoverflow.com/questions/12217047/how-to-determine-empty-row – assylias

+2

Возможно, вам также необходимо проверить ячейки «Пустые» - те, которые, как правило, не имеют значения, но некоторые форматирование – Gagravarr

+0

@Gagravarr Вы действительно правы. Я изменил код! – Fitz

ответ

2

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

Хороший компромисс из трех будет только проходить через физические ряды и выполнять прилично хорошо, пока startRow намного ближе к getFirstRowNum(), чем getLastRowNum().

public static boolean isColumnEmpty(Sheet sheet, int columnIndex, int startRow) { 
    for (Row row : sheet) { 
     if (row.getRowNum() < startRow) continue; 
     Cell cell = row.getCell(columnIndex, Row.RETURN_BLANK_AS_NULL); 
     if (cell != null) { 
      return false; 
     } 
    } 
    return true; 
} 

Для книги с плотными рядами ваш код лучше.

Для кода, который делает меньше работы, вы могли бы объединить эти два подхода (я предпочитаю for -loops над while -loops, как это быстрее, чтобы убедиться, что ваш код не будет застревать в бесконечном цикле)

public static boolean isColumnEmpty(Sheet sheet, int columnIndex, int startRow) { 
    int firstRow = sheet.getFirstRowNum(); 
    int lastRow = sheet.getLastRowNum(); 
    // No need to check rows above the first row 
    startRow = Math.max(startRow, firstRow); 
    int numRows = sheet.getPhysicalNumberOfRows(); 

    // Compute an estimate of the number of rows that each method 
    // will access. 
    // Assume the cost to access one row is the same 
    // between an explicit getRow() or through the rowIterator. 
    // Assume physical rows are uniformly spaced, which is unlikely true 
    // but the best estimate possible without iterating over the rows. 
    double rowDensity = (lastRow - firstRow + 1)/numRows; 
    double estimatedForEachLoopCost = numRows; 
    double estimatedForLoopCost = (lastRow - startRow) + 1) * rowDensity; 
    if (estimatedForEachLoopCost < estimatedForLoopCost) { 
     // for-each iteration 
     for (Row row : sheet) { 
      if (row.getRowNum() < startRow) continue; 
      Cell cell = row.getCell(columnIndex, Row.RETURN_BLANK_AS_NULL); 
      if (cell != null) { 
       return false; 
      } 
     } 
     return true; 
    } else { 
     for (int r=startRow; r<=lastRow; r++) { 
      Row row = sheet.getRow(r); 
      if (row == null) continue; 
      Cell cell = row.getCell(columnIndex, Row.RETURN_BLANK_AS_NULL); 
      if (cell != null) { 
       return false; 
      } 
     } 
     return true; 
    } 
} 

Если вы действительно забота о производительности, вы можете раскошелиться POI и написать метод, чтобы разоблачить TreeMap<Integer, XSSFRow> что XSSFSheet использует для доступа к строкам. Тогда вы можете получить доступ к минимальному количеству строк с помощью _rows.tailMap(startRow, inclusive=true).

Если вы установили патч и тестовый пример в POI bugzilla для метода, который возвращает java.util.Collections.unmodifiableSortedMap(_rows.subMap(startRow, true, endRow, true)) из HSSF, XSSF и SXSSF (сбой, если начальная строка или конечная строка находятся вне окна доступа или использует колонковый трекер, аналогичный autosize tracker), затем добавьте функцию isColumnEmpty в соответствующий класс, тогда вы можете избежать поддержки вилки, если ваш патч будет принят.

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