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());
尝试替换:
StringUtils.isNotEmpty(c.toString())
跟:
StringUtils.isNotEmpty(null == c ? "" : c.toString())
或避免使用第三方库和更短的库(如 Holger 建议的那样(:
c!=null && !c.toString().isEmpty()
过滤所有空单元格:
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());
潜在的null
候选者是getRow
的结果,在.mapToObj(i -> sheet.getRow(i))
年获得,但在.map(col -> row.getCell(col.getColumnIndex()))
行中首先取消引用。
另请注意,最后一个filter
是有问题的,因为您正在使用实用程序函数来测试可能null
字符串的空性,但List.toString()
的结果永远不会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());
请注意,内部列表仍然可以包含null
元素,具体取决于配置的MissingCellPolicy
。将工作簿配置为始终获取空白单元格比从行列表中删除null
元素更可取,以使所有行列表的列表索引对齐。