0

我对 Apache POI XSSF 有疑问,因为它没有读取空白单元格值。

我有一个实现 DefaultHandler 的类。在该类中,所有非空白单元格都能够从 startElement 和 endElement 方法中读取。

我想读取数据单元格中间的空白单元格。

任何人都可以提供如何执行此操作的示例或有关如何调试的说明吗?

4

3 回答 3

2

今天遇到了同样的问题。我使用的是 XSSF 事件模型。但是 XSSF 不会为空白列提供列元素或值元素。很可能是因为支持 XML 就是这种方式。

关键是检查单元格引用的属性(您知道 Excel 使用的 A1、A2、A3)。属性被传递给startElement()回调方法。然后我们可以检测丢失的单元格引用。因此,如果我们为前一列元素获取 L1 并为当前列元素获取 N1,我们知道 M1 是空白/缺失单元格。

public void startElement(String uri, String localName, String qName,        Attributes atts) throws SAXException {
if (qName.equals("c")) {
    String newColRef = atts.getValue("r");
    coverColumnDistanceWithNulls(currentColRef, newColRef);

并且coverColumnDistanceWithNulls()只需为 currentColRef 和 newColRef 之间的每个缺失单元格引用添加空值

private void coverColumnDistanceWithNulls(String fromColRefString, String toColRefString) {
    int colRefDistance = getDistance(fromColRefString, toColRefString);
    while (colRefDistance > 1) {
        logger.debug("Covering distance with null");
        rowValues.add(null);
        --colRefDistance;
    }
}

private int getDistance(String fromColRefString, String toColRefString) {
    String fromColRef = getExcelCellRef(fromColRefString);
    String toColRef = getExcelCellRef(toColRefString);
    logger.debug("fromCol: {} toCol: {}", new Object[] {fromColRefString, toColRefString});
    return excelCellReferenceOrder.get(toColRef) - excelCellReferenceOrder.get(fromColRef);
}

private String getExcelCellRef(String fromColRef) {
    if (fromColRef != null) {
        int i = 0;
        for (;i < fromColRef.length(); i++) {
            if (Character.isDigit(fromColRef.charAt(i))) {
                break;
            }
        }
        if (i == 0) {
            return fromColRef;
        }
        else {
            return fromColRef.substring(0, i);
        }
    }
    return null;
}
于 2013-02-19T13:29:04.877 回答
1

以 Sab Than 的回答为基础:

private void coverColumnDistance(String fromColRefString, String toColRefString) {
    int colRefDistance = getDistance(fromColRefString, toColRefString);
    while (colRefDistance > 0) {
        c = getRow().addCell("");
        colRefDistance--;
    }
}

private int getDistance(String fromColRefString, String toColRefString) {
    String fromColRef = getExcelCellRef(fromColRefString);
    String toColRef = getExcelCellRef(toColRefString);
    int distance = 0;
    if (fromColRef == null || fromColRef.compareTo(toColRef) > 0)
        return getDistance("A", toColRefString) + 1;
    if (fromColRef != null && toColRef != null) {
        while (fromColRef.length() < toColRef.length() || fromColRef.compareTo(toColRef) < 0) {
            distance++;
            fromColRef = increment(fromColRef);
        }
    }
    return distance;
}

public String increment(String s) {
    int length = s.length();
    char c = s.charAt(length - 1);

    if(c == 'Z') {
        return length > 1 ? increment(s.substring(0, length - 1)) + 'A' : "AA";
    }

    return s.substring(0, length - 1) + ++c;
}

private String getExcelCellRef(String fromColRef) {
    if (fromColRef != null) {
        int i = 0;
        for (; i < fromColRef.length(); i++) {
            if (Character.isDigit(fromColRef.charAt(i))) {
                break;
            }
        }
        if (i == 0) {
            return fromColRef;
        }
        else {
            return fromColRef.substring(0, i);
        }
    }
    return null;
}
于 2014-12-30T19:40:49.403 回答
0

如果我没记错的话,如果您尝试读取尚未分配值的单元格值,您会得到 NullPointerException 或类似的。您可以在 try-catch 语句中包围检查单元格的代码,然后编写自己的代码来处理这种情况。

如果我的记忆不能正确地为我服务并且抛出的错误不是 NullPointerException,那么将 catch 异常类更改为相关的类。

于 2012-05-15T18:14:55.353 回答