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);
|
Row r = sheet.getRow(rowNum);
|
||||||
double points = (r == null) ? sheet.getDefaultRowHeightInPoints() : r.getHeightInPoints();
|
double points = (r == null) ? sheet.getDefaultRowHeightInPoints() : r.getHeightInPoints();
|
||||||
return Units.toEMU(points)/(double)EMU_PER_PIXEL;
|
return Units.toEMU(points)/(double)EMU_PER_PIXEL;
|
||||||
|
|
|
@ -17,7 +17,10 @@
|
||||||
|
|
||||||
package org.apache.poi.xssf.usermodel;
|
package org.apache.poi.xssf.usermodel;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
import org.apache.poi.openxml4j.opc.PackageRelationship;
|
||||||
|
import org.apache.poi.ss.usermodel.ShapeContainer;
|
||||||
import org.apache.poi.util.Internal;
|
import org.apache.poi.util.Internal;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupTransform2D;
|
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.CTPoint2D;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
|
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.CTConnector;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShape;
|
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShape;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGroupShapeNonVisual;
|
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
|
* 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
|
* 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.
|
* 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 static CTGroupShape prototype = null;
|
||||||
|
|
||||||
private CTGroupShape ctGroup;
|
private CTGroupShape ctGroup;
|
||||||
|
@ -164,6 +166,34 @@ public final class XSSFShapeGroup extends XSSFShape {
|
||||||
return shape;
|
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
|
@Internal
|
||||||
public CTGroupShape getCTGroupShape() {
|
public CTGroupShape getCTGroupShape() {
|
||||||
return ctGroup;
|
return ctGroup;
|
||||||
|
@ -194,4 +224,13 @@ public final class XSSFShapeGroup extends XSSFShape {
|
||||||
throw new IllegalStateException("Not supported for shape group");
|
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.openxml4j.opc.OPCPackage;
|
||||||
import org.apache.poi.ss.usermodel.ClientAnchor;
|
import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||||
import org.apache.poi.ss.usermodel.FontUnderline;
|
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.apache.poi.xssf.XSSFTestDataSamples;
|
||||||
import org.junit.Test;
|
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.CTTextCharacterProperties;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
|
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
|
||||||
import org.openxmlformats.schemas.drawingml.x2006.main.STTextUnderlineType;
|
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 {
|
private static void checkRewrite(XSSFWorkbook wb) throws IOException {
|
||||||
XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb);
|
XSSFWorkbook wb2 = XSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||||
assertNotNull(wb2);
|
assertNotNull(wb2);
|
||||||
|
|
Loading…
Reference in New Issue