From 7290c5fabd2282e4c363f87f7895743531c65f0f Mon Sep 17 00:00:00 2001 From: Yegor Kozlov Date: Thu, 4 Oct 2012 11:23:32 +0000 Subject: [PATCH] Bugzilla 53568 - Set shapes anchors in XSSF when reading from existing drawings git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1393992 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 1 + .../poi/xssf/usermodel/XSSFClientAnchor.java | 10 ++++- .../poi/xssf/usermodel/XSSFDrawing.java | 38 ++++++++++++++++--- .../poi/xssf/usermodel/TestXSSFDrawing.java | 31 +++++++++++++++ 4 files changed, 73 insertions(+), 7 deletions(-) diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 99234ca01..0d13e0b3c 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 53568 - Set shapes anchors in XSSF when reading from existing drawings HSSFOptimiser will now also tidy away un-used cell styles, in addition to duplicate styles 53493 - Fixed memory and temporary file leak in SXSSF 53780 - Fixed memory and temporary file leak in SXSSF diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java index 76990c017..d1c703516 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java @@ -161,8 +161,14 @@ public final class XSSFClientAnchor extends XSSFAnchor implements ClientAnchor { if (o == null || !(o instanceof XSSFClientAnchor)) return false; XSSFClientAnchor anchor = (XSSFClientAnchor) o; - return cell1.toString().equals(anchor.getFrom().toString()) && - cell2.toString().equals(anchor.getTo().toString()) ; + return getDx1() == anchor.getDx1() && + getDx2() == anchor.getDx2() && + getDy1() == anchor.getDy1() && + getDy2() == anchor.getDy2() && + getCol1() == anchor.getCol1() && + getCol2() == anchor.getCol2() && + getRow1() == anchor.getRow1() && + getRow2() == anchor.getRow2() ; } diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java index f682200d2..43a1d2e21 100644 --- a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java +++ b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java @@ -35,6 +35,7 @@ import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.util.Internal; import org.apache.poi.xssf.model.CommentsTable; +import org.apache.xmlbeans.XmlCursor; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; @@ -370,12 +371,39 @@ public final class XSSFDrawing extends POIXMLDocumentPart implements Drawing { public List getShapes(){ List lst = new ArrayList(); for(XmlObject obj : drawing.selectPath("./*/*")) { - if(obj instanceof CTPicture) lst.add(new XSSFPicture(this, (CTPicture)obj)) ; - else if(obj instanceof CTConnector) lst.add(new XSSFConnector(this, (CTConnector)obj)) ; - else if(obj instanceof CTShape) lst.add(new XSSFSimpleShape(this, (CTShape)obj)) ; - else if(obj instanceof CTGraphicalObjectFrame) lst.add(new XSSFGraphicFrame(this, (CTGraphicalObjectFrame)obj)) ; - else if(obj instanceof CTGroupShape) lst.add(new XSSFShapeGroup(this, (CTGroupShape)obj)) ; + XSSFShape shape = null; + if(obj instanceof CTPicture) shape = new XSSFPicture(this, (CTPicture)obj) ; + else if(obj instanceof CTConnector) shape = new XSSFConnector(this, (CTConnector)obj) ; + else if(obj instanceof CTShape) shape = new XSSFSimpleShape(this, (CTShape)obj) ; + else if(obj instanceof CTGraphicalObjectFrame) shape = new XSSFGraphicFrame(this, (CTGraphicalObjectFrame)obj) ; + else if(obj instanceof CTGroupShape) shape = new XSSFShapeGroup(this, (CTGroupShape)obj) ; + + if(shape != null){ + shape.anchor = getAnchorFromParent(obj); + lst.add(shape); + } } return lst; } + + + private XSSFAnchor getAnchorFromParent(XmlObject obj){ + XSSFAnchor anchor = null; + + XmlObject parentXbean = null; + XmlCursor cursor = obj.newCursor(); + if(cursor.toParent()) parentXbean = cursor.getObject(); + cursor.dispose(); + if(parentXbean != null){ + if (parentXbean instanceof CTTwoCellAnchor) { + CTTwoCellAnchor ct = (CTTwoCellAnchor)parentXbean; + anchor = new XSSFClientAnchor(ct.getFrom(), ct.getTo()); + } else if (parentXbean instanceof CTOneCellAnchor) { + CTOneCellAnchor ct = (CTOneCellAnchor)parentXbean; + anchor = new XSSFClientAnchor(ct.getFrom(), CTMarker.Factory.newInstance()); + } + } + return anchor; + } + } diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java index cd5d52deb..79d0c9855 100644 --- a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java +++ b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java @@ -62,6 +62,8 @@ public class TestXSSFDrawing extends TestCase { assertTrue(shapes.get(4) instanceof XSSFSimpleShape); assertTrue(shapes.get(5) instanceof XSSFPicture); + for(XSSFShape sh : shapes) assertNotNull(sh.getAnchor()); + } public void testNew() throws Exception { @@ -212,4 +214,33 @@ public class TestXSSFDrawing extends TestCase { rPr.getSolidFill().getSrgbClr().getVal())); } + + /** + * test that anchor is not null when reading shapes from existing drawings + */ + public void testReadAnchors(){ + XSSFWorkbook wb = new XSSFWorkbook(); + XSSFSheet sheet = wb.createSheet(); + XSSFDrawing drawing = sheet.createDrawingPatriarch(); + + XSSFClientAnchor anchor1 = new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 4); + XSSFShape shape1 = drawing.createTextbox(anchor1); + + XSSFClientAnchor anchor2 = new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 5); + XSSFShape shape2 = drawing.createTextbox(anchor2); + + int pictureIndex= wb.addPicture(new byte[]{}, XSSFWorkbook.PICTURE_TYPE_PNG); + XSSFClientAnchor anchor3 = new XSSFClientAnchor(0, 0, 0, 0, 2, 2, 3, 6); + XSSFShape shape3 = drawing.createPicture(anchor3, pictureIndex); + + wb = XSSFTestDataSamples.writeOutAndReadBack(wb); + sheet = wb.getSheetAt(0); + drawing = sheet.createDrawingPatriarch(); + List shapes = drawing.getShapes(); + assertEquals(shapes.get(0).getAnchor(), anchor1); + assertEquals(shapes.get(1).getAnchor(), anchor2); + assertEquals(shapes.get(2).getAnchor(), anchor3); + + + } }