当前位置: 首页 > 知识库问答 >
问题:

尝试访问XSSFShape的父级会导致NullPointerException

上官德寿
2023-03-14

在尝试遍历ShapeContainer的内部内容时,我希望通过检查XSSFShapeGroup的父项来区分XSSFPicture和不是XSSFPicture的子项:

private void traverseShapeContainer(ShapeContainer<XSSFShape> container) {
    for (XSSFShape shape : container) {
          // Other types of XSSFShapes have not been mentioned here.
          if (shape instanceof XSSFPicture) {
            XSSFPicture picture = (XSSFPicture) shape;
            System.out.println(shape.getParent() instanceof XSSFShapeGroup); // Always outputs false
            System.out.println(Objects.isNull(shape.getParent())); // Always outputs true
        } else if (shape instanceof XSSFShapeGroup) {
            XSSFShapeGroup shapeGroup = (XSSFShapeGroup) shape;
            // accessing inner contents of XSSFShapeGroup
            traverseShapeContainer(shapeGroup);
        }
    }
}

无论XSSFPicture是否是XSSFShapeGroup的子级,这对于每种情况都是相同的。

  • 测试1:检查ShapeContainer是否为XSSFShapeGroup的实例。
System.out.println(Objects.isNull(container instanceof XSSFShapeGroup)); // Output: false
  • 测试2:访问子节点后查找父标记。
if (shape instanceof XSSFPicture) {
   XSSFPicture picture = (XSSFPicture) shape;
   // "xdr:grpSp" is the tag for XSSFShapeGroup
   System.out.println(picture.getCTPicture().getDomNode().getParentNode().getNodeName()
                      .equals("xdr:grpSp")); // Output: true
}

这清楚地表明父级确实存在,并且还允许我们在进程中检查父级。

我还没有检查其他类型的XSSFShapes,如XSSFSimpleShapeXSSFConnector。但是,由于它们都继承了同一个类,即xssfshape,我想结果不会有太大不同。

共有1个答案

东郭良弼
2023-03-14

这是因为Apache poi直到现在(2021年5月,版本Apache poi 5.0.0)还不完整。它影响形状组中的所有形状。

XSSFShape.getParent只是返回XSSFShapeGroup Parent的类成员XSSFShapeGroup Parent。但在解析Office Open XML绘图时,apache poi只执行以下操作:

...
 } else if (obj instanceof CTGroupShape) {
  shape = new XSSFShapeGroup(this, (CTGroupShape) obj);
 }...

请参见https://svn.apache.org/viewvc/poi/tags/rel_5_0_0/src/ooxml/java/org/apache/poi/xssf/usermodel/xssfdrawing.java?view=markup#l619。

XSSFShapeGroup的构造函数只是

protected XSSFShapeGroup(XSSFDrawing drawing, CTGroupShape ctGroup) {
 this.drawing = drawing;
 this.ctGroup = ctGroup;
}

请参见https://svn.apache.org/viewvc/poi/tags/rel_5_0_0/src/ooxml/java/org/apache/poi/xssf/usermodel/xssfshapegroup.java?view=markup#l55。

这样就不需要遍历该组中的所有形状并将其父形状设置为该形状组。因此始终为

例如:

...
 ... void traverseShapeContainer(ShapeContainer<XSSFShape> container) {
  for (XSSFShape shape : container) { 
   // possible:   XSSFConnector, XSSFGraphicFrame, XSSFPicture, XSSFShapeGroup, XSSFSimpleShape
   if (shape instanceof XSSFConnector) {
    XSSFConnector connector = (XSSFConnector)shape;
    System.out.println(connector);

   } else if (shape instanceof XSSFGraphicFrame) {
    XSSFGraphicFrame graphicFrame = (XSSFGraphicFrame)shape;
    System.out.println(graphicFrame);

   } else if (shape instanceof XSSFPicture) {
    XSSFPicture picture = (XSSFPicture)shape;
    System.out.println(picture);
    if (container instanceof XSSFDrawing) {
     System.out.println("Picture is in drawing directly.");
    } else if (container instanceof XSSFShapeGroup) {
     System.out.println("Picture is in shape group.");
     XSSFShapeGroup parent = (XSSFShapeGroup) container;
     System.out.println("Parent is " +  parent);
    }

   } else if (shape instanceof XSSFShapeGroup) { //we have a shape group
    XSSFShapeGroup shapeGroup = (XSSFShapeGroup)shape;
    System.out.println(shapeGroup);

    traverseShapeContainer(shapeGroup); // we now can sinply get the XSSFShapeGroup as ShapeContainer<XSSFShape>

   } else if (shape instanceof XSSFSimpleShape) {
    XSSFSimpleShape simpleShape = (XSSFSimpleShape)shape;
    System.out.println(simpleShape);

   }
  }

 }
...
 类似资料:
  • 我试图升级我目前的java项目,运行在1.6到1.8,但程序编译良好如何曾经当我去http://localhost:8080/MyProject/login.jsp-我得到错误。 我正在使用eclipse luna,我将java\u HOME更改为1.8,将eclipse项目facets更改为1.8,并更新了javax。servlet api=3.1.0。 堆栈跟踪 无布局。jsp 我用常春藤做依

  • 我正在尝试访问在“MyClass”的@RequestMapping父级中定义的@PathVariables。简化的screnario: 此类是某种产品的基类,不应进行编辑。因此,我扩展了“父类”。在“MyClass”中,我想做如下操作: 我认为这是允许的(还没有测试),但我不知道如何获得所有已经用“ParentClass”定义的PathVariable。 非常感谢您的任何想法/RTFM参考。

  • 每当我试图获取SpringMVC的时,都会抛出一个。 这是我的用户道: 线程“main”java.lang.NullPointerException位于com.markor.smarthome.utilites.SpringContextutil.getBeans(SpringContextutil.java:31)位于com.markor.smarthome.dao.userdao.(userd

  • 我正在进行搜索,然后循环搜索结果。这会导致我的代码被锁定,更糟糕的是,它会锁定数据库,使其无法进一步使用。即使在浏览器关闭之后。当然,在我再次尝试我的代码之前,这种“锁定”似乎会在一段时间后被清除。我将改变我执行这项特定任务的方式,但我很好奇是什么导致了这种锁定。

  • 你好,我正在尝试创建一个类,它使用从学生类到研究生类的继承,但程序说它是不可访问的。 程序应该打印出一个初始化的GraduateStudent类变量,调用printStudent();

  • 我有嵌套片段,片段内部片段。使用NavigationBottomView。当我从父片段反压到子片段时,一切都正常。 但是现在,如果我在子片段中,突然我的手机屏幕熄灭,如果我再次打开屏幕并从我离开的地方反压,它不会消失,我想它是忘记或清除我的背包。不知道为什么。我在下面的github链接上做了一个演示 github演示链接在这里