mirror of https://github.com/apache/poi.git
#60521 - Enable nested XSSF GroupShapes and fix calculation of Client-/ChildAnchor
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1776820 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
6a44282608
commit
14c98d456a
|
@ -277,7 +277,7 @@ public class ImageUtils {
|
|||
}
|
||||
|
||||
|
||||
private static double getRowHeightInPixels(Sheet sheet, int rowNum) {
|
||||
public static double getRowHeightInPixels(Sheet sheet, int rowNum) {
|
||||
Row r = sheet.getRow(rowNum);
|
||||
double points = (r == null) ? sheet.getDefaultRowHeightInPoints() : r.getHeightInPoints();
|
||||
return Units.toEMU(points)/(double)EMU_PER_PIXEL;
|
||||
|
|
|
@ -17,7 +17,10 @@
|
|||
|
||||
package org.apache.poi.xssf.usermodel;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||
import org.apache.poi.ss.usermodel.ShapeContainer;
|
||||
import org.apache.poi.util.Internal;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D;
|
||||
|
@ -25,6 +28,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
|
|||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTConnector;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShape;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShapeNonVisual;
|
||||
|
@ -36,10 +40,8 @@ import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
|
|||
* just as if it were a regular shape but instead of being described by a single geometry it is made up of all the
|
||||
* shape geometries encompassed within it. Within a group shape each of the shapes that make up the group are
|
||||
* specified just as they normally would.
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public final class XSSFShapeGroup extends XSSFShape {
|
||||
public final class XSSFShapeGroup extends XSSFShape implements ShapeContainer<XSSFShape> {
|
||||
private static CTGroupShape prototype = null;
|
||||
|
||||
private CTGroupShape ctGroup;
|
||||
|
@ -164,6 +166,34 @@ public final class XSSFShapeGroup extends XSSFShape {
|
|||
return shape;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a group shape.
|
||||
*
|
||||
* @param anchor the client anchor describes how this group is attached to the group.
|
||||
* @return the newly created group shape.
|
||||
*/
|
||||
public XSSFShapeGroup createGroup(XSSFChildAnchor anchor) {
|
||||
CTGroupShape ctShape = ctGroup.addNewGrpSp();
|
||||
ctShape.set(prototype());
|
||||
|
||||
XSSFShapeGroup shape = new XSSFShapeGroup(getDrawing(), ctShape);
|
||||
shape.parent = this;
|
||||
shape.anchor = anchor;
|
||||
|
||||
// TODO: calculate bounding rectangle on anchor and set off/ext correctly
|
||||
|
||||
CTGroupTransform2D xfrm = shape.getCTGroupShape().getGrpSpPr().getXfrm();
|
||||
CTTransform2D t2 = anchor.getCTTransform2D();
|
||||
xfrm.setOff(t2.getOff());
|
||||
xfrm.setExt(t2.getExt());
|
||||
// child offset is left to 0,0
|
||||
xfrm.setChExt(t2.getExt());
|
||||
xfrm.setFlipH(t2.getFlipH());
|
||||
xfrm.setFlipV(t2.getFlipV());
|
||||
|
||||
return shape;
|
||||
}
|
||||
|
||||
@Internal
|
||||
public CTGroupShape getCTGroupShape() {
|
||||
return ctGroup;
|
||||
|
@ -194,4 +224,13 @@ public final class XSSFShapeGroup extends XSSFShape {
|
|||
throw new IllegalStateException("Not supported for shape group");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<XSSFShape> iterator() {
|
||||
return getDrawing().getShapes(this).iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getShapeName() {
|
||||
return ctGroup.getNvGrpSpPr().getCNvPr().getName();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,8 +32,11 @@ import org.apache.poi.POIXMLDocumentPart.RelationPart;
|
|||
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||
import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||
import org.apache.poi.ss.usermodel.FontUnderline;
|
||||
import org.apache.poi.ss.usermodel.ShapeTypes;
|
||||
import org.apache.poi.util.Units;
|
||||
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||
import org.junit.Test;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextCharacterProperties;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;
|
||||
|
@ -778,6 +781,65 @@ public class TestXSSFDrawing {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGroupShape() throws Exception {
|
||||
XSSFWorkbook wb1 = new XSSFWorkbook();
|
||||
XSSFSheet sheet = wb1.createSheet();
|
||||
XSSFDrawing drawing = sheet.createDrawingPatriarch();
|
||||
|
||||
XSSFSimpleShape s0 = drawing.createSimpleShape(drawing.createAnchor(0, 0, Units.pixelToEMU(30), Units.pixelToEMU(30), 1, 1, 10, 10));
|
||||
s0.setShapeType(ShapeTypes.RECT);
|
||||
s0.setLineStyleColor(100, 0, 0);
|
||||
|
||||
XSSFShapeGroup g1 = drawing.createGroup(drawing.createAnchor(0, 0, 300, 300, 1, 1, 10, 10));
|
||||
CTGroupTransform2D xfrmG1 = g1.getCTGroupShape().getGrpSpPr().getXfrm();
|
||||
|
||||
XSSFSimpleShape s1 = g1.createSimpleShape(new XSSFChildAnchor(
|
||||
(int)(xfrmG1.getChExt().getCx()*0.1),
|
||||
(int)(xfrmG1.getChExt().getCy()*0.1),
|
||||
(int)(xfrmG1.getChExt().getCx()*0.9),
|
||||
(int)(xfrmG1.getChExt().getCy()*0.9)
|
||||
));
|
||||
s1.setShapeType(ShapeTypes.RECT);
|
||||
s1.setLineStyleColor(0, 100, 0);
|
||||
|
||||
XSSFShapeGroup g2 = g1.createGroup(new XSSFChildAnchor(
|
||||
(int)(xfrmG1.getChExt().getCx()*0.2),
|
||||
(int)(xfrmG1.getChExt().getCy()*0.2),
|
||||
(int)(xfrmG1.getChExt().getCx()*0.8),
|
||||
(int)(xfrmG1.getChExt().getCy()*0.8)
|
||||
));
|
||||
CTGroupTransform2D xfrmG2 = g2.getCTGroupShape().getGrpSpPr().getXfrm();
|
||||
|
||||
XSSFSimpleShape s2 = g2.createSimpleShape(new XSSFChildAnchor(
|
||||
(int)(xfrmG2.getChExt().getCx()*0.1),
|
||||
(int)(xfrmG2.getChExt().getCy()*0.1),
|
||||
(int)(xfrmG2.getChExt().getCx()*0.9),
|
||||
(int)(xfrmG2.getChExt().getCy()*0.9)
|
||||
));
|
||||
s2.setShapeType(ShapeTypes.RECT);
|
||||
s2.setLineStyleColor(0, 0, 100);
|
||||
|
||||
XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb1);
|
||||
wb1.close();
|
||||
|
||||
XSSFDrawing draw = wb2.getSheetAt(0).getDrawingPatriarch();
|
||||
List<XSSFShape> shapes = draw.getShapes();
|
||||
assertEquals(2, shapes.size());
|
||||
assertTrue(shapes.get(0) instanceof XSSFSimpleShape);
|
||||
assertTrue(shapes.get(1) instanceof XSSFShapeGroup);
|
||||
shapes = draw.getShapes((XSSFShapeGroup)shapes.get(1));
|
||||
assertEquals(2, shapes.size());
|
||||
assertTrue(shapes.get(0) instanceof XSSFSimpleShape);
|
||||
assertTrue(shapes.get(1) instanceof XSSFShapeGroup);
|
||||
shapes = draw.getShapes((XSSFShapeGroup)shapes.get(1));
|
||||
assertEquals(1, shapes.size());
|
||||
assertTrue(shapes.get(0) instanceof XSSFSimpleShape);
|
||||
|
||||
wb2.close();
|
||||
}
|
||||
|
||||
|
||||
private static void checkRewrite(XSSFWorkbook wb) throws IOException {
|
||||
XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
assertNotNull(wb2);
|
||||
|
|
Loading…
Reference in New Issue