在解析apache poi中的空单元时获取NPE?

时间:2018-01-09 08:02:05

标签: java lambda java-stream

protected List<List<XSSFCell>> read2DTable(XSSFSheet sheet) {
    LOGGER.debug("read2DTable START");
    List<XSSFCell> headerCells = readTableHeader(sheet);
    List<List<XSSFCell>>  allRows = IntStream.range(sheet.getFirstRowNum(), sheet.getLastRowNum()+1)
                .mapToObj(i -> sheet.getRow(i))
                .map(row -> headerCells.stream()
                                       .map(col -> row.getCell(col.getColumnIndex()))
                                       .collect(Collectors.toList()))
                .filter(c -> StringUtils.isNotEmpty(c.toString()))
                .collect(Collectors.toList());

    LOGGER.info("rows read: {}, columns read: {}", allRows, headerCells.size());
    LOGGER.info("read2DTable END");

    return allRows;
}

这是错误:

 Caused by: java.lang.NullPointerException
        at com.netcracker.solutions.gtdc.cim.importdata.processing.excel.ExcelProcessor.lambda$null$9(ExcelProcessor.java:162)
        at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
        at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
        at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
        at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
        at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
        at com.netcracker.solutions.gtdc.cim.importdata.processing.excel.ExcelProcessor.lambda$read2DTable$10(ExcelProcessor.java:162)

发生在这里:

     .map(col -> row.getCell(col.getColumnIndex()))
    .collect(Collectors.toList()))
.filter(c ->StringUtils.isNotEmpty(c.toString()))
.collect(Collectors.toList());

3 个答案:

答案 0 :(得分:1)

尝试更换:

page_result

使用:

StringUtils.isNotEmpty(c.toString())

或避免使用第三方库并缩短(如Holger所示):

StringUtils.isNotEmpty(null == c ? "" : c.toString())

答案 1 :(得分:0)

过滤所有空单元格:

List<List<XSSFCell>>  allRows = IntStream.range(sheet.getFirstRowNum(), sheet.getLastRowNum()+1)
        .mapToObj(i -> sheet.getRow(i))
        .map(row -> headerCells.stream()
                .map(col -> row.getCell(col.getColumnIndex()))
                .collect(Collectors.toList()))
        .filter(Obejcts::nonNull)
        .filter(c -> StringUtils.isNotEmpty(c.toString()))
        .collect(Collectors.toList());

答案 2 :(得分:0)

成为null的一个潜在候选人是getRow的结果,是.mapToObj(i -> sheet.getRow(i))中获得的,但首先在.map(col -> row.getCell(col.getColumnIndex()))行中取消引用。

另请注意,最后一个filter是有问题的,因为您使用实用程序函数来测试可能null字符串的空白,但List.toString()的结果永远不会{{1并且永远不会为空,因为空null的表示形式为List

固定代码如下:

"[]"

请注意,内部列表仍可包含List<List<XSSFCell>> allRows =IntStream.range(sheet.getFirstRowNum(), sheet.getLastRowNum()+1) .mapToObj(i -> sheet.getRow(i)) // you may also use .mapToObj(sheet::getRow) .filter(Objects::nonNull) .map(row -> headerCells.stream() .map(col -> row.getCell(col.getColumnIndex())) .collect(Collectors.toList())) .filter(list -> !list.isEmpty()) .collect(Collectors.toList()); 元素,具体取决于配置的MissingCellPolicy。将工作簿配置为始终获取空白单元格,最好从行列表中删除null个元素,以保持所有行列表的列表索引对齐。