从 CellComment 检索 ClientAnchor 时的 POI 3.17 NPE

POI 3.17 NPE while retrieving ClientAnchor from CellComment

在同一工作簿中尝试将 CellComments 从一个 sheet 复制到另一个 sheet 时,CellComment ClientAnchor 的检索收到 NPE。

java.lang.NullPointerException at org.apache.poi.xssf.usermodel.XSSFComment.getClientAnchor(XSSFComment.java:220)

使用的代码:

for (Entry<CellAddress, ? extends Comment> e : sheet.getCellComments().entrySet())
  {
    CellAddress addr = e.getKey();
    Comment comment = e.getValue();
    ClientAnchor anchor = comment.getClientAnchor();

这是POI还是检索码的问题?

请注意,以下代码有效并检索 ClientAnchor。

  for (CellAddress addr : sheet.getCellComments().keySet())
  {
    Comment comment = sheet.getCellComment(addr);
    ClientAnchor anchor = comment.getClientAnchor();

这绝对是 apache poi 的问题,至少 apache poi 版本 3.17 是这样。这种问题是我不在 apache poi 的开发者名单中的原因之一。

以下都是关于apache poi版本3.17

如果XSSFComment.java:220抛出NPE,那么_vmlShape就是null。那么什么是_vmlShape呢?它是一个 com.microsoft.schemas.vml.CTShape,通常在 XSSFComment 的构造函数中设置。

public XSSFComment(CommentsTable comments, CTComment comment, CTShape vmlShape).

那么为什么 XSSFSheet.getCellComments().entrySet()Entry 的值可以是 null

XSSFSheetpublic Map getCellComments() returns sheetComments.getCellComments(). So what is sheetComments? It is a org.apache.poi.xssf.model.CommentsTable which was read while reading the sheet's package part from the worbook.

那又怎样returnssheetComments.getCellComments()?它 returns 一个 final TreeMap<CellAddress, XSSFComment> map,其中每个值都是一个 XSSFComment。但是所有这些 XSSFComment 都是新建的 CTShape vmlShape = null: map.put(e.getKey(), new XSSFComment(this, e.getValue(), null));.

嗯,这就是为什么 _vmlShapenullXSSFComment.java 代码行 220 抛出 NPE 的原因。

以及为什么 sheet.getCellComment(addr)addrCellAddress 作为相同 TreeMap<CellAddress, XSSFComment> 的键?

因为那里的程序员已经知道 VMLDrawing 的必要性,请参阅 public XSSFComment getCellComment(CellAddress address)