]> source.dussan.org Git - poi.git/commitdiff
more progress on SpreadsheetML drawing layer;finished XSSFPicture, auto-sizing is...
authorYegor Kozlov <yegor@apache.org>
Fri, 17 Oct 2008 15:14:00 +0000 (15:14 +0000)
committerYegor Kozlov <yegor@apache.org>
Fri, 17 Oct 2008 15:14:00 +0000 (15:14 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@705638 13f79535-47bb-0310-9956-ffa450edef68

28 files changed:
src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithPictures.java [new file with mode: 0755]
src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Row.java
src/ooxml/interfaces-jdk15/org/apache/poi/ss/usermodel/Sheet.java
src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
src/ooxml/java/org/apache/poi/POIXMLFactory.java
src/ooxml/java/org/apache/poi/xssf/model/CommentsTable.java
src/ooxml/java/org/apache/poi/xssf/model/SharedStringsTable.java
src/ooxml/java/org/apache/poi/xssf/model/StylesTable.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAnchor.java [new file with mode: 0755]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java [new file with mode: 0755]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFClientAnchor.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConnector.java [new file with mode: 0755]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFDrawing.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFPicture.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRichTextString.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFRow.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShape.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java [new file with mode: 0755]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSheet.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFSimpleShape.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextBox.java [new file with mode: 0755]
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFWorkbook.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFCell.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFDrawing.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFRow.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFSheet.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFWorkbook.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/helpers/TestColumnHelper.java

diff --git a/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithPictures.java b/src/examples/src/org/apache/poi/xssf/usermodel/examples/WorkingWithPictures.java
new file mode 100755 (executable)
index 0000000..b4c018d
--- /dev/null
@@ -0,0 +1,60 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.xssf.usermodel.examples;\r
+\r
+import org.apache.poi.xssf.usermodel.*;\r
+\r
+import java.io.IOException;\r
+import java.io.InputStream;\r
+import java.io.FileInputStream;\r
+import java.io.FileOutputStream;\r
+\r
+/**\r
+ * Demonstrates how to insert pictures in a SpreadsheetML document\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public class WorkingWithPictures {\r
+    public static void main(String[] args) throws IOException {\r
+\r
+        //create a new workbook\r
+        XSSFWorkbook wb = new XSSFWorkbook();\r
+\r
+        //add a picture in this workbook.\r
+        InputStream is = new FileInputStream("lilies.jpg");\r
+        int pictureIdx = wb.addPicture(is, XSSFWorkbook.PICTURE_TYPE_JPEG);\r
+        is.close();\r
+\r
+        //create sheet\r
+        XSSFSheet sheet = wb.createSheet();\r
+\r
+        //create drawing\r
+        XSSFDrawing drawing = sheet.createDrawingPatriarch();\r
+\r
+        //add a picture shape\r
+        XSSFPicture pict = drawing.createPicture(new XSSFClientAnchor(), pictureIdx);\r
+\r
+        //auto-size picture\r
+        pict.resize();\r
+\r
+        //save workbook\r
+        FileOutputStream fileOut = new FileOutputStream("xssf-picture.xlsx");\r
+        wb.write(fileOut);\r
+        fileOut.close();\r
+\r
+    }\r
+}\r
index bbed1cfdbbc5620c2173af77d08a28f7b022c292..99cd0320ea16c0fdace6ce4e668355848db7c93a 100644 (file)
@@ -176,11 +176,6 @@ public interface Row extends Iterable<Cell> {
         */
        Iterator<Cell> iterator();
 
-    int compareTo(Object obj);
-
-    boolean equals(Object obj);
-
-    
     /**
      * Used to specify the different possible policies
      *  if for the case of null and blank cells
index ce4f92ceb569f47976ac4cb41c9918fba3b8f74d..d5ad5bddad0b47a20d7a363e38343d6b5eaf0229 100644 (file)
@@ -98,32 +98,6 @@ public interface Sheet extends Iterable<Row> {
 
     int getLastRowNum();
 
-    
-    
-    /**
-     * @deprecated (Sep 2008) use {@link #setColumnHidden(int, boolean)}
-     */
-    void setColumnHidden(short columnIndex, boolean hidden);
-    /**
-     * @deprecated (Sep 2008) use {@link #isColumnHidden(int)}
-     */
-    boolean isColumnHidden(short columnIndex);
-
-    /**
-     * @deprecated (Sep 2008) use {@link #setColumnWidth(int, int)}
-     */
-    void setColumnWidth(short columnIndex, short width);
-
-    /**
-     * @deprecated (Sep 2008) use {@link #getColumnWidth(int)}
-     */
-    short getColumnWidth(short columnIndex);
-
-    /**
-     * @deprecated (Sep 2008) use {@link #setDefaultColumnWidth(int)}
-     */
-    void setDefaultColumnWidth(short width);
-    
     /**
      * Get the visibility state for a given column.
      * @param columnIndex - the column to get (0-based)
index e809a7729df06d0bd2aff75e2ed0e6d5a352223a..faf7e7c07edd2f19c3abeedb1818b6c42ac81f06 100755 (executable)
@@ -110,7 +110,7 @@ public class POIXMLDocumentPart {
 \r
     /**\r
      * Save the content in the underlying package part.\r
-     * Default implemenation is empty meaning that the package part is left unmodified.\r
+     * Default implementation is empty meaning that the package part is left unmodified.\r
      *\r
      * Sub-classes should override and add logic to marshal the "model" into Ooxml4J.\r
      *\r
@@ -122,6 +122,7 @@ public class POIXMLDocumentPart {
      *   XmlObject bean = getXmlBean(); //the "model" which holds changes in memory\r
      *   bean.save(out, DEFAULT_XML_OPTIONS);\r
      *   out.close();\r
+     * }\r
      *  </code></pre>\r
      *\r
      */\r
index 4b922dd14603186e04ff08b86da1ea7f17f04c08..6341b20842493b32f9448c0da04d1fc334f91dce 100755 (executable)
@@ -41,7 +41,7 @@ public abstract class POIXMLFactory {
      * Create a new POIXMLDocumentPart using the supplied descriptor. This method is used when adding new parts\r
      * to a document, for example, when adding a sheet to a workbook, slide to a presentation, etc.\r
      *\r
-     * @param descriptor  described the object to create\r
+     * @param descriptor  describes the object to create\r
      * @return A new instance of a POIXMLDocumentPart.\r
      */\r
      public abstract POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor);\r
index 15c09c80a9502b5fd91e14805088e30b45e52cb3..f59a8bc308e2b1b43696d8291ebafdf6fb98d7bf 100644 (file)
@@ -34,7 +34,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CommentsDocument;
 import org.openxml4j.opc.PackagePart;
 import org.openxml4j.opc.PackageRelationship;
 
-public class CommentsTable extends POIXMLDocumentPart implements CommentsSource, XSSFModel {
+public class CommentsTable extends POIXMLDocumentPart implements CommentsSource {
     private CTComments comments;
 
     public CommentsTable(InputStream is) throws IOException {
index e854d19d02349d21ed36a70074d49f49d5c026d1..cbf2811676ca8cd5f4e6d436e4e2af840f95d115 100644 (file)
@@ -60,7 +60,7 @@ import org.openxml4j.opc.PackageRelationship;
  * @author Nick Birch
  * @author Yegor Kozlov
  */
-public class SharedStringsTable extends POIXMLDocumentPart implements XSSFModel, SharedStringSource {
+public class SharedStringsTable extends POIXMLDocumentPart implements SharedStringSource {
 
     /**
      *  Array of individual string items in the Shared String table.
index 568d56c15740923306946f275faa6d8abc603a2f..1e7fdd888fba8ae3ace27b5c43a607320eaa1c07 100644 (file)
@@ -64,15 +64,15 @@ import org.openxml4j.opc.PackageRelationship;
  *
  * @author ugo
  */
-public class StylesTable extends POIXMLDocumentPart implements StylesSource, XSSFModel {
+public class StylesTable extends POIXMLDocumentPart implements StylesSource {
        private final Hashtable<Long,String> numberFormats = new Hashtable<Long,String>();
        private final List<XSSFFont> fonts = new ArrayList<XSSFFont>();
        private final List<XSSFCellFill> fills = new ArrayList<XSSFCellFill>();
        private final List<XSSFCellBorder> borders = new ArrayList<XSSFCellBorder>();
-       private final List<CTXf> styleXfs = new LinkedList<CTXf>();
-       private final List<CTXf> xfs = new LinkedList<CTXf>();
+       private final List<CTXf> styleXfs = new ArrayList<CTXf>();
+       private final List<CTXf> xfs = new ArrayList<CTXf>();
 
-       private final List<CTDxf> dxfs = new LinkedList<CTDxf>();
+       private final List<CTDxf> dxfs = new ArrayList<CTDxf>();
 
        /**
         * The first style id available for use as a custom style
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAnchor.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFAnchor.java
new file mode 100755 (executable)
index 0000000..89f4fb8
--- /dev/null
@@ -0,0 +1,27 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.xssf.usermodel;\r
+\r
+/**\r
+ * An anchor is what specifics the position of a shape within a client object\r
+ * or within another containing shape.\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public abstract class XSSFAnchor {\r
+\r
+}\r
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFChildAnchor.java
new file mode 100755 (executable)
index 0000000..d02ee82
--- /dev/null
@@ -0,0 +1,81 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.xssf.usermodel;\r
+\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;\r
+\r
+/**\r
+ * @author Yegor Kozlov\r
+ */\r
+public class XSSFChildAnchor extends XSSFAnchor {\r
+    private CTTransform2D t2d;\r
+\r
+    public XSSFChildAnchor(int x, int y, int cx, int cy) {\r
+        t2d = CTTransform2D.Factory.newInstance();\r
+        CTPoint2D off = t2d.addNewOff();\r
+        CTPositiveSize2D ext = t2d.addNewExt();\r
+\r
+        off.setX(x);\r
+        off.setY(y);\r
+        ext.setCx(Math.abs(cx - x));\r
+        ext.setCy(Math.abs(cy - y));\r
+        if(x > cx)  t2d.setFlipH(true);\r
+        if(y > cy)  t2d.setFlipV(true);\r
+    }\r
+\r
+    public XSSFChildAnchor(CTTransform2D t2d) {\r
+        this.t2d = t2d;\r
+    }\r
+\r
+    public CTTransform2D getCTTransform2D() {\r
+        return t2d;\r
+    }\r
+\r
+    public int getDx1() {\r
+        return (int)t2d.getOff().getX();\r
+    }\r
+\r
+    public void setDx1(int dx1) {\r
+        t2d.getOff().setX(dx1);\r
+    }\r
+\r
+    public int getDy1() {\r
+        return (int)t2d.getOff().getY();\r
+    }\r
+\r
+    public void setDy1(int dy1) {\r
+        t2d.getOff().setY(dy1);\r
+    }\r
+\r
+    public int getDy2() {\r
+        return (int)(getDy1() + t2d.getExt().getCy());\r
+    }\r
+\r
+    public void setDy2(int dy2) {\r
+        t2d.getExt().setCy(dy2 - getDy1());\r
+    }\r
+\r
+    public int getDx2() {\r
+        return (int)(getDx1() + t2d.getExt().getCx());\r
+    }\r
+\r
+    public void setDx2(int dx2) {\r
+        t2d.getExt().setCx(dx2 - getDx1());\r
+    }\r
+}\r
index 0a6129e432d11d16627d1ea83e0b454dc12612c7..9e6bd262777fce4e24ed93f8f123e63edcf43ad4 100755 (executable)
@@ -20,11 +20,11 @@ import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
 \r
 /**\r
  * A client anchor is attached to an excel worksheet.  It anchors against\r
- * top-left and buttom-right cells.\r
+ * top-left and bottom-right cells.\r
  *\r
  * @author Yegor Kozlov\r
  */\r
-public class XSSFClientAnchor {\r
+public class XSSFClientAnchor extends XSSFAnchor {\r
 \r
     /**\r
      * Starting anchor point\r
@@ -92,7 +92,7 @@ public class XSSFClientAnchor {
         return cell1.getCol();\r
     }\r
 \r
-    public void setCol1(short col1) {\r
+    public void setCol1(int col1) {\r
         cell1.setCol(col1);\r
     }\r
 \r
@@ -100,7 +100,7 @@ public class XSSFClientAnchor {
         return cell2.getCol();\r
     }\r
 \r
-    public void setCol2(short col2) {\r
+    public void setCol2(int col2) {\r
         cell2.setCol(col2);\r
     }\r
 \r
@@ -176,6 +176,10 @@ public class XSSFClientAnchor {
         return cell1;\r
     }\r
 \r
+    protected void setFrom(CTMarker from){\r
+        cell1 = from;\r
+    }\r
+\r
     /**\r
      * Return ending anchor point\r
      *\r
@@ -184,4 +188,8 @@ public class XSSFClientAnchor {
     public CTMarker getTo(){\r
         return cell2;\r
     }\r
+\r
+    protected void setTo(CTMarker to){\r
+        cell2 = to;\r
+    }\r
 }\r
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConnector.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFConnector.java
new file mode 100755 (executable)
index 0000000..2127263
--- /dev/null
@@ -0,0 +1,121 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.xssf.usermodel;\r
+\r
+import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
+\r
+/**\r
+ * A connection shape drawing element. A connection shape is a line, etc.\r
+ * that connects two other shapes in this drawing.\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public class XSSFConnector extends XSSFShape {\r
+\r
+    private static CTConnector prototype = null;\r
+\r
+    private CTConnector ctShape;\r
+\r
+    /**\r
+     * Construct a new XSSFConnector object.\r
+     *\r
+     * @param drawing the XSSFDrawing that owns this shape\r
+     * @param ctShape the shape bean that holds all the shape properties\r
+     */\r
+    protected XSSFConnector(XSSFDrawing drawing, CTConnector ctShape) {\r
+        this.drawing = drawing;\r
+        this.ctShape = ctShape;\r
+    }\r
+\r
+    /**\r
+     * Initialize default structure of a new auto-shape\r
+     *\r
+     */\r
+    protected static CTConnector prototype() {\r
+        if(prototype == null) {\r
+            CTConnector shape = CTConnector.Factory.newInstance();\r
+            CTConnectorNonVisual nv = shape.addNewNvCxnSpPr();\r
+            CTNonVisualDrawingProps nvp = nv.addNewCNvPr();\r
+            nvp.setId(1);\r
+            nvp.setName("Shape 1");\r
+            nv.addNewCNvCxnSpPr();\r
+\r
+            CTShapeProperties sp = shape.addNewSpPr();\r
+            CTTransform2D t2d = sp.addNewXfrm();\r
+            CTPositiveSize2D p1 = t2d.addNewExt();\r
+            p1.setCx(0);\r
+            p1.setCy(0);\r
+            CTPoint2D p2 = t2d.addNewOff();\r
+            p2.setX(0);\r
+            p2.setY(0);\r
+\r
+            CTPresetGeometry2D geom = sp.addNewPrstGeom();\r
+            geom.setPrst(STShapeType.LINE);\r
+            geom.addNewAvLst();\r
+\r
+            CTShapeStyle style = shape.addNewStyle();\r
+            CTSchemeColor scheme = style.addNewLnRef().addNewSchemeClr();\r
+            scheme.setVal(STSchemeColorVal.ACCENT_1);\r
+            style.getLnRef().setIdx(1);\r
+\r
+            CTStyleMatrixReference fillref = style.addNewFillRef();\r
+            fillref.setIdx(0);\r
+            fillref.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);\r
+\r
+            CTStyleMatrixReference effectRef = style.addNewEffectRef();\r
+            effectRef.setIdx(0);\r
+            effectRef.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);\r
+\r
+            CTFontReference fontRef = style.addNewFontRef();\r
+            fontRef.setIdx(STFontCollectionIndex.MINOR);\r
+            fontRef.addNewSchemeClr().setVal(STSchemeColorVal.TX_1);\r
+\r
+            prototype = shape;\r
+        }\r
+        return prototype;\r
+    }\r
+\r
+    public CTConnector getCTConnector(){\r
+        return ctShape;\r
+    }\r
+\r
+    /**\r
+     * Gets the shape type, one of the constants defined in {@link org.apache.poi.xssf.usermodel.ShapeTypes}.\r
+     *\r
+     * @return the shape type\r
+     * @see org.apache.poi.xssf.usermodel.ShapeTypes\r
+     */\r
+    public int getShapeType() {\r
+        return ctShape.getSpPr().getPrstGeom().getPrst().intValue();\r
+    }\r
+\r
+    /**\r
+     * Sets the shape types.\r
+     *\r
+     * @param type the shape type, one of the constants defined in {@link org.apache.poi.xssf.usermodel.ShapeTypes}.\r
+     * @see org.apache.poi.xssf.usermodel.ShapeTypes\r
+     */\r
+    public void setShapeType(int type) {\r
+        ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type));\r
+    }\r
+\r
+    protected CTShapeProperties getShapeProperties(){\r
+        return ctShape.getSpPr();\r
+    }\r
+\r
+}\r
index 1172612eb0fade7c2fc4bc0fe3e72be632214994..82f6ec0fcbe6a958416e4ed5e6d14234a7f2daee 100755 (executable)
@@ -19,10 +19,9 @@ package org.apache.poi.xssf.usermodel;
 import org.apache.poi.POIXMLDocumentPart;\r
 import org.apache.xmlbeans.XmlException;\r
 import org.apache.xmlbeans.XmlOptions;\r
+import org.apache.xmlbeans.XmlObject;\r
 import org.openxml4j.opc.*;\r
-import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTDrawing;\r
-import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;\r
-import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.STEditAs;\r
+import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;\r
 import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;\r
 \r
 import javax.xml.namespace.QName;\r
@@ -30,6 +29,8 @@ import java.io.IOException;
 import java.io.OutputStream;\r
 import java.util.Map;\r
 import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.LinkedList;\r
 \r
 /**\r
  * Represents a SpreadsheetML drawing\r
@@ -105,6 +106,23 @@ public class XSSFDrawing extends POIXMLDocumentPart {
         out.close();\r
     }\r
 \r
+    /**\r
+     * Constructs a textbox under the drawing.\r
+     *\r
+     * @param anchor    the client anchor describes how this group is attached\r
+     *                  to the sheet.\r
+     * @return      the newly created textbox.\r
+     */\r
+    public XSSFTextBox createTextbox(XSSFClientAnchor anchor){\r
+        CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);\r
+        CTShape ctShape = ctAnchor.addNewSp();\r
+        ctShape.set(XSSFSimpleShape.prototype());\r
+        XSSFTextBox shape = new XSSFTextBox(this, ctShape);\r
+        shape.anchor = anchor;\r
+        return shape;\r
+\r
+    }\r
+\r
     /**\r
      * Creates a picture.\r
      *\r
@@ -116,13 +134,32 @@ public class XSSFDrawing extends POIXMLDocumentPart {
      */\r
     public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex)\r
     {\r
+        PackageRelationship rel = addPictureReference(pictureIndex);\r
+\r
+        CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);\r
+        ctAnchor.setEditAs(STEditAs.ONE_CELL);\r
+        CTPicture ctShape = ctAnchor.addNewPic();\r
+        ctShape.set(XSSFPicture.prototype());\r
+\r
+        XSSFPicture shape = new XSSFPicture(this, ctShape);\r
+        shape.anchor = anchor;\r
+        shape.setPictureReference(rel);\r
+        return shape;\r
+    }\r
+\r
+    /**\r
+     * Add the indexed picture to this drawing relations\r
+     *\r
+     * @param pictureIndex the index of the picture in the workbook collection of pictures,\r
+     *   {@link org.apache.poi.xssf.usermodel.XSSFWorkbook#getAllPictures()} .\r
+     */\r
+    protected PackageRelationship addPictureReference(int pictureIndex){\r
         XSSFWorkbook wb = (XSSFWorkbook)getParent().getParent();\r
         XSSFPictureData data = wb.getAllPictures().get(pictureIndex);\r
         PackagePartName ppName = data.getPackagePart().getPartName();\r
         PackageRelationship rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, XSSFRelation.IMAGES.getRelation());\r
         addRelation(new XSSFPictureData(data.getPackagePart(), rel));\r
-        CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);\r
-        return new XSSFPicture(this, rel, ctAnchor);\r
+        return rel;\r
     }\r
 \r
     /**\r
@@ -136,7 +173,49 @@ public class XSSFDrawing extends POIXMLDocumentPart {
     public XSSFSimpleShape createSimpleShape(XSSFClientAnchor anchor)\r
     {\r
         CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);\r
-        return new XSSFSimpleShape(this, ctAnchor);\r
+        CTShape ctShape = ctAnchor.addNewSp();\r
+        ctShape.set(XSSFSimpleShape.prototype());\r
+        XSSFSimpleShape shape = new XSSFSimpleShape(this, ctShape);\r
+        shape.anchor = anchor;\r
+        return shape;\r
+    }\r
+\r
+    /**\r
+     * Creates a simple shape.  This includes such shapes as lines, rectangles,\r
+     * and ovals.\r
+     *\r
+     * @param anchor    the client anchor describes how this group is attached\r
+     *                  to the sheet.\r
+     * @return  the newly created shape.\r
+     */\r
+    public XSSFConnector createConnector(XSSFClientAnchor anchor)\r
+    {\r
+        CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);\r
+        CTConnector ctShape = ctAnchor.addNewCxnSp();\r
+        ctShape.set(XSSFConnector.prototype());\r
+\r
+        XSSFConnector shape = new XSSFConnector(this, ctShape);\r
+        shape.anchor = anchor;\r
+        return shape;\r
+    }\r
+\r
+    /**\r
+     * Creates a simple shape.  This includes such shapes as lines, rectangles,\r
+     * and ovals.\r
+     *\r
+     * @param anchor    the client anchor describes how this group is attached\r
+     *                  to the sheet.\r
+     * @return  the newly created shape.\r
+     */\r
+    public XSSFShapeGroup createGroup(XSSFClientAnchor anchor)\r
+    {\r
+        CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);\r
+        CTGroupShape ctGroup = ctAnchor.addNewGrpSp();\r
+        ctGroup.set(XSSFShapeGroup.prototype());\r
+\r
+        XSSFShapeGroup shape = new XSSFShapeGroup(this, ctGroup);\r
+        shape.anchor = anchor;\r
+        return shape;\r
     }\r
 \r
     /**\r
@@ -144,12 +223,13 @@ public class XSSFDrawing extends POIXMLDocumentPart {
      *\r
      * @return a new CTTwoCellAnchor\r
      */\r
