Java ApachePOI:检查列是否为空

Java ApachePOI:检查列是否为空,java,excel,apache-poi,Java,Excel,Apache Poi,我需要检查.xlsx文件中的列是否为空,但找不到比此更平滑的列: 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

我需要检查.xlsx文件中的列是否为空,但找不到比此更平滑的列:

    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
正是您想要开始的行(实际上我的列不是完全空的,还有一个标题)


我想知道你们中的一些人是否有更好的想法

答案取决于工作表中物理行的稀疏程度、对简单代码的渴望以及对执行速度的关注程度

这三种方法的一个很好的折衷方案只能循环物理行,并且只要
startRow
getLastRowNum()
更接近
getFirstRowNum()

如果您真的关心性能,可以分叉POI并编写一个方法来公开
TreeMap
,该
xssfheet
用于访问行。 然后您可以使用
\u rows.tailMap(startRow,inclusive=true)
访问最小行数


如果在POI bugzilla上为返回
java.util.Collections.unmodifiableSortedMap(_rows.subMap(startRow,true,endRow,true))
from HSSF、XSSF和SXSSF的方法添加补丁和测试用例(如果开始行或结束行在访问窗口之外,或者使用类似于自动调整列跟踪器的列跟踪器,则失败),然后将isColumnEmpty函数添加到相应的类中,这样,如果您的修补程序被接受,您就可以避免维护fork。

您可能还需要检查
空白的
单元格-这些单元格通常是在中没有值的单元格,但有些是空白的formatting@Gagravarr你确实是对的。我改了密码@还有,我说的是列,而不是行。除非我遗漏了什么?@assylias我很确定情况并非如此,因为ApachePOI中似乎没有提供任何内容来通过这些列。但我理解你的想法。
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;
}
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;
    }
}