获取 ShapeGroup 中的所有形状
Get all shapes in ShapeGroup
我的代码基本上是这样的:
worksheet.getDrawingPatriarch().getShapes().get(0)
这将 return XSSFShapeGroup 对象,但是从这一点上我不知道如何在组中获取 XSSFSimpleShape 或 XSSFShape。我想输出该组中每个形状的位置(行和列),但我不知道如何从组中提取它们。
要从形状组 (XSSFShapeGroup
) 中获取 XSSFSimpleShape
或 XSSFShape
到现在为止无法使用 apache poi。
从 CTGroupShape 开始可以获得低级 CTShapes。但是“输出该组中每个形状的位置(行和列)”几乎是不可能的,因为该组只有一个锚点(行,列),并且所有分组的形状都相对于该锚点以单位 EMU
(英制单位)。
所以我们可以得到形状组的锚点和EMU
中组成员相对于该锚点的位置:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTConnector;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphicalObjectFrame;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPicture;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShape;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;
import java.io.*;
class ReadGroupedShapes {
public static void main(String[] args) {
try {
InputStream inp = new FileInputStream("Shapegroup.xlsx");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
XSSFDrawing drawing = (XSSFDrawing)sheet.getDrawingPatriarch();
for (XSSFShape shape : drawing.getShapes()) {
// possible: XSSFConnector, XSSFGraphicFrame, XSSFPicture, XSSFShapeGroup, XSSFSimpleShape
if (shape instanceof XSSFConnector) {
//System.out.println(((XSSFConnector)shape).getCTConnector());
} else if (shape instanceof XSSFGraphicFrame) {
//System.out.println(((XSSFGraphicFrame)shape).getCTGraphicalObjectFrame());
} else if (shape instanceof XSSFPicture) {
//System.out.println(((XSSFPicture)shape).getCTPicture());
} else if (shape instanceof XSSFShapeGroup) { //we have a shape group
//System.out.println(((XSSFShapeGroup)shape).getCTGroupShape());
System.out.println("Whole group is anchored upper left:");
int groupRow = ((XSSFClientAnchor)shape.getAnchor()).getRow1();
long groupRowDy = ((XSSFClientAnchor)shape.getAnchor()).getDy1();
System.out.print("Row: " + groupRow);
System.out.println(" + " + groupRowDy + " EMU");
int groupCol = ((XSSFClientAnchor)shape.getAnchor()).getCol1();
long groupColDx = ((XSSFClientAnchor)shape.getAnchor()).getDx1();
System.out.print("Col: " + groupCol);
System.out.println(" + " + groupColDx + " EMU");
//go through all shapes in the group
for (CTConnector lowLewelConnector : ((XSSFShapeGroup)shape).getCTGroupShape().getCxnSpList()) {
//System.out.println(lowLewelConnector);
System.out.println("A connector is in the group:");
String cxnName = lowLewelConnector.getNvCxnSpPr().getCNvPr().getName();
String cxnDescr = lowLewelConnector.getNvCxnSpPr().getCNvPr().getDescr();
System.out.println("Name: " + cxnName + ((!"".equals(cxnDescr)) ? ": " + cxnDescr : ""));
System.out.println("positioned upper left:");
long connectorDy = lowLewelConnector.getSpPr().getXfrm().getOff().getY();
System.out.println("Row " + groupRow + " + " + groupRowDy + " + " + connectorDy + " EMU");
long connectorDx = lowLewelConnector.getSpPr().getXfrm().getOff().getX();
System.out.println("Col " + groupCol + " + " + groupColDx + " + " + connectorDx + " EMU");
}
for (CTGraphicalObjectFrame lowLewelGrFrame : ((XSSFShapeGroup)shape).getCTGroupShape().getGraphicFrameList()) {
//System.out.println(lowLewelGrFrame);
}
for (CTPicture lowLewelPic : ((XSSFShapeGroup)shape).getCTGroupShape().getPicList()) {
//System.out.println(lowLewelPic);
System.out.println("A picture is in the group:");
String picName = lowLewelPic.getNvPicPr().getCNvPr().getName();
String picDescr = lowLewelPic.getNvPicPr().getCNvPr().getDescr();
System.out.println("Name: " + picName + ((!"".equals(picDescr)) ? ": " + picDescr : ""));
System.out.println("positioned upper left:");
long pictDy = lowLewelPic.getSpPr().getXfrm().getOff().getY();
System.out.println("Row " + groupRow + " + " + groupRowDy + " + " + pictDy + " EMU");
long pictDx = lowLewelPic.getSpPr().getXfrm().getOff().getX();
System.out.println("Col " + groupCol + " + " + groupColDx + " + " + pictDx + " EMU");
}
for (CTGroupShape lowLewelGroupShape : ((XSSFShapeGroup)shape).getCTGroupShape().getGrpSpList()) {
//System.out.println(lowLewelGroupShape);
}
for (CTShape lowLewelShape : ((XSSFShapeGroup)shape).getCTGroupShape().getSpList()) {
//System.out.println(lowLewelShape);
System.out.println("A simple shape is in the group:");
String spName = lowLewelShape.getNvSpPr().getCNvPr().getName();
String spDescr = lowLewelShape.getNvSpPr().getCNvPr().getDescr();
System.out.println("Name: " + spName + ((!"".equals(spDescr)) ? ": " + spDescr : ""));
System.out.println("positioned upper left:");
long simpleShapeDy = lowLewelShape.getSpPr().getXfrm().getOff().getY();
System.out.println("Row " + groupRow + " + " + groupRowDy + " + " + simpleShapeDy + " EMU");
long simpleShapeDx = lowLewelShape.getSpPr().getXfrm().getOff().getX();
System.out.println("Col " + groupCol + " + " + groupColDx + " + " + simpleShapeDx + " EMU");
}
} else if (shape instanceof XSSFSimpleShape) {
//System.out.println(((XSSFSimpleShape)shape).getCTShape());
}
}
} catch (InvalidFormatException ifex) {
} catch (FileNotFoundException fnfex) {
} catch (IOException ioex) {
}
}
}
2016 年 10 月,当前 apache poi
版本为 3.14
或 3.15
。现在在 2021 年,我们的版本为 5.0.0
,并且情况发生了变化。
现在(自 apache poi 3.17
起)ShapeContainer 提供了一个遍历所有形状的迭代器。 XSSFShapeGroup
也实现了 ShapeContainer
。所以上面的低级类用法就没有必要了。要从 XSSFDrawing
and/or 中获取所有形状,现在 XSSFShapeGroup
很简单:
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.usermodel.ShapeContainer;
import org.apache.poi.xssf.usermodel.*;
import java.io.FileInputStream;
class ReadGroupedShapes {
static 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);
} else if (shape instanceof XSSFShapeGroup) { //we have a shape group
XSSFShapeGroup shapeGroup = (XSSFShapeGroup)shape;
System.out.println(shapeGroup);
traverseShapeContainer(shapeGroup); // we now can simply get the XSSFShapeGroup as ShapeContainer<XSSFShape>
} else if (shape instanceof XSSFSimpleShape) {
XSSFSimpleShape simpleShape = (XSSFSimpleShape)shape;
System.out.println(simpleShape);
}
}
}
public static void main(String[] args) throws Exception {
FileInputStream in = new FileInputStream("Shapegroup.xlsx");
XSSFWorkbook wb = (XSSFWorkbook)WorkbookFactory.create(in);
XSSFSheet sheet = wb.getSheetAt(0);
XSSFDrawing drawing = sheet.getDrawingPatriarch();
traverseShapeContainer(drawing);
}
}
我的代码基本上是这样的:
worksheet.getDrawingPatriarch().getShapes().get(0)
这将 return XSSFShapeGroup 对象,但是从这一点上我不知道如何在组中获取 XSSFSimpleShape 或 XSSFShape。我想输出该组中每个形状的位置(行和列),但我不知道如何从组中提取它们。
要从形状组 (XSSFShapeGroup
) 中获取 XSSFSimpleShape
或 XSSFShape
到现在为止无法使用 apache poi。
从 CTGroupShape 开始可以获得低级 CTShapes。但是“输出该组中每个形状的位置(行和列)”几乎是不可能的,因为该组只有一个锚点(行,列),并且所有分组的形状都相对于该锚点以单位 EMU
(英制单位)。
所以我们可以得到形状组的锚点和EMU
中组成员相对于该锚点的位置:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTConnector;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphicalObjectFrame;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTPicture;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShape;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;
import java.io.*;
class ReadGroupedShapes {
public static void main(String[] args) {
try {
InputStream inp = new FileInputStream("Shapegroup.xlsx");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
XSSFDrawing drawing = (XSSFDrawing)sheet.getDrawingPatriarch();
for (XSSFShape shape : drawing.getShapes()) {
// possible: XSSFConnector, XSSFGraphicFrame, XSSFPicture, XSSFShapeGroup, XSSFSimpleShape
if (shape instanceof XSSFConnector) {
//System.out.println(((XSSFConnector)shape).getCTConnector());
} else if (shape instanceof XSSFGraphicFrame) {
//System.out.println(((XSSFGraphicFrame)shape).getCTGraphicalObjectFrame());
} else if (shape instanceof XSSFPicture) {
//System.out.println(((XSSFPicture)shape).getCTPicture());
} else if (shape instanceof XSSFShapeGroup) { //we have a shape group
//System.out.println(((XSSFShapeGroup)shape).getCTGroupShape());
System.out.println("Whole group is anchored upper left:");
int groupRow = ((XSSFClientAnchor)shape.getAnchor()).getRow1();
long groupRowDy = ((XSSFClientAnchor)shape.getAnchor()).getDy1();
System.out.print("Row: " + groupRow);
System.out.println(" + " + groupRowDy + " EMU");
int groupCol = ((XSSFClientAnchor)shape.getAnchor()).getCol1();
long groupColDx = ((XSSFClientAnchor)shape.getAnchor()).getDx1();
System.out.print("Col: " + groupCol);
System.out.println(" + " + groupColDx + " EMU");
//go through all shapes in the group
for (CTConnector lowLewelConnector : ((XSSFShapeGroup)shape).getCTGroupShape().getCxnSpList()) {
//System.out.println(lowLewelConnector);
System.out.println("A connector is in the group:");
String cxnName = lowLewelConnector.getNvCxnSpPr().getCNvPr().getName();
String cxnDescr = lowLewelConnector.getNvCxnSpPr().getCNvPr().getDescr();
System.out.println("Name: " + cxnName + ((!"".equals(cxnDescr)) ? ": " + cxnDescr : ""));
System.out.println("positioned upper left:");
long connectorDy = lowLewelConnector.getSpPr().getXfrm().getOff().getY();
System.out.println("Row " + groupRow + " + " + groupRowDy + " + " + connectorDy + " EMU");
long connectorDx = lowLewelConnector.getSpPr().getXfrm().getOff().getX();
System.out.println("Col " + groupCol + " + " + groupColDx + " + " + connectorDx + " EMU");
}
for (CTGraphicalObjectFrame lowLewelGrFrame : ((XSSFShapeGroup)shape).getCTGroupShape().getGraphicFrameList()) {
//System.out.println(lowLewelGrFrame);
}
for (CTPicture lowLewelPic : ((XSSFShapeGroup)shape).getCTGroupShape().getPicList()) {
//System.out.println(lowLewelPic);
System.out.println("A picture is in the group:");
String picName = lowLewelPic.getNvPicPr().getCNvPr().getName();
String picDescr = lowLewelPic.getNvPicPr().getCNvPr().getDescr();
System.out.println("Name: " + picName + ((!"".equals(picDescr)) ? ": " + picDescr : ""));
System.out.println("positioned upper left:");
long pictDy = lowLewelPic.getSpPr().getXfrm().getOff().getY();
System.out.println("Row " + groupRow + " + " + groupRowDy + " + " + pictDy + " EMU");
long pictDx = lowLewelPic.getSpPr().getXfrm().getOff().getX();
System.out.println("Col " + groupCol + " + " + groupColDx + " + " + pictDx + " EMU");
}
for (CTGroupShape lowLewelGroupShape : ((XSSFShapeGroup)shape).getCTGroupShape().getGrpSpList()) {
//System.out.println(lowLewelGroupShape);
}
for (CTShape lowLewelShape : ((XSSFShapeGroup)shape).getCTGroupShape().getSpList()) {
//System.out.println(lowLewelShape);
System.out.println("A simple shape is in the group:");
String spName = lowLewelShape.getNvSpPr().getCNvPr().getName();
String spDescr = lowLewelShape.getNvSpPr().getCNvPr().getDescr();
System.out.println("Name: " + spName + ((!"".equals(spDescr)) ? ": " + spDescr : ""));
System.out.println("positioned upper left:");
long simpleShapeDy = lowLewelShape.getSpPr().getXfrm().getOff().getY();
System.out.println("Row " + groupRow + " + " + groupRowDy + " + " + simpleShapeDy + " EMU");
long simpleShapeDx = lowLewelShape.getSpPr().getXfrm().getOff().getX();
System.out.println("Col " + groupCol + " + " + groupColDx + " + " + simpleShapeDx + " EMU");
}
} else if (shape instanceof XSSFSimpleShape) {
//System.out.println(((XSSFSimpleShape)shape).getCTShape());
}
}
} catch (InvalidFormatException ifex) {
} catch (FileNotFoundException fnfex) {
} catch (IOException ioex) {
}
}
}
2016 年 10 月,当前 apache poi
版本为 3.14
或 3.15
。现在在 2021 年,我们的版本为 5.0.0
,并且情况发生了变化。
现在(自 apache poi 3.17
起)ShapeContainer 提供了一个遍历所有形状的迭代器。 XSSFShapeGroup
也实现了 ShapeContainer
。所以上面的低级类用法就没有必要了。要从 XSSFDrawing
and/or 中获取所有形状,现在 XSSFShapeGroup
很简单:
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.usermodel.ShapeContainer;
import org.apache.poi.xssf.usermodel.*;
import java.io.FileInputStream;
class ReadGroupedShapes {
static 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);
} else if (shape instanceof XSSFShapeGroup) { //we have a shape group
XSSFShapeGroup shapeGroup = (XSSFShapeGroup)shape;
System.out.println(shapeGroup);
traverseShapeContainer(shapeGroup); // we now can simply get the XSSFShapeGroup as ShapeContainer<XSSFShape>
} else if (shape instanceof XSSFSimpleShape) {
XSSFSimpleShape simpleShape = (XSSFSimpleShape)shape;
System.out.println(simpleShape);
}
}
}
public static void main(String[] args) throws Exception {
FileInputStream in = new FileInputStream("Shapegroup.xlsx");
XSSFWorkbook wb = (XSSFWorkbook)WorkbookFactory.create(in);
XSSFSheet sheet = wb.getSheetAt(0);
XSSFDrawing drawing = sheet.getDrawingPatriarch();
traverseShapeContainer(drawing);
}
}