-    private CTTwoCellAnchor createTwoCellAnchor(XSSFClientAnchor anchor){\r
+    private CTTwoCellAnchor createTwoCellAnchor(XSSFClientAnchor anchor) {\r
         CTTwoCellAnchor ctAnchor = drawing.addNewTwoCellAnchor();\r
-        ctAnchor.setEditAs(STEditAs.ONE_CELL);\r
         ctAnchor.setFrom(anchor.getFrom());\r
         ctAnchor.setTo(anchor.getTo());\r
         ctAnchor.addNewClientData();\r
+        anchor.setTo(ctAnchor.getTo());\r
+        anchor.setFrom(ctAnchor.getFrom());\r
         return ctAnchor;\r
     }\r
 }\r
index 93a7caa6e66c96ebf9155e4ec6281e322303283d..293aeaaee2d77adef12b72473f3d8253a2e435eb 100755 (executable)
@@ -43,18 +43,15 @@ public class XSSFPicture extends XSSFShape {
     private static final POILogger logger = POILogFactory.getLogger(XSSFPicture.class);\r
 \r
     /**\r
-     * width of 1px in columns with default width\r
+     * A default instance of CTShape used for creating new shapes.\r
      */\r
-    private static final float PX_DEFAULT = 0.125f;\r
-    /**\r
-     * width of 1px in columns with overridden width\r
-     */\r
-    private static final float PX_MODIFIED = 0.143f;\r
+    private static CTPicture prototype = null;\r
 \r
     /**\r
-     * Height of 1px of a row\r
+     * Width of one character in pixels. Same for Calibry and Arial.\r
      */\r
-    private static final int PX_ROW = 15;\r
+    private static final float CHARACTER_WIDTH = 7.0017f;\r
+\r
 \r
     /**\r
      * This object specifies a picture object and all its properties\r
@@ -65,56 +62,60 @@ public class XSSFPicture extends XSSFShape {
      * Construct a new XSSFPicture object. This constructor is called from\r
      *  {@link XSSFDrawing#createPicture(XSSFClientAnchor, int)}\r
      *\r
-     * @param parent the XSSFDrawing that owns this picture\r
-     * @param rel    the relationship to the picture data\r
-     * @param anchor the two cell anchor placeholder for this picture,\r
-     *   this object encloses the CTPicture bean that holds all the picture properties\r
+     * @param drawing the XSSFDrawing that owns this picture\r
+     */\r
+    protected XSSFPicture(XSSFDrawing drawing, CTPicture ctPicture){\r
+        this.drawing = drawing;\r
+        this.ctPicture = ctPicture;\r
+    }\r
+\r
+    /**\r
+     * Returns a prototype that is used to construct new shapes\r
+     *\r
+     * @return a prototype that is used to construct new shapes\r
      */\r
-    protected XSSFPicture(XSSFDrawing parent, PackageRelationship rel, CTTwoCellAnchor anchor){\r
-        super(parent, anchor);\r
-        //Create a new picture and attach it to the specified two-cell anchor\r
-        ctPicture = newPicture(rel);\r
-        anchor.setPic(ctPicture);\r
+    protected static CTPicture prototype(){\r
+        if(prototype == null) {\r
+            CTPicture pic = CTPicture.Factory.newInstance();\r
+            CTPictureNonVisual nvpr = pic.addNewNvPicPr();\r
+            CTNonVisualDrawingProps nvProps = nvpr.addNewCNvPr();\r
+            nvProps.setId(1);\r
+            nvProps.setName("Picture 1");\r
+            nvProps.setDescr("Picture");\r
+            CTNonVisualPictureProperties nvPicProps = nvpr.addNewCNvPicPr();\r
+            nvPicProps.addNewPicLocks().setNoChangeAspect(true);\r
+\r
+            CTBlipFillProperties blip = pic.addNewBlipFill();\r
+            blip.addNewBlip().setEmbed("");\r
+            blip.addNewStretch().addNewFillRect();\r
+\r
+            CTShapeProperties sppr = pic.addNewSpPr();\r
+            CTTransform2D t2d = sppr.addNewXfrm();\r
+            CTPositiveSize2D ext = t2d.addNewExt();\r
+            //should be original picture width and height expressed in EMUs\r
+            ext.setCx(0);\r
+            ext.setCy(0);\r
+\r
+            CTPoint2D off = t2d.addNewOff();\r
+            off.setX(0);\r
+            off.setY(0);\r
+\r
+            CTPresetGeometry2D prstGeom = sppr.addNewPrstGeom();\r
+            prstGeom.setPrst(STShapeType.RECT);\r
+            prstGeom.addNewAvLst();\r
+\r
+            prototype = pic;\r
+        }\r
+        return prototype;\r
     }\r
 \r
     /**\r
-     * Create a new CTPicture bean and initialize its required attributes\r
+     * Link this shape with the picture data\r
      *\r
-     * @param rel the relationship to the picture data\r
-     * @return a new CTPicture bean\r
+     * @param rel relationship referring the picture data\r
      */\r
-    private static CTPicture newPicture(PackageRelationship rel){\r
-        CTPicture pic = CTPicture.Factory.newInstance();\r
-\r
-        CTPictureNonVisual nvpr = pic.addNewNvPicPr();\r
-        CTNonVisualDrawingProps nvProps = nvpr.addNewCNvPr();\r
-        //YK: TODO shape IDs must be unique across workbook\r
-        int shapeId = 1;\r
-        nvProps.setId(shapeId);\r
-        nvProps.setName("Picture " + shapeId);\r
-        nvProps.setDescr(rel.getTargetURI().toString());\r
-        CTNonVisualPictureProperties nvPicProps = nvpr.addNewCNvPicPr();\r
-        nvPicProps.addNewPicLocks().setNoChangeAspect(true);\r
-\r
-        CTBlipFillProperties blip = pic.addNewBlipFill();\r
-        blip.addNewBlip().setEmbed(rel.getId());\r
-        blip.addNewStretch().addNewFillRect();\r
-\r
-        CTShapeProperties sppr = pic.addNewSpPr();\r
-        CTTransform2D t2d = sppr.addNewXfrm();\r
-        CTPositiveSize2D ext = t2d.addNewExt();\r
-        //should be original picture width and height expressed in EMUs\r
-        ext.setCx(0);\r
-        ext.setCy(0);\r
-\r
-        CTPoint2D off = t2d.addNewOff();\r
-        off.setX(0);\r
-        off.setY(0);\r
-\r
-        CTPresetGeometry2D prstGeom = sppr.addNewPrstGeom();\r
-        prstGeom.setPrst(STShapeType.RECT);\r
-        prstGeom.addNewAvLst();\r
-        return pic;\r
+    protected void setPictureReference(PackageRelationship rel){\r
+        ctPicture.getBlipFill().getBlip().setEmbed(rel.getId());\r
     }\r
 \r
     /**\r
@@ -130,7 +131,7 @@ public class XSSFPicture extends XSSFShape {
      * Reset the image to the original size.\r
      */\r
     public void resize(){\r
-        XSSFClientAnchor anchor = getAnchor();\r
+        XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor();\r
 \r
         XSSFClientAnchor pref = getPreferredSize();\r
 \r
@@ -152,78 +153,76 @@ public class XSSFPicture extends XSSFShape {
      * @return XSSFClientAnchor with the preferred size for this image\r
      */\r
     public XSSFClientAnchor getPreferredSize(){\r
-        XSSFClientAnchor anchor = getAnchor();\r
+        XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor();\r
 \r
         XSSFPictureData data = getPictureData();\r
         Dimension size = getImageDimension(data.getPackagePart(), data.getPictureType());\r
 \r
         float w = 0;\r
-\r
-        //space in the leftmost cell\r
-        w += anchor.getDx1()/EMU_PER_POINT;\r
-        short col2 = (short)(anchor.getCol1() + 1);\r
+        int col2 = anchor.getCol1();\r
         int dx2 = 0;\r
+        if(anchor.getDx1() > 0){\r
+            w += getColumnWidthInPixels(col2) - anchor.getDx1();\r
+            col2++;\r
+        }\r
 \r
-        while(w < size.width){\r
-            w += getColumnWidthInPixels(col2++);\r
+        for (;;) {\r
+            w += getColumnWidthInPixels(col2);\r
+            if(w > size.width) break;\r
+            col2++;\r
         }\r
 \r
         if(w > size.width) {\r
-            //calculate dx2, offset in the rightmost cell\r
-            col2--;\r
-            float cw = getColumnWidthInPixels(col2);\r
+            float cw = getColumnWidthInPixels(col2 + 1);\r
             float delta = w - size.width;\r
-            dx2 = (int)(EMU_PER_POINT*(cw-delta));\r
+            dx2 = (int)(EMU_PER_PIXEL*(cw-delta));\r
         }\r
         anchor.setCol2(col2);\r
         anchor.setDx2(dx2);\r
 \r
         float h = 0;\r
-        h += (1 - anchor.getDy1()/256)* getRowHeightInPixels(anchor.getRow1());\r
-        int row2 = anchor.getRow1() + 1;\r
+        int row2 = anchor.getRow1();\r
         int dy2 = 0;\r
 \r
-        while(h < size.height){\r
-            h += getRowHeightInPixels(row2++);\r
+        if(anchor.getDy1() > 0){\r
+            h += getRowHeightInPixels(row2) - anchor.getDy1();\r
+            row2++;\r
         }\r
+\r
+        for (;;) {\r
+            h += getRowHeightInPixels(row2);\r
+            if(h > size.height) break;\r
+            row2++;\r
+        }\r
+\r
         if(h > size.height) {\r
-            row2--;\r
-            float ch = getRowHeightInPixels(row2);\r
+            float ch = getRowHeightInPixels(row2 + 1);\r
             float delta = h - size.height;\r
-            dy2 = (int)((ch-delta)/ch*256);\r
+            dy2 = (int)(EMU_PER_PIXEL*(ch-delta));\r
         }\r
         anchor.setRow2(row2);\r
         anchor.setDy2(dy2);\r
 \r
-        return anchor;\r
-    }\r
-\r
-    private float getColumnWidthInPixels(int column){\r
-        XSSFSheet sheet = (XSSFSheet)getDrawing().getParent();\r
-        int cw = sheet.getColumnWidth(column);\r
-        float px = getPixelWidth(column);\r
+        CTPositiveSize2D size2d =  ctPicture.getSpPr().getXfrm().getExt();\r
+        size2d.setCx(size.width*EMU_PER_PIXEL);\r
+        size2d.setCy(size.height*EMU_PER_PIXEL);\r
 \r
-        return cw/px;\r
+        return anchor;\r
     }\r
 \r
-    private float getRowHeightInPixels(int i){\r
+    private float getColumnWidthInPixels(int columnIndex){\r
         XSSFSheet sheet = (XSSFSheet)getDrawing().getParent();\r
+        float numChars = (float)sheet.getColumnWidth(columnIndex)/256;\r
 \r
-        XSSFRow row = sheet.getRow(i);\r
-        float height;\r
-        if(row != null) height = row.getHeight();\r
-        else height = sheet.getDefaultRowHeight();\r
-\r
-        return height/PX_ROW;\r
+        return numChars*CHARACTER_WIDTH;\r
     }\r
 \r
-    private float getPixelWidth(int column){\r
+    private float getRowHeightInPixels(int rowIndex){\r
         XSSFSheet sheet = (XSSFSheet)getDrawing().getParent();\r
 \r
-        int def = sheet.getDefaultColumnWidth();\r
-        int cw = sheet.getColumnWidth(column);\r
-\r
-        return cw == def ? PX_DEFAULT : PX_MODIFIED;\r
+        XSSFRow row = sheet.getRow(rowIndex);\r
+        float height = row != null ?  row.getHeightInPoints() : sheet.getDefaultRowHeightInPoints();\r
+        return height*PIXEL_DPI/POINT_DPI;\r
     }\r
 \r
     /**\r
@@ -238,7 +237,7 @@ public class XSSFPicture extends XSSFShape {
         Dimension size = new Dimension();\r
 \r
         switch (type){\r
-            //we can calculate the preferred size only for JPEG and PNG\r
+            //we can calculate the preferred size only for JPEG, PNG and BMP\r
             //other formats like WMF, EMF and PICT are not supported in Java\r
             case Workbook.PICTURE_TYPE_JPEG:\r
             case Workbook.PICTURE_TYPE_PNG:\r
@@ -255,11 +254,11 @@ public class XSSFPicture extends XSSFShape {
 \r
                     //if DPI is zero then assume standard 96 DPI\r
                     //since cannot divide by zero\r
-                    if (dpi[0] == 0) dpi[0] = 96;\r
-                    if (dpi[1] == 0) dpi[1] = 96;\r
+                    if (dpi[0] == 0) dpi[0] = PIXEL_DPI;\r
+                    if (dpi[1] == 0) dpi[1] = PIXEL_DPI;\r
 \r
-                    size.width = img.getWidth()*96/dpi[0];\r
-                    size.height = img.getHeight()*96/dpi[1];\r
+                    size.width = img.getWidth()*PIXEL_DPI/dpi[0];\r
+                    size.height = img.getHeight()*PIXEL_DPI/dpi[1];\r
 \r
                 } catch (IOException e){\r
                     //silently return if ImageIO failed to read the image\r
@@ -282,7 +281,7 @@ public class XSSFPicture extends XSSFShape {
      * {96, 96} is the default.\r
      */\r
     protected static int[] getResolution(ImageReader r) throws IOException {\r
-        int hdpi=96, vdpi=96;\r
+        int hdpi = PIXEL_DPI, vdpi = PIXEL_DPI;\r
         double mm2inch = 25.4;\r
 \r
         NodeList lst;\r
@@ -296,16 +295,6 @@ public class XSSFPicture extends XSSFShape {
         return new int[]{hdpi, vdpi};\r
     }\r
 \r
-    /**\r
-     * return the anchor that is used by this shape.\r
-     *\r
-     * @return  the anchor that is used by this shape.\r
-     */\r
-    public XSSFClientAnchor getAnchor(){\r
-        CTTwoCellAnchor ctAnchor = (CTTwoCellAnchor)getShapeContainer();\r
-        return new XSSFClientAnchor(ctAnchor.getFrom(), ctAnchor.getTo());\r
-    }\r
-\r
     /**\r
      * Return picture data for this shape\r
      *\r
@@ -322,4 +311,8 @@ public class XSSFPicture extends XSSFShape {
         return null;\r
     }\r
 \r
+    protected CTShapeProperties getShapeProperties(){\r
+        return ctPicture.getSpPr();\r
+    }\r
+\r
 }\r
index 799479dc98b7db2e8fde4c830ff33c4d453c97a0..8d1a585730af2949dcf7a2383b0dd4a0a83c9559 100644 (file)
@@ -108,7 +108,7 @@ public class XSSFRichTextString implements RichTextString {
             font.setFontName("#" + fontIndex);
             fontIdRuns = new ArrayList<CTRPrElt>();
         } else {
-            font = (XSSFFont)styles.getFontAt(fontIndex);
+            font = styles.getFontAt(fontIndex);
         }
         applyFont(startIndex, endIndex, font);
     }
@@ -219,7 +219,7 @@ public class XSSFRichTextString implements RichTextString {
             font.setFontName("#" + fontIndex);
             fontIdRuns = new ArrayList<CTRPrElt>();
         } else {
-            font = (XSSFFont)styles.getFontAt(fontIndex);
+            font = styles.getFontAt(fontIndex);
         }
         applyFont(font);
     }
@@ -425,7 +425,7 @@ public class XSSFRichTextString implements RichTextString {
                     String fontName = pr.getRFontArray(0).getVal();
                     if(fontName.startsWith("#")){
                         int idx = Integer.parseInt(fontName.substring(1));
-                        XSSFFont font = (XSSFFont)styles.getFontAt(idx);
+                        XSSFFont font = styles.getFontAt(idx);
                         pr.removeRFont(0);
                         setRunAttributes(font.getCTFont(), pr);
                     }
index 5c90429dd2628ccc2f3661282ab8a99cafc9bcda..e65224e72f43a89d9e96651829746a5cfcb394e4 100644 (file)
@@ -28,7 +28,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;
 
 
-public class XSSFRow implements Row {
+public class XSSFRow implements Row, Comparable {
 
     private CTRow row;
     
@@ -76,8 +76,20 @@ public class XSSFRow implements Row {
     }
 
     public int compareTo(Object obj) {
-        // TODO Auto-generated method stub
-        return 0;
+        XSSFRow loc = (XSSFRow) obj;
+        if (this.getRowNum() == loc.getRowNum())
+        {
+            return 0;
+        }
+        if (this.getRowNum() < loc.getRowNum())
+        {
+            return -1;
+        }
+        if (this.getRowNum() > loc.getRowNum())
+        {
+            return 1;
+        }
+        return -1;
     }
 
     public XSSFCell createCell(int column) {
@@ -184,18 +196,29 @@ public class XSSFRow implements Row {
        return -1;
     }
 
+    /**
+     * Get the row's height measured in twips (1/20th of a point). If the height is not set, the default worksheet value is returned,
+     * See {@link org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints()}
+     *
+     * @return row height measured in twips (1/20th of a point)
+     */
     public short getHeight() {
-       if (this.row.getHt() > 0) {
-               return (short) (this.row.getHt());
-       }
-        return -1;
+        return (short)(getHeightInPoints()*20);
     }
 
+    /**
+     * Returns row height measured in point size. If the height is not set, the default worksheet value is returned,
+     * See {@link org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints()}
+     *
+     * @return row height measured in point size
+     * @see org.apache.poi.xssf.usermodel.XSSFSheet#getDefaultRowHeightInPoints()
+     */
     public float getHeightInPoints() {
-       if (this.row.getHt() > 0) {
-               return (short) this.row.getHt();
-       }
-        return -1;
+       if (this.row.isSetHt()) {
+               return (float) this.row.getHt();
+       } else {
+            return sheet.getDefaultRowHeightInPoints();
+        }
     }
 
     /**
@@ -259,18 +282,28 @@ public class XSSFRow implements Row {
        }
     }
 
+    /**
+     *  Set the height in "twips" or  1/20th of a point.
+     *
+     * @param height the height in "twips" or  1/20th of a point. <code>-1</code>  resets to the default height
+     */
     public void setHeight(short height) {
-       this.row.setHt((double) height);
-       this.row.setCustomHeight(true);
-    }
+       if(height == -1){
+            this.row.unsetHt();
+            this.row.unsetCustomHeight();
+        } else {
+            this.row.setHt((double)height/20);
+            this.row.setCustomHeight(true);
 
-    public void setHeight(double height) {
-       this.row.setHt((double) height);
-       this.row.setCustomHeight(true);
+        }
     }
-
+    /**
+     * Set the row's height in points.
+     *
+     * @param height the height in points. <code>-1</code>  resets to the default height
+     */
     public void setHeightInPoints(float height) {
-           setHeight((short)height);
+           setHeight((short)(height*20));
     }
 
     public void setRowNum(int rowNum) {
index 861c96b525b1b7b8b24c0161acbe073c0f209b59..ad6c27271b9397622f9535a517d78c30834a3a0c 100755 (executable)
@@ -21,73 +21,135 @@ import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAn
 import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTAbsoluteAnchor;\r
 import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTOneCellAnchor;\r
 import org.openxmlformats.schemas.drawingml.x2006.chartDrawing.CTGroupShape;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
 \r
 /**\r
  * Represents a shape in a SpreadsheetML drawing.\r
- * \r
+ *\r
  * @author Yegor Kozlov\r
  */\r
 public abstract class XSSFShape {\r
+    public static final int EMU_PER_PIXEL = 9525;\r
     public static final int EMU_PER_POINT = 12700;\r
 \r
+    public static final int POINT_DPI = 72;\r
+    public static final int PIXEL_DPI = 96;\r
 \r
     /**\r
-     * Shape container. Can be CTTwoCellAnchor, CTOneCellAnchor, CTAbsoluteAnchor or CTGroupShape\r
+     * Parent drawing\r
      */\r
-    private XmlObject spContainer;\r
+    protected XSSFDrawing drawing;\r
 \r
     /**\r
-     * Parent drawing\r
+     * The parent shape, always not-null for shapes in groups\r
      */\r
-    private XSSFDrawing drawing;\r
+    protected XSSFShapeGroup parent;\r
 \r
     /**\r
-     * The parent shape, always not-null for shapes in groups\r
+     * anchor that is used by this shape\r
+     */\r
+    protected XSSFAnchor anchor;\r
+\r
+    /**\r
+     * Return the drawing that owns this shape\r
+     *\r
+     * @return the parent drawing that owns this shape\r
+     */\r
+    public XSSFDrawing getDrawing(){\r
+        return drawing;\r
+    }\r
+\r
+    /**\r
+     * Gets the parent shape.\r
+     */\r
+    public XSSFShapeGroup getParent()\r
+    {\r
+        return parent;\r
+    }\r
+\r
+    /**\r
+     * @return  the anchor that is used by this shape.\r
      */\r
-    private XSSFShape parent;\r
+    public XSSFAnchor getAnchor()\r
+    {\r
+        return anchor;\r
+    }\r
+\r
+    /**\r
+     * Returns xml bean with shape properties. \r
+     *\r
+     * @return xml bean with shape properties.\r
+     */\r
+    protected abstract CTShapeProperties getShapeProperties();\r
 \r
     /**\r
-     * Construct a new XSSFSimpleShape object.\r
+     * Whether this shape is not filled with a color\r
      *\r
-     * @param parent the XSSFDrawing that owns this shape\r
-     * @param anchor an object that encloses the shape bean,\r
-     *   can be CTTwoCellAnchor, CTOneCellAnchor, CTAbsoluteAnchor or CTGroupShape\r
+     * @return true if this shape is not filled with a color.\r
      */\r
-    protected XSSFShape(XSSFDrawing parent, XmlObject anchor){\r
-        drawing = parent;\r
-        if(!(anchor instanceof CTTwoCellAnchor) && !(anchor instanceof CTOneCellAnchor) &&\r
-           !(anchor instanceof CTAbsoluteAnchor) && !(anchor instanceof CTGroupShape)) {\r
-            throw new IllegalArgumentException("anchor must be one of the following types: " +\r
-                    "CTTwoCellAnchor, CTOneCellAnchor, CTAbsoluteAnchor or CTGroupShape");\r
-        }\r
-        spContainer = anchor;\r
+    public boolean isNoFill() {\r
+        return getShapeProperties().isSetNoFill();\r
     }\r
 \r
     /**\r
-     * Return the anchor bean that encloses this shape.\r
-     * Can be CTTwoCellAnchor, CTOneCellAnchor, CTAbsoluteAnchor or CTGroupShape.\r
+     * Sets whether this shape is filled or transparent.\r
      *\r
-     * @return the anchor bean that encloses this shape\r
+     * @param noFill if true then no fill will be applied to the shape element.\r
      */\r
-    public XmlObject getShapeContainer(){\r
-        return spContainer;\r
+    public void setNoFill(boolean noFill) {\r
+        CTShapeProperties props = getShapeProperties();\r
+        //unset solid and pattern fills if they are set\r
+        if (props.isSetPattFill()) props.unsetPattFill();\r
+        if (props.isSetSolidFill()) props.unsetSolidFill();\r
+\r
+        props.setNoFill(CTNoFillProperties.Factory.newInstance());\r
     }\r
 \r
     /**\r
-     * Return the drawing that owns this shape\r
+     * Sets the color used to fill this shape using the solid fill pattern.\r
+     */\r
+    public void setFillColor(int red, int green, int blue) {\r
+        CTShapeProperties props = getShapeProperties();\r
+        CTSolidColorFillProperties fill = props.isSetSolidFill() ? props.getSolidFill() : props.addNewSolidFill();\r
+        CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();\r
+        rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue});\r
+        fill.setSrgbClr(rgb);\r
+    }\r
+\r
+    /**\r
+     * The color applied to the lines of this shape.\r
+     */\r
+    public void setLineStyleColor( int red, int green, int blue ) {\r
+        CTShapeProperties props = getShapeProperties();\r
+        CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();\r
+        CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln.getSolidFill() : ln.addNewSolidFill();\r
+        CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();\r
+        rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue});\r
+        fill.setSrgbClr(rgb);\r
+    }\r
+\r
+    /**\r
+     * Specifies the width to be used for the underline stroke.\r
      *\r
-     * @return the parent drawing that owns this shape\r
+     * @param lineWidth width in points\r
      */\r
-    public XSSFDrawing getDrawing(){\r
-        return drawing;\r
+    public void setLineWidth( double lineWidth ) {\r
+        CTShapeProperties props = getShapeProperties();\r
+        CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();\r
+        ln.setW((int)(lineWidth*EMU_PER_POINT));\r
     }\r
 \r
     /**\r
-     * Gets the parent shape.\r
+     * Sets the line style.\r
+     *\r
+     * @param lineStyle\r
      */\r
-    public XSSFShape getParent()\r
-    {\r
-        return parent;\r
+    public void setLineStyle( int lineStyle ) {\r
+        CTShapeProperties props = getShapeProperties();\r
+        CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();\r
+        CTPresetLineDashProperties dashStyle = CTPresetLineDashProperties.Factory.newInstance();\r
+        dashStyle.setVal(STPresetLineDashVal.Enum.forInt(lineStyle+1));\r
+        ln.setPrstDash(dashStyle);\r
     }\r
 \r
 }\r
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFShapeGroup.java
new file mode 100755 (executable)
index 0000000..f483393
--- /dev/null
@@ -0,0 +1,189 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.xssf.usermodel;\r
+\r
+import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
+import org.openxml4j.opc.PackagePartName;\r
+import org.openxml4j.opc.PackageRelationship;\r
+import org.openxml4j.opc.TargetMode;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * This object specifies a group shape that represents many shapes grouped together. This shape is to be treated\r
+ * just as if it were a regular shape but instead of being described by a single geometry it is made up of all the\r
+ * shape geometries encompassed within it. Within a group shape each of the shapes that make up the group are\r
+ * specified just as they normally would.\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public class XSSFShapeGroup extends XSSFShape {\r
+    private static CTGroupShape prototype = null;\r
+\r
+    private CTGroupShape ctGroup;\r
+\r
+    /**\r
+     * Construct a new XSSFSimpleShape object.\r
+     *\r
+     * @param drawing the XSSFDrawing that owns this shape\r
+     * @param ctGroup the XML bean that stores this group content\r
+     */\r
+    public XSSFShapeGroup(XSSFDrawing drawing, CTGroupShape ctGroup) {\r
+        this.drawing = drawing;\r
+        this.ctGroup = ctGroup;\r
+    }\r
+\r
+    /**\r
+     * Initialize default structure of a new shape group\r
+     */\r
+    protected static CTGroupShape prototype() {\r
+        if (prototype == null) {\r
+            CTGroupShape shape = CTGroupShape.Factory.newInstance();\r
+\r
+            CTGroupShapeNonVisual nv = shape.addNewNvGrpSpPr();\r
+            CTNonVisualDrawingProps nvpr = nv.addNewCNvPr();\r
+            nvpr.setId(0);\r
+            nvpr.setName("Group 0");\r
+            nv.addNewCNvGrpSpPr();\r
+            CTGroupShapeProperties sp = shape.addNewGrpSpPr();\r
+            CTGroupTransform2D t2d = sp.addNewXfrm();\r
+            CTPositiveSize2D p1 = t2d.addNewExt();\r
+            p1.setCx(0);\r
+            p1.setCy(0);\r
+            CTPoint2D p2 = t2d.addNewOff();\r
+            p2.setX(0);\r
+            p2.setY(0);\r
+            CTPositiveSize2D p3 = t2d.addNewChExt();\r
+            p3.setCx(0);\r
+            p3.setCy(0);\r
+            CTPoint2D p4 = t2d.addNewChOff();\r
+            p4.setX(0);\r
+            p4.setY(0);\r
+\r
+            prototype = shape;\r
+        }\r
+        return prototype;\r
+    }\r
+\r
+    /**\r
+     * Constructs a textbox.\r
+     *\r
+     * @param anchor the child anchor describes how this shape is attached\r
+     *               to the group.\r
+     * @return      the newly created textbox.\r
+     */\r
+    public XSSFTextBox createTextbox(XSSFChildAnchor anchor){\r
+        CTShape ctShape = ctGroup.addNewSp();\r
+        ctShape.set(XSSFSimpleShape.prototype());\r
+\r
+        XSSFTextBox shape = new XSSFTextBox(getDrawing(), ctShape);\r
+        shape.parent = this;\r
+        shape.anchor = anchor;\r
+        shape.getCTShape().getSpPr().setXfrm(anchor.getCTTransform2D());\r
+        return shape;\r
+\r
+    }\r
+    /**\r
+     * Creates a simple shape.  This includes such shapes as lines, rectangles,\r
+     * and ovals.\r
+     *\r
+     * @param anchor the child anchor describes how this shape is attached\r
+     *               to the group.\r
+     * @return the newly created shape.\r
+     */\r
+    public XSSFSimpleShape createSimpleShape(XSSFChildAnchor anchor) {\r
+        CTShape ctShape = ctGroup.addNewSp();\r
+        ctShape.set(XSSFSimpleShape.prototype());\r
+\r
+        XSSFSimpleShape shape = new XSSFSimpleShape(getDrawing(), ctShape);\r
+        shape.parent = this;\r
+        shape.anchor = anchor;\r
+        shape.getCTShape().getSpPr().setXfrm(anchor.getCTTransform2D());\r
+        return shape;\r
+    }\r
+\r
+    /**\r
+     * Creates a simple shape.  This includes such shapes as lines, rectangles,\r
+     * and ovals.\r
+     *\r
+     * @param anchor the child anchor describes how this shape is attached\r
+     *               to the group.\r
+     * @return the newly created shape.\r
+     */\r
+    public XSSFConnector createConnector(XSSFChildAnchor anchor) {\r
+        CTConnector ctShape = ctGroup.addNewCxnSp();\r
+        ctShape.set(XSSFConnector.prototype());\r
+\r
+        XSSFConnector shape = new XSSFConnector(getDrawing(), ctShape);\r
+        shape.parent = this;\r
+        shape.anchor = anchor;\r
+        shape.getCTConnector().getSpPr().setXfrm(anchor.getCTTransform2D());\r
+        return shape;\r
+    }\r
+\r
+    /**\r
+     * Creates a picture.\r
+     *\r
+     * @param anchor       the client anchor describes how this picture is attached to the sheet.\r
+     * @param pictureIndex the index of the picture in the workbook collection of pictures,\r
+     *                     {@link XSSFWorkbook#getAllPictures()} .\r
+     * @return the newly created picture shape.\r
+     */\r
+    public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex) {\r
+        PackageRelationship rel = getDrawing().addPictureReference(pictureIndex);\r
+\r
+        CTPicture ctShape = ctGroup.addNewPic();\r
+        ctShape.set(XSSFPicture.prototype());\r
+\r
+        XSSFPicture shape = new XSSFPicture(getDrawing(), ctShape);\r
+        shape.parent = this;\r
+        shape.anchor = anchor;\r
+        shape.setPictureReference(rel);\r
+        return shape;\r
+    }\r
+\r
+    public CTGroupShape getCTGroupShape() {\r
+        return ctGroup;\r
+    }\r
+\r
+    /**\r
+     * Sets the coordinate space of this group.  All children are constrained\r
+     * to these coordinates.\r
+     */\r
+    public void setCoordinates(int x1, int y1, int x2, int y2) {\r
+        CTGroupTransform2D t2d = ctGroup.getGrpSpPr().getXfrm();\r
+        CTPoint2D off = t2d.getOff();\r
+        off.setX(x1);\r
+        off.setY(y1);\r
+        CTPositiveSize2D ext = t2d.getExt();\r
+        ext.setCx(x2);\r
+        ext.setCy(y2);\r
+\r
+        CTPoint2D chOff = t2d.getChOff();\r
+        chOff.setX(x1);\r
+        chOff.setY(y1);\r
+        CTPositiveSize2D chExt = t2d.getChExt();\r
+        chExt.setCx(x2);\r
+        chExt.setCy(y2);\r
+    }\r
+\r
+    protected CTShapeProperties getShapeProperties() {\r
+        throw new IllegalStateException("Not supported for shape group");\r
+    }\r
+\r
+}\r
index 127e43851050bf9c00632b3dfbef3772e1eabbaa..e2632b7d179c8e7cfbb57eb0cf70a610dd217aa7 100644 (file)
@@ -60,6 +60,15 @@ import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelations
 public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
     private static POILogger logger = POILogFactory.getLogger(XSSFSheet.class);
 
+    /**
+     * Column width measured as the number of characters of the maximum digit width of the
+     * numbers 0, 1, 2, ..., 9 as rendered in the normal style's font. There are 4 pixels of margin
+     * padding (two on each side), plus 1 pixel padding for the gridlines.
+     *
+     * This value is the same for default font in Office 2007 (Calibry) and Office 2003 and earlier (Arial)
+     */
+    private static float DEFAULT_COLUMN_WIDTH = 9.140625f;
+
     protected CTSheet sheet;
     protected CTWorksheet worksheet;
     protected CTDialogsheet dialogsheet;
@@ -260,7 +269,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         CTDrawing ctDrawing = worksheet.getDrawing();
         if(ctDrawing == null) {
             //drawingNumber = #drawings.size() + 1
-            int drawingNumber = getPackagePart().getPackage().getPartsByRelationshipType(XSSFRelation.DRAWINGS.getRelation()).size() + 1;
+            int drawingNumber = getPackagePart().getPackage().getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()).size() + 1;
             drawing = (XSSFDrawing)createRelationship(XSSFRelation.DRAWINGS, XSSFFactory.getInstance(), drawingNumber);
             String relId = drawing.getPackageRelationship().getId();
 
@@ -425,32 +434,62 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         return worksheet.getColBreaks();
     }
 
+    /**
+     * Get the actual column width (in units of 1/256th of a character width )
+     *
+     * <p>
+     * Note, the returned  value is always gerater that {@link #getDefaultColumnWidth()} because the latter does not include margins.
+     * Actual column width measured as the number of characters of the maximum digit width of the
+     * numbers 0, 1, 2, ..., 9 as rendered in the normal style's font. There are 4 pixels of margin
+     * padding (two on each side), plus 1 pixel padding for the gridlines.
+     * </p>
+     *
+     * @param columnIndex - the column to set (0-based)
+     * @return width - the width in units of 1/256th of a character width
+     */
     public int getColumnWidth(int columnIndex) {
         CTCol col = columnHelper.getColumn(columnIndex, false);
-        return col == null ? getDefaultColumnWidth() : (int)col.getWidth();
-    }
-    public short getColumnWidth(short column) {
-        return (short) getColumnWidth(column & 0xFFFF);
+        double width = col == null || !col.isSetWidth() ? DEFAULT_COLUMN_WIDTH : col.getWidth();
+        return (int)(width*256);
     }
 
+    /**
+     * Get the default column width for the sheet (if the columns do not define their own width) in
+     * characters.
+     * <p>
+     * Note, this value is different from {@link #getColumnWidth(int)}. The latter is always greater and includes
+     * 4 pixels of margin padding (two on each side), plus 1 pixel padding for the gridlines.
+     * </p>
+     * @return default column width
+     */
     public int getDefaultColumnWidth() {
         CTSheetFormatPr pr = getSheetTypeSheetFormatPr();
-        return pr.isSetDefaultColWidth() ? (int)pr.getDefaultColWidth() : (int)pr.getBaseColWidth();
+        return (int)pr.getBaseColWidth();
     }
 
+    /**
+     * Get the default row height for the sheet (if the rows do not define their own height) in
+     * twips (1/20 of  a point)
+     *
+     * @return  default row height
+     */
     public short getDefaultRowHeight() {
         return (short) (getSheetTypeSheetFormatPr().getDefaultRowHeight() * 20);
     }
 
-    protected CTSheetFormatPr getSheetTypeSheetFormatPr() {
-        if (worksheet.getSheetFormatPr() == null) {
-            worksheet.setSheetFormatPr(CTSheetFormatPr.Factory.newInstance());
-        }
-        return worksheet.getSheetFormatPr();
+    /**
+     * Get the default row height for the sheet measued in point size (if the rows do not define their own height).
+     *
+     * @return  default row height in points
+     */
+    public float getDefaultRowHeightInPoints() {
+        return (float)getSheetTypeSheetFormatPr().getDefaultRowHeight();
     }
 
-    public float getDefaultRowHeightInPoints() {
-        return (short) getSheetTypeSheetFormatPr().getDefaultRowHeight();
+    protected CTSheetFormatPr getSheetTypeSheetFormatPr() {
+        return worksheet.isSetSheetFormatPr() ?
+               worksheet.getSheetFormatPr() :
+               worksheet.addNewSheetFormatPr();
     }
 
     public boolean getDialog() {
@@ -589,8 +628,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
      *  when set, used on even pages.
      */
     public Header getEvenHeader() {
-        return new XSSFEvenHeader(getSheetTypeHeaderFooter()
-);
+        return new XSSFEvenHeader(getSheetTypeHeaderFooter());
     }
     /**
      * Returns the first page header. Not there by
@@ -931,21 +969,39 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         return false;
     }
 
+    /**
+     * Get the hidden state for a given column.
+     *
+     * @param columnIndex - the column to set (0-based)
+     * @return hidden - <code>false</code> if the column is visible
+     */
     public boolean isColumnHidden(int columnIndex) {
         return columnHelper.getColumn(columnIndex, false).getHidden();
     }
-    public boolean isColumnHidden(short column) {
-        return isColumnHidden(column & 0xFFFF);
-    }
 
+    /**
+     * Gets the flag indicating whether this sheet should display formulas.
+     *
+     * @return <code>true</code> if this sheet should display formulas.
+     */
     public boolean isDisplayFormulas() {
         return getSheetTypeSheetView().getShowFormulas();
     }
 
+    /**
+     * Gets the flag indicating whether this sheet should display gridlines.
+     *
+     * @return <code>true</code> if this sheet should display gridlines.
+     */
     public boolean isDisplayGridlines() {
         return getSheetTypeSheetView().getShowGridLines();
     }
 
+    /**
+     * Gets the flag indicating whether this sheet should display row and column headings.
+     *
+     * @return <code>true</code> if this sheet should display row and column headings.
+     */
     public boolean isDisplayRowColHeadings() {
         return getSheetTypeSheetView().getShowRowColHeaders();
     }
@@ -1098,36 +1154,57 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
 
     }
 
-    public void setColumnHidden(int columnIndex, boolean hidden) {
+    /**
+     * Get the visibility state for a given column.
+     *
+     * @param columnIndex - the column to get (0-based)
+     * @param hidden - the visiblity state of the column
+     */
+     public void setColumnHidden(int columnIndex, boolean hidden) {
         columnHelper.setColHidden(columnIndex, hidden);
-    }
-    public void setColumnHidden(short column, boolean hidden) {
-        setColumnHidden(column & 0xFFFF, hidden);
-    }
+     }
 
+    /**
+     * Set the width (in units of 1/256th of a character width)
+     *
+     * @param columnIndex - the column to set (0-based)
+     * @param width - the width in units of 1/256th of a character width
+     */
     public void setColumnWidth(int columnIndex, int width) {
-        columnHelper.setColWidth(columnIndex, width);
-    }
-    public void setColumnWidth(short column, short width) {
-        setColumnWidth(column & 0xFFFF, width & 0xFFFF);
+        columnHelper.setColWidth(columnIndex, (double)width/256);
     }
 
     public void setDefaultColumnStyle(short column, CellStyle style) {
         columnHelper.setColDefaultStyle(column, style);
     }
 
+    /**
+     * Specifies the number of characters of the maximum digit width of the normal style's font.
+     * This value does not include margin padding or extra padding for gridlines. It is only the
+     * number of characters.
+     *
+     * @param width the number of characters. Default value is <code>8</code>.
+     */
     public void setDefaultColumnWidth(int width) {
-        getSheetTypeSheetFormatPr().setDefaultColWidth(width);
-    }
-    public void setDefaultColumnWidth(short width) {
-        setDefaultColumnWidth(width & 0xFFFF);
+        getSheetTypeSheetFormatPr().setBaseColWidth(width);
     }
 
+    /**
+     * Set the default row height for the sheet (if the rows do not define their own height) in
+     * twips (1/20 of  a point)
+     *
+     * @param  height default row height in  twips (1/20 of  a point)
+     */
     public void setDefaultRowHeight(short height) {
-        getSheetTypeSheetFormatPr().setDefaultRowHeight(height / 20);
+        getSheetTypeSheetFormatPr().setDefaultRowHeight((double)height / 20);
 
     }
 
+    /**
+     * Sets default row height measured in point size.
+     *
+     * @param height default row height measured in point size.
+     */
     public void setDefaultRowHeightInPoints(float height) {
         getSheetTypeSheetFormatPr().setDefaultRowHeight(height);
 
@@ -1142,6 +1219,11 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         }
     }
 
+    /**
+     * Sets the flag indicating whether this sheet should display formulas.
+     *
+     * @param show <code>true</code> if this sheet should display formulas.
+     */
     public void setDisplayFormulas(boolean show) {
         getSheetTypeSheetView().setShowFormulas(show);
     }
@@ -1153,15 +1235,30 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         return getDefaultSheetView();
     }
 
+    /**
+     * Sets the flag indicating whether this sheet should display gridlines.
+     *
+     * @param show <code>true</code> if this sheet should display gridlines.
+     */
     public void setDisplayGridlines(boolean show) {
         getSheetTypeSheetView().setShowGridLines(show);
     }
 
+    /**
+     * Sets the flag indicating whether this sheet should display row and column headings.
+     *
+     * @param show <code>true</code> if this sheet should display row and column headings.
+     */
     public void setDisplayRowColHeadings(boolean show) {
         getSheetTypeSheetView().setShowRowColHeaders(show);
     }
 
-    public void setFitToPage(boolean b) {
+    /**
+     * Flag indicating whether the Fit to Page print option is enabled.
+     *
+     * @param b <code>true</code> if the Fit to Page print option is enabled.
+     */
+     public void setFitToPage(boolean b) {
         getSheetTypePageSetUpPr().setFitToPage(b);
     }
 
@@ -1169,6 +1266,11 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         setPrintGridlines(value);
     }
 
+    /**
+     * Center on page horizontally when printing.
+     *
+     * @param value whether to center on page horizontally when printing.
+     */
     public void setHorizontallyCenter(boolean value) {
         getSheetTypePrintOptions().setHorizontalCentered(value);
     }
@@ -1306,15 +1408,45 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
         getSheetTypeSheetView().setZoomScaleSheetLayoutView(scale);
     }
 
+    /**
+     * Shifts rows between startRow and endRow n number of rows.
+     * If you use a negative number, it will shift rows up.
+     * Code ensures that rows don't wrap around.
+     *
+     * Calls shiftRows(startRow, endRow, n, false, false);
+     *
+     * <p>
+     * Additionally shifts merged regions that are completely defined in these
+     * rows (ie. merged 2 cells on a row to be shifted).
+     * @param startRow the row to start shifting
+     * @param endRow the row to end shifting
+     * @param n the number of rows to shift
+     */
     public void shiftRows(int startRow, int endRow, int n) {
         shiftRows(startRow, endRow, n, false, false);
     }
 
+    /**
+     * Shifts rows between startRow and endRow n number of rows.
+     * If you use a negative number, it will shift rows up.
+     * Code ensures that rows don't wrap around
+     *
+     * <p>
+     * Additionally shifts merged regions that are completely defined in these
+     * rows (ie. merged 2 cells on a row to be shifted).
+     * <p>
+     * TODO Might want to add bounds checking here
+     * @param startRow the row to start shifting
+     * @param endRow the row to end shifting
+     * @param n the number of rows to shift
+     * @param copyRowHeight whether to copy the row height during the shift
+     * @param resetOriginalRowHeight whether to set the original row's height to the default
+     */
     public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
         for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
             Row row = it.next();
             if (!copyRowHeight) {
-                row.setHeight((short)0);
+                row.setHeight((short)-1);
             }
             if (resetOriginalRowHeight && getDefaultRowHeight() >= 0) {
                 row.setHeight(getDefaultRowHeight());
index a564013d130643020ccbb2f03fc91d3ca3becb83..220765015d45dfab01f27d6960b91c7a281233a0 100755 (executable)
 ==================================================================== */\r
 package org.apache.poi.xssf.usermodel;\r
 \r
-import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;\r
 import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;\r
 import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShapeNonVisual;\r
 import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;\r
 \r
 /**\r
- * Represents an auto-shape in a SpreadsheetML drawing.\r
+ * Represents a shape with a predefined geometry in a SpreadsheetML drawing.\r
+ * Possible shape types are defined in {@link ShapeTypes}\r
  *\r
  * @author Yegor Kozlov\r
  */\r
 public class XSSFSimpleShape extends XSSFShape {\r
-\r
-    private CTShape ctShape;\r
+    /**\r
+     * A default instance of CTShape used for creating new shapes.\r
+     */\r
+    private static CTShape prototype = null;\r
 \r
     /**\r
-     * Construct a new XSSFSimpleShape object.\r
-     *\r
-     * @param parent the XSSFDrawing that owns this shape\r
-     * @param anchor the two cell anchor placeholder for this shape,\r
-     *               this object encloses the shape bean that holds all the shape properties\r
+     *  Xml bean that stores properties of this shape\r
      */\r
-    protected XSSFSimpleShape(XSSFDrawing parent, CTTwoCellAnchor anchor) {\r
-        super(parent, anchor);\r
-        ctShape = anchor.addNewSp();\r
-        newShape(ctShape);\r
+    private CTShape ctShape;\r
+\r
+    protected XSSFSimpleShape(XSSFDrawing drawing, CTShape ctShape) {\r
+        this.drawing = drawing;\r
+        this.ctShape = ctShape;\r
     }\r
 \r
     /**\r
-     * Initialize default structure of a new auto-shape\r
-     *\r
-     * @param shape newly created shape to initialize\r
+     * Prototype with the default structure of a new auto-shape.\r
      */\r
-    private static void newShape(CTShape shape) {\r
-        CTShapeNonVisual nv = shape.addNewNvSpPr();\r
-        CTNonVisualDrawingProps nvp = nv.addNewCNvPr();\r
-        int shapeId = 1;\r
-        nvp.setId(shapeId);\r
-        nvp.setName("Shape " + shapeId);\r
-        nv.addNewCNvSpPr();\r
-\r
-        CTShapeProperties sp = shape.addNewSpPr();\r
-        CTTransform2D t2d = sp.addNewXfrm();\r
-        CTPositiveSize2D p1 = t2d.addNewExt();\r
-        p1.setCx(0);\r
-        p1.setCy(0);\r
-        CTPoint2D p2 = t2d.addNewOff();\r
-        p2.setX(0);\r
-        p2.setY(0);\r
-\r
-        CTPresetGeometry2D geom = sp.addNewPrstGeom();\r
-        geom.setPrst(STShapeType.RECT);\r
-        geom.addNewAvLst();\r
-\r
-        CTShapeStyle style = shape.addNewStyle();\r
-        CTSchemeColor scheme = style.addNewLnRef().addNewSchemeClr();\r
-        scheme.setVal(STSchemeColorVal.ACCENT_1);\r
-        scheme.addNewShade().setVal(50000);\r
-        style.getLnRef().setIdx(2);\r
-\r
-        CTStyleMatrixReference fillref = style.addNewFillRef();\r
-        fillref.setIdx(1);\r
-        fillref.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);\r
-\r
-        CTStyleMatrixReference effectRef = style.addNewEffectRef();\r
-        effectRef.setIdx(0);\r
-        effectRef.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);\r
-\r
-        CTFontReference fontRef = style.addNewFontRef();\r
-        fontRef.setIdx(STFontCollectionIndex.MINOR);\r
-        fontRef.addNewSchemeClr().setVal(STSchemeColorVal.LT_1);\r
-\r
-        CTTextBody body = shape.addNewTxBody();\r
-        CTTextBodyProperties bodypr = body.addNewBodyPr();\r
-        bodypr.setAnchor(STTextAnchoringType.CTR);\r
-        bodypr.setRtlCol(false);\r
-        CTTextParagraph p = body.addNewP();\r
-        p.addNewPPr().setAlgn(STTextAlignType.CTR);\r
-\r
-        body.addNewLstStyle();\r
+    protected static CTShape prototype() {\r
+        if(prototype == null) {\r
+            CTShape shape = CTShape.Factory.newInstance();\r
+\r
+            CTShapeNonVisual nv = shape.addNewNvSpPr();\r
+            CTNonVisualDrawingProps nvp = nv.addNewCNvPr();\r
+            nvp.setId(1);\r
+            nvp.setName("Shape 1");\r
+            nv.addNewCNvSpPr();\r
+\r
+            CTShapeProperties sp = shape.addNewSpPr();\r
+            CTTransform2D t2d = sp.addNewXfrm();\r
+            CTPositiveSize2D p1 = t2d.addNewExt();\r
+            p1.setCx(0);\r
+            p1.setCy(0);\r
+            CTPoint2D p2 = t2d.addNewOff();\r
+            p2.setX(0);\r
+            p2.setY(0);\r
+\r
+            CTPresetGeometry2D geom = sp.addNewPrstGeom();\r
+            geom.setPrst(STShapeType.RECT);\r
+            geom.addNewAvLst();\r
+\r
+            CTShapeStyle style = shape.addNewStyle();\r
+            CTSchemeColor scheme = style.addNewLnRef().addNewSchemeClr();\r
+            scheme.setVal(STSchemeColorVal.ACCENT_1);\r
+            scheme.addNewShade().setVal(50000);\r
+            style.getLnRef().setIdx(2);\r
+\r
+            CTStyleMatrixReference fillref = style.addNewFillRef();\r
+            fillref.setIdx(1);\r
+            fillref.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);\r
+\r
+            CTStyleMatrixReference effectRef = style.addNewEffectRef();\r
+            effectRef.setIdx(0);\r
+            effectRef.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);\r
+\r
+            CTFontReference fontRef = style.addNewFontRef();\r
+            fontRef.setIdx(STFontCollectionIndex.MINOR);\r
+            fontRef.addNewSchemeClr().setVal(STSchemeColorVal.LT_1);\r
+\r
+            CTTextBody body = shape.addNewTxBody();\r
+            CTTextBodyProperties bodypr = body.addNewBodyPr();\r
+            bodypr.setAnchor(STTextAnchoringType.CTR);\r
+            bodypr.setRtlCol(false);\r
+            CTTextParagraph p = body.addNewP();\r
+            p.addNewPPr().setAlgn(STTextAlignType.CTR);\r
+            CTTextCharacterProperties endPr = p.addNewEndParaRPr();\r
+            endPr.setLang("en-US");\r
+            endPr.setSz(1100);\r
+\r
+            body.addNewLstStyle();\r
+\r
+            prototype = shape;\r
+        }\r
+        return prototype;\r
+    }\r
+\r
+    public CTShape getCTShape(){\r
+        return ctShape;\r
     }\r
 \r
     /**\r
@@ -117,62 +128,52 @@ public class XSSFSimpleShape extends XSSFShape {
         ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type));\r
     }\r
 \r
-\r
-    /**\r
-     * Whether this shape is not filled with a color\r
-     *\r
-     * @return true if this shape is not filled with a color.\r
-     */\r
-    public boolean isNoFill() {\r
-        return ctShape.getSpPr().isSetNoFill();\r
+    protected CTShapeProperties getShapeProperties(){\r
+        return ctShape.getSpPr();\r
     }\r
 \r
-    /**\r
-     * Sets whether this shape is filled or transparent.\r
-     *\r
-     * @param noFill if true then no fill will be applied to the shape element.\r
-     */\r
-    public void setNoFill(boolean noFill) {\r
-        CTShapeProperties props = ctShape.getSpPr();\r
-        //unset solid and pattern fills if they are set\r
-        if (props.isSetPattFill()) props.unsetPattFill();\r
-        if (props.isSetSolidFill()) props.unsetSolidFill();\r
+    public void setText(XSSFRichTextString str){\r
 \r
-        props.setNoFill(CTNoFillProperties.Factory.newInstance());\r
-    }\r
+        XSSFWorkbook wb = (XSSFWorkbook)getDrawing().getParent().getParent();\r
+        str.setStylesTableReference(wb.getStylesSource());\r
 \r
-    /**\r
-     * Sets the color used to fill this shape using the solid fill pattern.\r
-     */\r
-    public void setFillColor(int red, int green, int blue) {\r
-        CTShapeProperties props = ctShape.getSpPr();\r
-        CTSolidColorFillProperties fill = props.isSetSolidFill() ? props.getSolidFill() : props.addNewSolidFill();\r
-        CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();\r
-        rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue});\r
-        fill.setSrgbClr(rgb);\r
-    }\r
+        CTTextParagraph p = CTTextParagraph.Factory.newInstance();\r
+        if(str.numFormattingRuns() == 0){\r
+            CTRegularTextRun r = p.addNewR();\r
+            CTTextCharacterProperties rPr = r.addNewRPr();\r
+            rPr.setLang("en-US");\r
+            rPr.setSz(1100);\r
+            r.setT(str.getString());\r
+\r
+        } else {\r
+            for (int i = 0; i < str.getCTRst().sizeOfRArray(); i++) {\r
+                CTRElt lt = str.getCTRst().getRArray(i);\r
+                CTRPrElt ltPr = lt.getRPr();\r
+\r
+                CTRegularTextRun r = p.addNewR();\r
+                CTTextCharacterProperties rPr = r.addNewRPr();\r
+                rPr.setLang("en-US");\r
+\r
+                applyAttributes(ltPr, rPr);\r
+\r
+                r.setT(lt.getT());\r
+            }\r
+        }\r
+        ctShape.getTxBody().setPArray(new CTTextParagraph[]{p});\r
 \r
-    /**\r
-     * The color applied to the lines of this shape.\r
-     */\r
-    public void setLineStyleColor( int red, int green, int blue ) {\r
-        CTShapeProperties props = ctShape.getSpPr();\r
-        CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();\r
-        CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln.getSolidFill() : ln.addNewSolidFill();\r
-        CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();\r
-        rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue});\r
-        fill.setSrgbClr(rgb);\r
     }\r
 \r
     /**\r
-     * Specifies the width to be used for the underline stroke.\r
      *\r
-     * @param lineWidth width in points\r
+     * CTRPrElt --> CTFont adapter\r
      */\r
-    public void setLineWidth( double lineWidth ) {\r
-        CTShapeProperties props = ctShape.getSpPr();\r
-        CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();\r
-        ln.setW((int)(lineWidth*EMU_PER_POINT));\r
-    }\r
+    private static void applyAttributes(CTRPrElt pr, CTTextCharacterProperties rPr){\r
+\r
+        if(pr.sizeOfBArray() > 0) rPr.setB(pr.getBArray(0).getVal());\r
+        //if(pr.sizeOfUArray() > 0) rPr.setU(pr.getUArray(0).getVal());\r
+        if(pr.sizeOfIArray() > 0) rPr.setI(pr.getIArray(0).getVal());\r
 \r
+        CTTextFont rFont = rPr.addNewLatin();\r
+        rFont.setTypeface(pr.sizeOfRFontArray() > 0 ? pr.getRFontArray(0).getVal() : "Arial");\r
+    }\r
 }\r
diff --git a/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextBox.java b/src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFTextBox.java
new file mode 100755 (executable)
index 0000000..85032ab
--- /dev/null
@@ -0,0 +1,33 @@
+/* ====================================================================\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to You under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+==================================================================== */\r
+package org.apache.poi.xssf.usermodel;\r
+\r
+import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.*;\r
+\r
+/**\r
+ * Represents a text box in a SpreadsheetML drawing.\r
+ *\r
+ * @author Yegor Kozlov\r
+ */\r
+public class XSSFTextBox extends XSSFSimpleShape {\r
+\r
+    protected XSSFTextBox(XSSFDrawing drawing, CTShape ctShape) {\r
+        super(drawing, ctShape);\r
+    }\r
+\r
+}\r
index 8a10a266cebbbacf2c4c89d15236e6e459c4dbd1..c12c7ab7797782166be9b7220eab858ff0a9fe97 100644 (file)
@@ -19,6 +19,7 @@ package org.apache.poi.xssf.usermodel;
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.io.InputStream;
 import java.util.*;
 import javax.xml.namespace.QName;
 import org.apache.poi.POIXMLDocument;
@@ -30,6 +31,7 @@ import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 import org.apache.poi.util.PackageHelper;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.xssf.model.*;
 import org.apache.poi.POIXMLException;
 import org.apache.xmlbeans.XmlObject;
@@ -279,6 +281,31 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
         return imageNumber - 1;
     }
 
+    /**
+     * Adds a picture to the workbook.
+     *
+     * @param is                The sream to read image from
+     * @param format            The format of the picture.
+     *
+     * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
+     * @see #PICTURE_TYPE_EMF
+     * @see #PICTURE_TYPE_WMF
+     * @see #PICTURE_TYPE_PICT
+     * @see #PICTURE_TYPE_JPEG
+     * @see #PICTURE_TYPE_PNG
+     * @see #PICTURE_TYPE_DIB
+     * @see #getAllPictures()
+     */
+    public int addPicture(InputStream is, int format) throws IOException {
+        int imageNumber = getAllPictures().size() + 1;
+        XSSFPictureData img = (XSSFPictureData)createRelationship(XSSFPictureData.RELATIONS[format], XSSFFactory.getInstance(), imageNumber, true);
+        OutputStream out = img.getPackagePart().getOutputStream();
+        IOUtils.copy(is, out);
+        out.close();
+        pictures.add(img);
+        return imageNumber - 1;
+    }
+
     public XSSFSheet cloneSheet(int sheetNum) {
         XSSFSheet srcSheet = sheets.get(sheetNum);
         String srcName = getSheetName(sheetNum);
index f705b5b5b367e5cb9e38d581fb74cb088d684893..39dc9a1636aff5a29126db5783fd9a2cf4abeb35 100644 (file)
@@ -400,13 +400,11 @@ public final class TestXSSFCell extends TestCase {
 
        //BLANK
        assertEquals(hcell.toString(),xcell.toString());
-       System.out.println("BLANK==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
        //BOOLEAN
        xcell.setCellValue(true);
        xcell.setCellType(Cell.CELL_TYPE_BOOLEAN);
        hcell.setCellValue(true);
        hcell.setCellType(Cell.CELL_TYPE_BOOLEAN);
-       System.out.println("BOOLEAN==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
        assertEquals(hcell.toString(),xcell.toString());
        
        //NUMERIC
@@ -415,7 +413,6 @@ public final class TestXSSFCell extends TestCase {
        xcell.setCellType(Cell.CELL_TYPE_NUMERIC);
        hcell.setCellValue(1234);
        hcell.setCellType(Cell.CELL_TYPE_NUMERIC);
-       System.out.println("NUMERIC==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
        assertEquals(hcell.toString(),xcell.toString());
        
        //DATE ********************
@@ -434,7 +431,6 @@ public final class TestXSSFCell extends TestCase {
        hstyle.setDataFormat(hformat.getFormat("YYYY-MM-DD"));
        hcell.setCellStyle(hstyle);
        
-       System.out.println("DATE==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
        assertEquals(hcell.toString(),xcell.toString());
        
        
@@ -443,7 +439,6 @@ public final class TestXSSFCell extends TestCase {
        xcell.setCellType(Cell.CELL_TYPE_STRING);
        hcell.setCellValue(new HSSFRichTextString("text string"));
        hcell.setCellType(Cell.CELL_TYPE_STRING);
-       System.out.println("STRING==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
        assertEquals(hcell.toString(),xcell.toString());
        
        //ERROR
@@ -453,13 +448,11 @@ public final class TestXSSFCell extends TestCase {
        hcell.setCellErrorValue((byte)0);
        hcell.setCellType(Cell.CELL_TYPE_ERROR);
 
-       System.out.println("ERROR==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
        assertEquals(hcell.toString(),xcell.toString());
        
        //FORMULA
        xcell.setCellFormula("A1+B2");
        hcell.setCellValue("A1+B2");
-       System.out.println("FORMULA==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
        assertEquals(hcell.toString(),xcell.toString());
        
     }
index c2ff6acad3ea434d8de48edc1b46bf6e3066b4c8..430924c8565924bfa5014dd8d4aafcc1d8626dda 100755 (executable)
@@ -67,4 +67,13 @@ public class TestXSSFDrawing extends TestCase {
         assertEquals(drawingId, sheet.getWorksheet().getDrawing().getId());\r
 \r
     }\r
+    public void testMultipleDrawings(){\r
+        XSSFWorkbook wb = new XSSFWorkbook();\r
+        for (int i = 0; i < 3; i++) {\r
+            XSSFSheet sheet = wb.createSheet();\r
+            XSSFDrawing drawing = sheet.createDrawingPatriarch();\r
+        }\r
+        org.openxml4j.opc.Package pkg = wb.getPackage();\r
+        assertEquals(3, pkg.getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()).size());\r
+    }\r
 }\r
index 8e2f437233183a5499adec820f080c3f85c865a2..f10b9e216f3c08dc94b19d1b36e212414351594f 100644 (file)
@@ -25,6 +25,8 @@ import junit.framework.TestCase;
 
 import org.apache.poi.ss.usermodel.Cell;
 import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.xssf.model.SharedStringsTable;
 import org.apache.poi.xssf.XSSFTestDataSamples;
 import org.apache.poi.hssf.usermodel.HSSFSheet;
@@ -131,15 +133,15 @@ public final class TestXSSFRow extends TestCase {
         XSSFRow row = getSampleRow();
         // I assume that "ht" attribute value is in 'points', please verify that
         // Test that no rowHeight is set
-        assertEquals((short) -1, row.getHeight());
+        assertEquals(row.getSheet().getDefaultRowHeight(), row.getHeight());
         // Set a rowHeight and test the new value
         row.setHeight((short) 240);
         assertEquals((short) 240.0, row.getHeight());
-        assertEquals((float)240.0, row.getHeightInPoints());
+        assertEquals(12.0f, row.getHeightInPoints());
         // Set a new rowHeight in points and test the new value
         row.setHeightInPoints(13);
         assertEquals((float) 13.0, row.getHeightInPoints());
-        assertEquals((short) 13.0, row.getHeight());
+        assertEquals((short)(13.0*20), row.getHeight());
     }
 
     public void testGetSetZeroHeight() throws Exception {
@@ -225,8 +227,7 @@ public final class TestXSSFRow extends TestCase {
 
     private static XSSFSheet createParentObjects() {
         XSSFWorkbook wb = new XSSFWorkbook();
-        wb.setSharedStringSource(new SharedStringsTable());
-        return new XSSFSheet(wb);
+        return wb.createSheet();
     }
 
     /**
@@ -298,4 +299,37 @@ public final class TestXSSFRow extends TestCase {
         assertEquals(-1, sheet.getRow(0).getLastCellNum());
         assertEquals(-1, sheet.getRow(0).getFirstCellNum());
     }
+
+    public void testRowHeightCompatibility(){
+        Workbook wb1 = new HSSFWorkbook();
+        Workbook wb2 = new XSSFWorkbook();
+
+        Sheet sh1 = wb1.createSheet();
+        Sheet sh2 = wb2.createSheet();
+
+        sh2.setDefaultRowHeight(sh1.getDefaultRowHeight());
+
+        assertEquals(sh1.getDefaultRowHeight(), sh2.getDefaultRowHeight());
+
+        //junit.framework.AssertionFailedError: expected:<12.0> but was:<12.75>
+        //YK: there is a bug in HSSF version, it trunkates decimal part
+        //assertEquals(sh1.getDefaultRowHeightInPoints(), sh2.getDefaultRowHeightInPoints());
+
+        Row row1 = sh1.createRow(0);
+        Row row2 = sh2.createRow(0);
+
+        assertEquals(row1.getHeight(), row2.getHeight());
+        assertEquals(row1.getHeightInPoints(), row2.getHeightInPoints());
+        row1.setHeight((short)100);
+        row2.setHeight((short)100);
+        assertEquals(row1.getHeight(), row2.getHeight());
+        assertEquals(row1.getHeightInPoints(), row2.getHeightInPoints());
+
+        row1.setHeightInPoints(25.5f);
+        row2.setHeightInPoints(25.5f);
+        assertEquals(row1.getHeight(), row2.getHeight());
+        assertEquals(row1.getHeightInPoints(), row2.getHeightInPoints());
+
+
+    }
 }
index 0400c5b4d7cc231333bda1e59aed16309e8d5b98..ea6bd8c1540483221f47991967394d81e5617ef6 100644 (file)
@@ -29,6 +29,7 @@ import org.apache.poi.xssf.model.CommentsTable;
 import org.apache.poi.xssf.model.StylesTable;
 import org.apache.poi.xssf.usermodel.helpers.ColumnHelper;
 import org.apache.poi.xssf.XSSFTestDataSamples;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCol;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
 import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment;
@@ -126,7 +127,7 @@ public class TestXSSFSheet extends TestCase {
         assertEquals((float) 18, sheet.getDefaultRowHeightInPoints());
         // Test that defaultRowHeight is a truncated short: E.G. 360inPoints -> 18; 361inPoints -> 18
         sheet.setDefaultRowHeight((short) 361);
-        assertEquals((float) 18, sheet.getDefaultRowHeightInPoints());
+        assertEquals((float)361/20, sheet.getDefaultRowHeightInPoints());
         // Set a new default row height in points and test getting the value in twips
         sheet.setDefaultRowHeightInPoints((short) 17);
         assertEquals((short) 340, sheet.getDefaultRowHeight());
@@ -398,13 +399,13 @@ public class TestXSSFSheet extends TestCase {
 
     public void testGetSetColumnWidth() {
         XSSFWorkbook workbook = new XSSFWorkbook();
-        Sheet sheet = workbook.createSheet("Sheet 1");
-        sheet.setColumnWidth((short) 1,(short)  22);
-        assertEquals(22, sheet.getColumnWidth((short) 1));
+        XSSFSheet sheet = workbook.createSheet("Sheet 1");
+        sheet.setColumnWidth(1,  22*256);
+        assertEquals(22*256, sheet.getColumnWidth(1));
 
         // Now check the low level stuff, and check that's all
         //  been set correctly
-        XSSFSheet xs = (XSSFSheet)sheet;
+        XSSFSheet xs = sheet;
         CTWorksheet cts = xs.getWorksheet();
 
         CTCols[] cols_s = cts.getColsArray();
@@ -420,7 +421,7 @@ public class TestXSSFSheet extends TestCase {
 
 
         // Now set another
-        sheet.setColumnWidth((short) 3,(short)  33);
+        sheet.setColumnWidth(3, 33*256);
 
         cols_s = cts.getColsArray();
         assertEquals(1, cols_s.length);
@@ -534,7 +535,7 @@ public class TestXSSFSheet extends TestCase {
     
     public void testTopRowLeftCol() {
         XSSFWorkbook workbook = new XSSFWorkbook();
-        XSSFSheet sheet = (XSSFSheet) workbook.createSheet("Sheet 1");
+        XSSFSheet sheet = workbook.createSheet("Sheet 1");
         sheet.showInPane((short)1, (short)1);
         assertEquals((short) 1, sheet.getTopRow());
         assertEquals((short) 1, sheet.getLeftCol());
@@ -546,7 +547,7 @@ public class TestXSSFSheet extends TestCase {
     public void testShiftRows() {
         XSSFWorkbook workbook = new XSSFWorkbook();
         
-        XSSFSheet sheet = (XSSFSheet) createSheet(workbook, "Sheet 1");
+        XSSFSheet sheet = createSheet(workbook, "Sheet 1");
        sheet.shiftRows(1, 2, 4, true, false);
        assertEquals((short) 1, sheet.getRow(5).getHeight());
        assertEquals((short) 2, sheet.getRow(6).getHeight());
@@ -554,7 +555,7 @@ public class TestXSSFSheet extends TestCase {
        assertNull(sheet.getRow(2));
        assertEquals(8, sheet.getPhysicalNumberOfRows());
 
-        XSSFSheet sheet2 = (XSSFSheet) createSheet(workbook, "Sheet 2");
+        XSSFSheet sheet2 = createSheet(workbook, "Sheet 2");
        sheet2.shiftRows(1, 5, 3, true, false);
        assertEquals((short) 1, sheet2.getRow(4).getHeight());
        assertEquals((short) 2, sheet2.getRow(5).getHeight());
@@ -566,7 +567,7 @@ public class TestXSSFSheet extends TestCase {
        assertNull(sheet2.getRow(3));
        assertEquals(7, sheet2.getPhysicalNumberOfRows());
 
-        XSSFSheet sheet3 = (XSSFSheet) createSheet(workbook, "Sheet 3");
+        XSSFSheet sheet3 = createSheet(workbook, "Sheet 3");
        sheet3.shiftRows(5, 7, -3, true, false);
        assertEquals(5, sheet3.getRow(2).getHeight());
        assertEquals(6, sheet3.getRow(3).getHeight());
@@ -576,7 +577,7 @@ public class TestXSSFSheet extends TestCase {
        assertNull(sheet3.getRow(7));
        assertEquals(7, sheet3.getPhysicalNumberOfRows());
 
-        XSSFSheet sheet4 = (XSSFSheet) createSheet(workbook, "Sheet 4");
+        XSSFSheet sheet4 = createSheet(workbook, "Sheet 4");
        sheet4.shiftRows(5, 7, -2, true, false);
        assertEquals(5, sheet4.getRow(3).getHeight());
        assertEquals(6, sheet4.getRow(4).getHeight());
@@ -586,17 +587,17 @@ public class TestXSSFSheet extends TestCase {
        assertEquals(8, sheet4.getPhysicalNumberOfRows());
 
        // Test without copying rowHeight
-        XSSFSheet sheet5 = (XSSFSheet) createSheet(workbook, "Sheet 5");
+        XSSFSheet sheet5 = createSheet(workbook, "Sheet 5");
        sheet5.shiftRows(5, 7, -2, false, false);
-       assertEquals(-1, sheet5.getRow(3).getHeight());
-       assertEquals(-1, sheet5.getRow(4).getHeight());
-       assertEquals(-1, sheet5.getRow(5).getHeight());
+       assertEquals(sheet5.getDefaultRowHeight(), sheet5.getRow(3).getHeight());
+       assertEquals(sheet5.getDefaultRowHeight(), sheet5.getRow(4).getHeight());
+       assertEquals(sheet5.getDefaultRowHeight(), sheet5.getRow(5).getHeight());
        assertNull(sheet5.getRow(6));
        assertNull(sheet5.getRow(7));
        assertEquals(8, sheet5.getPhysicalNumberOfRows());
 
        // Test without copying rowHeight and resetting to default height
-        XSSFSheet sheet6 = (XSSFSheet) createSheet(workbook, "Sheet 6");
+        XSSFSheet sheet6 = createSheet(workbook, "Sheet 6");
         sheet6.setDefaultRowHeight((short) 200);
        sheet6.shiftRows(5, 7, -2, false, true);
        assertEquals(200, sheet6.getRow(3).getHeight());
@@ -738,7 +739,7 @@ public class TestXSSFSheet extends TestCase {
     
 
        private XSSFSheet createSheet(XSSFWorkbook workbook, String name) {
-        XSSFSheet sheet = (XSSFSheet) workbook.createSheet(name);
+        XSSFSheet sheet = workbook.createSheet(name);
        Row row0 = sheet.createRow(0);
        row0.setHeight((short) 1);
        Row row1 = sheet.createRow(1);
@@ -875,4 +876,29 @@ public class TestXSSFSheet extends TestCase {
         assertFalse(sheet.getRowSumsRight());
     }
 
+
+    public void testColumnWidthCompatibility() {
+        Workbook wb1 = new HSSFWorkbook();
+        Workbook wb2 = new XSSFWorkbook();
+
+        Sheet sh1 = wb1.createSheet();
+        Sheet sh2 = wb2.createSheet();
+
+        assertEquals(sh1.getDefaultColumnWidth(), sh2.getDefaultColumnWidth());
+
+        //if column width is not set, HSSF returns a wrong value which does not take into account
+        //margins and borders, it is always less than the actual column width
+        assertEquals(2048, sh1.getColumnWidth(0));
+        assertEquals(2340, sh2.getColumnWidth(0));
+
+        sh1.setDefaultColumnWidth(1000);
+        sh2.setDefaultColumnWidth(1000);
+        assertEquals(1000, sh2.getDefaultColumnWidth());
+        assertEquals(sh1.getDefaultColumnWidth(), sh2.getDefaultColumnWidth());
+
+        sh1.setColumnWidth(0, 500);
+        sh2.setColumnWidth(0, 500);
+        assertEquals(500, sh2.getColumnWidth(0));
+        assertEquals(sh1.getColumnWidth(0), sh2.getColumnWidth(0));
+    }
 }
index ce1de14e18513139ccaede5580696262170b4fce..49e47c937d9db321c1b80e988b65a1988e76c99e 100644 (file)
@@ -154,16 +154,13 @@ public final class TestXSSFWorkbook extends TestCase {
        /**
         * Tests that we can save a new document
         */
-       public void testSaveNew() throws IOException {
+       public void testSaveNew() {
                XSSFWorkbook workbook = new XSSFWorkbook();
                workbook.createSheet("sheet1");
                workbook.createSheet("sheet2");
                workbook.createSheet("sheet3");
-               File file = File.createTempFile("poi-", ".xlsx");
-               System.out.println("Saving newly created file to " + file.getAbsolutePath());
-               OutputStream out = new FileOutputStream(file);
-               workbook.write(out);
-               out.close();
+
+        XSSFTestDataSamples.writeOutAndReadBack(workbook);
        }
 
        /**
@@ -258,7 +255,6 @@ public final class TestXSSFWorkbook extends TestCase {
                font.setUnderline(Font.U_DOUBLE);
                StylesTable styleSource=new StylesTable();
                long index=styleSource.putFont(font);
-               System.out.println("index="+index);
                workbook.setStylesSource(styleSource);
                fontFind=workbook.findFont(Font.BOLDWEIGHT_BOLD, IndexedColors.BLACK.getIndex(), (short)15, "Calibri", false, false, Font.SS_NONE, Font.U_DOUBLE);
                assertNull(fontFind);
index 34db8b57c4be10d6aec43d2a7dfc365aab82fde8..62f465cc547ee847c70956ebb0cb8daa307137b4 100644 (file)
@@ -186,9 +186,6 @@ public final class TestColumnHelper extends TestCase {
         col9.setMax(27);
         helper.addCleanColIntoCols(cols1, col9);
 
-        if (false) {
-            System.err.println(cols1);
-        }
         // TODO - assert something interesting
         CTCol[] colArray = cols1.getColArray();
         assertEquals(12, colArray.length);