--- /dev/null
+/* ====================================================================\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
*/
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
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)
\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
* 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
* 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
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 {
* @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.
*
* @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
--- /dev/null
+/* ====================================================================\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
--- /dev/null
+/* ====================================================================\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
\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
return cell1.getCol();\r
}\r
\r
- public void setCol1(short col1) {\r
+ public void setCol1(int col1) {\r
cell1.setCol(col1);\r
}\r
\r
return cell2.getCol();\r
}\r
\r
- public void setCol2(short col2) {\r
+ public void setCol2(int col2) {\r
cell2.setCol(col2);\r
}\r
\r
return cell1;\r
}\r
\r
+ protected void setFrom(CTMarker from){\r
+ cell1 = from;\r
+ }\r
+\r
/**\r
* Return ending anchor point\r
*\r
public CTMarker getTo(){\r
return cell2;\r
}\r
+\r
+ protected void setTo(CTMarker to){\r
+ cell2 = to;\r
+ }\r
}\r
--- /dev/null
+/* ====================================================================\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
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
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
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
*/\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
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
*\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
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
* 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
* 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
* @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
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
\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
* {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
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
return null;\r
}\r
\r
+ protected CTShapeProperties getShapeProperties(){\r
+ return ctPicture.getSpPr();\r
+ }\r
+\r
}\r
font.setFontName("#" + fontIndex);
fontIdRuns = new ArrayList<CTRPrElt>();
} else {
- font = (XSSFFont)styles.getFontAt(fontIndex);
+ font = styles.getFontAt(fontIndex);
}
applyFont(startIndex, endIndex, font);
}
font.setFontName("#" + fontIndex);
fontIdRuns = new ArrayList<CTRPrElt>();
} else {
- font = (XSSFFont)styles.getFontAt(fontIndex);
+ font = styles.getFontAt(fontIndex);
}
applyFont(font);
}
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);
}
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;
-public class XSSFRow implements Row {
+public class XSSFRow implements Row, Comparable {
private CTRow 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) {
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();
+ }
}
/**
}
}
+ /**
+ * 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) {
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
--- /dev/null
+/* ====================================================================\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
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;
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();
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() {
* 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
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();
}
}
- 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);
}
}
+ /**
+ * 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);
}
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);
}
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);
}
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());
==================================================================== */\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
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
--- /dev/null
+/* ====================================================================\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
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;
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;
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);
//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
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 ********************
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());
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
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());
}
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
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;
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 {
private static XSSFSheet createParentObjects() {
XSSFWorkbook wb = new XSSFWorkbook();
- wb.setSharedStringSource(new SharedStringsTable());
- return new XSSFSheet(wb);
+ return wb.createSheet();
}
/**
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());
+
+
+ }
}
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;
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());
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();
// Now set another
- sheet.setColumnWidth((short) 3,(short) 33);
+ sheet.setColumnWidth(3, 33*256);
cols_s = cts.getColsArray();
assertEquals(1, cols_s.length);
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());
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());
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());
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());
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());
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());
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);
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));
+ }
}
/**
* 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);
}
/**
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);
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);