git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@705638 13f79535-47bb-0310-9956-ffa450edef68tags/ooxml_20081107
@@ -0,0 +1,60 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.xssf.usermodel.examples; | |||
import org.apache.poi.xssf.usermodel.*; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.io.FileInputStream; | |||
import java.io.FileOutputStream; | |||
/** | |||
* Demonstrates how to insert pictures in a SpreadsheetML document | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public class WorkingWithPictures { | |||
public static void main(String[] args) throws IOException { | |||
//create a new workbook | |||
XSSFWorkbook wb = new XSSFWorkbook(); | |||
//add a picture in this workbook. | |||
InputStream is = new FileInputStream("lilies.jpg"); | |||
int pictureIdx = wb.addPicture(is, XSSFWorkbook.PICTURE_TYPE_JPEG); | |||
is.close(); | |||
//create sheet | |||
XSSFSheet sheet = wb.createSheet(); | |||
//create drawing | |||
XSSFDrawing drawing = sheet.createDrawingPatriarch(); | |||
//add a picture shape | |||
XSSFPicture pict = drawing.createPicture(new XSSFClientAnchor(), pictureIdx); | |||
//auto-size picture | |||
pict.resize(); | |||
//save workbook | |||
FileOutputStream fileOut = new FileOutputStream("xssf-picture.xlsx"); | |||
wb.write(fileOut); | |||
fileOut.close(); | |||
} | |||
} |
@@ -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 |
@@ -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) |
@@ -110,7 +110,7 @@ public class POIXMLDocumentPart { | |||
/** | |||
* Save the content in the underlying package part. | |||
* Default implemenation is empty meaning that the package part is left unmodified. | |||
* Default implementation is empty meaning that the package part is left unmodified. | |||
* | |||
* Sub-classes should override and add logic to marshal the "model" into Ooxml4J. | |||
* | |||
@@ -122,6 +122,7 @@ public class POIXMLDocumentPart { | |||
* XmlObject bean = getXmlBean(); //the "model" which holds changes in memory | |||
* bean.save(out, DEFAULT_XML_OPTIONS); | |||
* out.close(); | |||
* } | |||
* </code></pre> | |||
* | |||
*/ |
@@ -41,7 +41,7 @@ public abstract class POIXMLFactory { | |||
* Create a new POIXMLDocumentPart using the supplied descriptor. This method is used when adding new parts | |||
* to a document, for example, when adding a sheet to a workbook, slide to a presentation, etc. | |||
* | |||
* @param descriptor described the object to create | |||
* @param descriptor describes the object to create | |||
* @return A new instance of a POIXMLDocumentPart. | |||
*/ | |||
public abstract POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor); |
@@ -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 { |
@@ -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. |
@@ -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 |
@@ -0,0 +1,27 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.xssf.usermodel; | |||
/** | |||
* An anchor is what specifics the position of a shape within a client object | |||
* or within another containing shape. | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public abstract class XSSFAnchor { | |||
} |
@@ -0,0 +1,81 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.xssf.usermodel; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D; | |||
/** | |||
* @author Yegor Kozlov | |||
*/ | |||
public class XSSFChildAnchor extends XSSFAnchor { | |||
private CTTransform2D t2d; | |||
public XSSFChildAnchor(int x, int y, int cx, int cy) { | |||
t2d = CTTransform2D.Factory.newInstance(); | |||
CTPoint2D off = t2d.addNewOff(); | |||
CTPositiveSize2D ext = t2d.addNewExt(); | |||
off.setX(x); | |||
off.setY(y); | |||
ext.setCx(Math.abs(cx - x)); | |||
ext.setCy(Math.abs(cy - y)); | |||
if(x > cx) t2d.setFlipH(true); | |||
if(y > cy) t2d.setFlipV(true); | |||
} | |||
public XSSFChildAnchor(CTTransform2D t2d) { | |||
this.t2d = t2d; | |||
} | |||
public CTTransform2D getCTTransform2D() { | |||
return t2d; | |||
} | |||
public int getDx1() { | |||
return (int)t2d.getOff().getX(); | |||
} | |||
public void setDx1(int dx1) { | |||
t2d.getOff().setX(dx1); | |||
} | |||
public int getDy1() { | |||
return (int)t2d.getOff().getY(); | |||
} | |||
public void setDy1(int dy1) { | |||
t2d.getOff().setY(dy1); | |||
} | |||
public int getDy2() { | |||
return (int)(getDy1() + t2d.getExt().getCy()); | |||
} | |||
public void setDy2(int dy2) { | |||
t2d.getExt().setCy(dy2 - getDy1()); | |||
} | |||
public int getDx2() { | |||
return (int)(getDx1() + t2d.getExt().getCx()); | |||
} | |||
public void setDx2(int dx2) { | |||
t2d.getExt().setCx(dx2 - getDx1()); | |||
} | |||
} |
@@ -20,11 +20,11 @@ import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; | |||
/** | |||
* A client anchor is attached to an excel worksheet. It anchors against | |||
* top-left and buttom-right cells. | |||
* top-left and bottom-right cells. | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public class XSSFClientAnchor { | |||
public class XSSFClientAnchor extends XSSFAnchor { | |||
/** | |||
* Starting anchor point | |||
@@ -92,7 +92,7 @@ public class XSSFClientAnchor { | |||
return cell1.getCol(); | |||
} | |||
public void setCol1(short col1) { | |||
public void setCol1(int col1) { | |||
cell1.setCol(col1); | |||
} | |||
@@ -100,7 +100,7 @@ public class XSSFClientAnchor { | |||
return cell2.getCol(); | |||
} | |||
public void setCol2(short col2) { | |||
public void setCol2(int col2) { | |||
cell2.setCol(col2); | |||
} | |||
@@ -176,6 +176,10 @@ public class XSSFClientAnchor { | |||
return cell1; | |||
} | |||
protected void setFrom(CTMarker from){ | |||
cell1 = from; | |||
} | |||
/** | |||
* Return ending anchor point | |||
* | |||
@@ -184,4 +188,8 @@ public class XSSFClientAnchor { | |||
public CTMarker getTo(){ | |||
return cell2; | |||
} | |||
protected void setTo(CTMarker to){ | |||
cell2 = to; | |||
} | |||
} |
@@ -0,0 +1,121 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.xssf.usermodel; | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.*; | |||
/** | |||
* A connection shape drawing element. A connection shape is a line, etc. | |||
* that connects two other shapes in this drawing. | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public class XSSFConnector extends XSSFShape { | |||
private static CTConnector prototype = null; | |||
private CTConnector ctShape; | |||
/** | |||
* Construct a new XSSFConnector object. | |||
* | |||
* @param drawing the XSSFDrawing that owns this shape | |||
* @param ctShape the shape bean that holds all the shape properties | |||
*/ | |||
protected XSSFConnector(XSSFDrawing drawing, CTConnector ctShape) { | |||
this.drawing = drawing; | |||
this.ctShape = ctShape; | |||
} | |||
/** | |||
* Initialize default structure of a new auto-shape | |||
* | |||
*/ | |||
protected static CTConnector prototype() { | |||
if(prototype == null) { | |||
CTConnector shape = CTConnector.Factory.newInstance(); | |||
CTConnectorNonVisual nv = shape.addNewNvCxnSpPr(); | |||
CTNonVisualDrawingProps nvp = nv.addNewCNvPr(); | |||
nvp.setId(1); | |||
nvp.setName("Shape 1"); | |||
nv.addNewCNvCxnSpPr(); | |||
CTShapeProperties sp = shape.addNewSpPr(); | |||
CTTransform2D t2d = sp.addNewXfrm(); | |||
CTPositiveSize2D p1 = t2d.addNewExt(); | |||
p1.setCx(0); | |||
p1.setCy(0); | |||
CTPoint2D p2 = t2d.addNewOff(); | |||
p2.setX(0); | |||
p2.setY(0); | |||
CTPresetGeometry2D geom = sp.addNewPrstGeom(); | |||
geom.setPrst(STShapeType.LINE); | |||
geom.addNewAvLst(); | |||
CTShapeStyle style = shape.addNewStyle(); | |||
CTSchemeColor scheme = style.addNewLnRef().addNewSchemeClr(); | |||
scheme.setVal(STSchemeColorVal.ACCENT_1); | |||
style.getLnRef().setIdx(1); | |||
CTStyleMatrixReference fillref = style.addNewFillRef(); | |||
fillref.setIdx(0); | |||
fillref.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1); | |||
CTStyleMatrixReference effectRef = style.addNewEffectRef(); | |||
effectRef.setIdx(0); | |||
effectRef.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1); | |||
CTFontReference fontRef = style.addNewFontRef(); | |||
fontRef.setIdx(STFontCollectionIndex.MINOR); | |||
fontRef.addNewSchemeClr().setVal(STSchemeColorVal.TX_1); | |||
prototype = shape; | |||
} | |||
return prototype; | |||
} | |||
public CTConnector getCTConnector(){ | |||
return ctShape; | |||
} | |||
/** | |||
* Gets the shape type, one of the constants defined in {@link org.apache.poi.xssf.usermodel.ShapeTypes}. | |||
* | |||
* @return the shape type | |||
* @see org.apache.poi.xssf.usermodel.ShapeTypes | |||
*/ | |||
public int getShapeType() { | |||
return ctShape.getSpPr().getPrstGeom().getPrst().intValue(); | |||
} | |||
/** | |||
* Sets the shape types. | |||
* | |||
* @param type the shape type, one of the constants defined in {@link org.apache.poi.xssf.usermodel.ShapeTypes}. | |||
* @see org.apache.poi.xssf.usermodel.ShapeTypes | |||
*/ | |||
public void setShapeType(int type) { | |||
ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type)); | |||
} | |||
protected CTShapeProperties getShapeProperties(){ | |||
return ctShape.getSpPr(); | |||
} | |||
} |
@@ -19,10 +19,9 @@ package org.apache.poi.xssf.usermodel; | |||
import org.apache.poi.POIXMLDocumentPart; | |||
import org.apache.xmlbeans.XmlException; | |||
import org.apache.xmlbeans.XmlOptions; | |||
import org.apache.xmlbeans.XmlObject; | |||
import org.openxml4j.opc.*; | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTDrawing; | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor; | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.STEditAs; | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*; | |||
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; | |||
import javax.xml.namespace.QName; | |||
@@ -30,6 +29,8 @@ import java.io.IOException; | |||
import java.io.OutputStream; | |||
import java.util.Map; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.LinkedList; | |||
/** | |||
* Represents a SpreadsheetML drawing | |||
@@ -105,6 +106,23 @@ public class XSSFDrawing extends POIXMLDocumentPart { | |||
out.close(); | |||
} | |||
/** | |||
* Constructs a textbox under the drawing. | |||
* | |||
* @param anchor the client anchor describes how this group is attached | |||
* to the sheet. | |||
* @return the newly created textbox. | |||
*/ | |||
public XSSFTextBox createTextbox(XSSFClientAnchor anchor){ | |||
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor); | |||
CTShape ctShape = ctAnchor.addNewSp(); | |||
ctShape.set(XSSFSimpleShape.prototype()); | |||
XSSFTextBox shape = new XSSFTextBox(this, ctShape); | |||
shape.anchor = anchor; | |||
return shape; | |||
} | |||
/** | |||
* Creates a picture. | |||
* | |||
@@ -116,13 +134,32 @@ public class XSSFDrawing extends POIXMLDocumentPart { | |||
*/ | |||
public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex) | |||
{ | |||
PackageRelationship rel = addPictureReference(pictureIndex); | |||
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor); | |||
ctAnchor.setEditAs(STEditAs.ONE_CELL); | |||
CTPicture ctShape = ctAnchor.addNewPic(); | |||
ctShape.set(XSSFPicture.prototype()); | |||
XSSFPicture shape = new XSSFPicture(this, ctShape); | |||
shape.anchor = anchor; | |||
shape.setPictureReference(rel); | |||
return shape; | |||
} | |||
/** | |||
* Add the indexed picture to this drawing relations | |||
* | |||
* @param pictureIndex the index of the picture in the workbook collection of pictures, | |||
* {@link org.apache.poi.xssf.usermodel.XSSFWorkbook#getAllPictures()} . | |||
*/ | |||
protected PackageRelationship addPictureReference(int pictureIndex){ | |||
XSSFWorkbook wb = (XSSFWorkbook)getParent().getParent(); | |||
XSSFPictureData data = wb.getAllPictures().get(pictureIndex); | |||
PackagePartName ppName = data.getPackagePart().getPartName(); | |||
PackageRelationship rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, XSSFRelation.IMAGES.getRelation()); | |||
addRelation(new XSSFPictureData(data.getPackagePart(), rel)); | |||
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor); | |||
return new XSSFPicture(this, rel, ctAnchor); | |||
return rel; | |||
} | |||
/** | |||
@@ -136,7 +173,49 @@ public class XSSFDrawing extends POIXMLDocumentPart { | |||
public XSSFSimpleShape createSimpleShape(XSSFClientAnchor anchor) | |||
{ | |||
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor); | |||
return new XSSFSimpleShape(this, ctAnchor); | |||
CTShape ctShape = ctAnchor.addNewSp(); | |||
ctShape.set(XSSFSimpleShape.prototype()); | |||
XSSFSimpleShape shape = new XSSFSimpleShape(this, ctShape); | |||
shape.anchor = anchor; | |||
return shape; | |||
} | |||
/** | |||
* Creates a simple shape. This includes such shapes as lines, rectangles, | |||
* and ovals. | |||
* | |||
* @param anchor the client anchor describes how this group is attached | |||
* to the sheet. | |||
* @return the newly created shape. | |||
*/ | |||
public XSSFConnector createConnector(XSSFClientAnchor anchor) | |||
{ | |||
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor); | |||
CTConnector ctShape = ctAnchor.addNewCxnSp(); | |||
ctShape.set(XSSFConnector.prototype()); | |||
XSSFConnector shape = new XSSFConnector(this, ctShape); | |||
shape.anchor = anchor; | |||
return shape; | |||
} | |||
/** | |||
* Creates a simple shape. This includes such shapes as lines, rectangles, | |||
* and ovals. | |||
* | |||
* @param anchor the client anchor describes how this group is attached | |||
* to the sheet. | |||
* @return the newly created shape. | |||
*/ | |||
public XSSFShapeGroup createGroup(XSSFClientAnchor anchor) | |||
{ | |||
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor); | |||
CTGroupShape ctGroup = ctAnchor.addNewGrpSp(); | |||
ctGroup.set(XSSFShapeGroup.prototype()); | |||
XSSFShapeGroup shape = new XSSFShapeGroup(this, ctGroup); | |||
shape.anchor = anchor; | |||
return shape; | |||
} | |||
/** | |||
@@ -144,12 +223,13 @@ public class XSSFDrawing extends POIXMLDocumentPart { | |||
* | |||
* @return a new CTTwoCellAnchor | |||
*/ | |||
private CTTwoCellAnchor createTwoCellAnchor(XSSFClientAnchor anchor){ | |||
private CTTwoCellAnchor createTwoCellAnchor(XSSFClientAnchor anchor) { | |||
CTTwoCellAnchor ctAnchor = drawing.addNewTwoCellAnchor(); | |||
ctAnchor.setEditAs(STEditAs.ONE_CELL); | |||
ctAnchor.setFrom(anchor.getFrom()); | |||
ctAnchor.setTo(anchor.getTo()); | |||
ctAnchor.addNewClientData(); | |||
anchor.setTo(ctAnchor.getTo()); | |||
anchor.setFrom(ctAnchor.getFrom()); | |||
return ctAnchor; | |||
} | |||
} |
@@ -43,18 +43,15 @@ public class XSSFPicture extends XSSFShape { | |||
private static final POILogger logger = POILogFactory.getLogger(XSSFPicture.class); | |||
/** | |||
* width of 1px in columns with default width | |||
* A default instance of CTShape used for creating new shapes. | |||
*/ | |||
private static final float PX_DEFAULT = 0.125f; | |||
/** | |||
* width of 1px in columns with overridden width | |||
*/ | |||
private static final float PX_MODIFIED = 0.143f; | |||
private static CTPicture prototype = null; | |||
/** | |||
* Height of 1px of a row | |||
* Width of one character in pixels. Same for Calibry and Arial. | |||
*/ | |||
private static final int PX_ROW = 15; | |||
private static final float CHARACTER_WIDTH = 7.0017f; | |||
/** | |||
* This object specifies a picture object and all its properties | |||
@@ -65,56 +62,60 @@ public class XSSFPicture extends XSSFShape { | |||
* Construct a new XSSFPicture object. This constructor is called from | |||
* {@link XSSFDrawing#createPicture(XSSFClientAnchor, int)} | |||
* | |||
* @param parent the XSSFDrawing that owns this picture | |||
* @param rel the relationship to the picture data | |||
* @param anchor the two cell anchor placeholder for this picture, | |||
* this object encloses the CTPicture bean that holds all the picture properties | |||
* @param drawing the XSSFDrawing that owns this picture | |||
*/ | |||
protected XSSFPicture(XSSFDrawing drawing, CTPicture ctPicture){ | |||
this.drawing = drawing; | |||
this.ctPicture = ctPicture; | |||
} | |||
/** | |||
* Returns a prototype that is used to construct new shapes | |||
* | |||
* @return a prototype that is used to construct new shapes | |||
*/ | |||
protected XSSFPicture(XSSFDrawing parent, PackageRelationship rel, CTTwoCellAnchor anchor){ | |||
super(parent, anchor); | |||
//Create a new picture and attach it to the specified two-cell anchor | |||
ctPicture = newPicture(rel); | |||
anchor.setPic(ctPicture); | |||
protected static CTPicture prototype(){ | |||
if(prototype == null) { | |||
CTPicture pic = CTPicture.Factory.newInstance(); | |||
CTPictureNonVisual nvpr = pic.addNewNvPicPr(); | |||
CTNonVisualDrawingProps nvProps = nvpr.addNewCNvPr(); | |||
nvProps.setId(1); | |||
nvProps.setName("Picture 1"); | |||
nvProps.setDescr("Picture"); | |||
CTNonVisualPictureProperties nvPicProps = nvpr.addNewCNvPicPr(); | |||
nvPicProps.addNewPicLocks().setNoChangeAspect(true); | |||
CTBlipFillProperties blip = pic.addNewBlipFill(); | |||
blip.addNewBlip().setEmbed(""); | |||
blip.addNewStretch().addNewFillRect(); | |||
CTShapeProperties sppr = pic.addNewSpPr(); | |||
CTTransform2D t2d = sppr.addNewXfrm(); | |||
CTPositiveSize2D ext = t2d.addNewExt(); | |||
//should be original picture width and height expressed in EMUs | |||
ext.setCx(0); | |||
ext.setCy(0); | |||
CTPoint2D off = t2d.addNewOff(); | |||
off.setX(0); | |||
off.setY(0); | |||
CTPresetGeometry2D prstGeom = sppr.addNewPrstGeom(); | |||
prstGeom.setPrst(STShapeType.RECT); | |||
prstGeom.addNewAvLst(); | |||
prototype = pic; | |||
} | |||
return prototype; | |||
} | |||
/** | |||
* Create a new CTPicture bean and initialize its required attributes | |||
* Link this shape with the picture data | |||
* | |||
* @param rel the relationship to the picture data | |||
* @return a new CTPicture bean | |||
* @param rel relationship referring the picture data | |||
*/ | |||
private static CTPicture newPicture(PackageRelationship rel){ | |||
CTPicture pic = CTPicture.Factory.newInstance(); | |||
CTPictureNonVisual nvpr = pic.addNewNvPicPr(); | |||
CTNonVisualDrawingProps nvProps = nvpr.addNewCNvPr(); | |||
//YK: TODO shape IDs must be unique across workbook | |||
int shapeId = 1; | |||
nvProps.setId(shapeId); | |||
nvProps.setName("Picture " + shapeId); | |||
nvProps.setDescr(rel.getTargetURI().toString()); | |||
CTNonVisualPictureProperties nvPicProps = nvpr.addNewCNvPicPr(); | |||
nvPicProps.addNewPicLocks().setNoChangeAspect(true); | |||
CTBlipFillProperties blip = pic.addNewBlipFill(); | |||
blip.addNewBlip().setEmbed(rel.getId()); | |||
blip.addNewStretch().addNewFillRect(); | |||
CTShapeProperties sppr = pic.addNewSpPr(); | |||
CTTransform2D t2d = sppr.addNewXfrm(); | |||
CTPositiveSize2D ext = t2d.addNewExt(); | |||
//should be original picture width and height expressed in EMUs | |||
ext.setCx(0); | |||
ext.setCy(0); | |||
CTPoint2D off = t2d.addNewOff(); | |||
off.setX(0); | |||
off.setY(0); | |||
CTPresetGeometry2D prstGeom = sppr.addNewPrstGeom(); | |||
prstGeom.setPrst(STShapeType.RECT); | |||
prstGeom.addNewAvLst(); | |||
return pic; | |||
protected void setPictureReference(PackageRelationship rel){ | |||
ctPicture.getBlipFill().getBlip().setEmbed(rel.getId()); | |||
} | |||
/** | |||
@@ -130,7 +131,7 @@ public class XSSFPicture extends XSSFShape { | |||
* Reset the image to the original size. | |||
*/ | |||
public void resize(){ | |||
XSSFClientAnchor anchor = getAnchor(); | |||
XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor(); | |||
XSSFClientAnchor pref = getPreferredSize(); | |||
@@ -152,78 +153,76 @@ public class XSSFPicture extends XSSFShape { | |||
* @return XSSFClientAnchor with the preferred size for this image | |||
*/ | |||
public XSSFClientAnchor getPreferredSize(){ | |||
XSSFClientAnchor anchor = getAnchor(); | |||
XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor(); | |||
XSSFPictureData data = getPictureData(); | |||
Dimension size = getImageDimension(data.getPackagePart(), data.getPictureType()); | |||
float w = 0; | |||
//space in the leftmost cell | |||
w += anchor.getDx1()/EMU_PER_POINT; | |||
short col2 = (short)(anchor.getCol1() + 1); | |||
int col2 = anchor.getCol1(); | |||
int dx2 = 0; | |||
if(anchor.getDx1() > 0){ | |||
w += getColumnWidthInPixels(col2) - anchor.getDx1(); | |||
col2++; | |||
} | |||
while(w < size.width){ | |||
w += getColumnWidthInPixels(col2++); | |||
for (;;) { | |||
w += getColumnWidthInPixels(col2); | |||
if(w > size.width) break; | |||
col2++; | |||
} | |||
if(w > size.width) { | |||
//calculate dx2, offset in the rightmost cell | |||
col2--; | |||
float cw = getColumnWidthInPixels(col2); | |||
float cw = getColumnWidthInPixels(col2 + 1); | |||
float delta = w - size.width; | |||
dx2 = (int)(EMU_PER_POINT*(cw-delta)); | |||
dx2 = (int)(EMU_PER_PIXEL*(cw-delta)); | |||
} | |||
anchor.setCol2(col2); | |||
anchor.setDx2(dx2); | |||
float h = 0; | |||
h += (1 - anchor.getDy1()/256)* getRowHeightInPixels(anchor.getRow1()); | |||
int row2 = anchor.getRow1() + 1; | |||
int row2 = anchor.getRow1(); | |||
int dy2 = 0; | |||
while(h < size.height){ | |||
h += getRowHeightInPixels(row2++); | |||
if(anchor.getDy1() > 0){ | |||
h += getRowHeightInPixels(row2) - anchor.getDy1(); | |||
row2++; | |||
} | |||
for (;;) { | |||
h += getRowHeightInPixels(row2); | |||
if(h > size.height) break; | |||
row2++; | |||
} | |||
if(h > size.height) { | |||
row2--; | |||
float ch = getRowHeightInPixels(row2); | |||
float ch = getRowHeightInPixels(row2 + 1); | |||
float delta = h - size.height; | |||
dy2 = (int)((ch-delta)/ch*256); | |||
dy2 = (int)(EMU_PER_PIXEL*(ch-delta)); | |||
} | |||
anchor.setRow2(row2); | |||
anchor.setDy2(dy2); | |||
return anchor; | |||
} | |||
private float getColumnWidthInPixels(int column){ | |||
XSSFSheet sheet = (XSSFSheet)getDrawing().getParent(); | |||
int cw = sheet.getColumnWidth(column); | |||
float px = getPixelWidth(column); | |||
CTPositiveSize2D size2d = ctPicture.getSpPr().getXfrm().getExt(); | |||
size2d.setCx(size.width*EMU_PER_PIXEL); | |||
size2d.setCy(size.height*EMU_PER_PIXEL); | |||
return cw/px; | |||
return anchor; | |||
} | |||
private float getRowHeightInPixels(int i){ | |||
private float getColumnWidthInPixels(int columnIndex){ | |||
XSSFSheet sheet = (XSSFSheet)getDrawing().getParent(); | |||
float numChars = (float)sheet.getColumnWidth(columnIndex)/256; | |||
XSSFRow row = sheet.getRow(i); | |||
float height; | |||
if(row != null) height = row.getHeight(); | |||
else height = sheet.getDefaultRowHeight(); | |||
return height/PX_ROW; | |||
return numChars*CHARACTER_WIDTH; | |||
} | |||
private float getPixelWidth(int column){ | |||
private float getRowHeightInPixels(int rowIndex){ | |||
XSSFSheet sheet = (XSSFSheet)getDrawing().getParent(); | |||
int def = sheet.getDefaultColumnWidth(); | |||
int cw = sheet.getColumnWidth(column); | |||
return cw == def ? PX_DEFAULT : PX_MODIFIED; | |||
XSSFRow row = sheet.getRow(rowIndex); | |||
float height = row != null ? row.getHeightInPoints() : sheet.getDefaultRowHeightInPoints(); | |||
return height*PIXEL_DPI/POINT_DPI; | |||
} | |||
/** | |||
@@ -238,7 +237,7 @@ public class XSSFPicture extends XSSFShape { | |||
Dimension size = new Dimension(); | |||
switch (type){ | |||
//we can calculate the preferred size only for JPEG and PNG | |||
//we can calculate the preferred size only for JPEG, PNG and BMP | |||
//other formats like WMF, EMF and PICT are not supported in Java | |||
case Workbook.PICTURE_TYPE_JPEG: | |||
case Workbook.PICTURE_TYPE_PNG: | |||
@@ -255,11 +254,11 @@ public class XSSFPicture extends XSSFShape { | |||
//if DPI is zero then assume standard 96 DPI | |||
//since cannot divide by zero | |||
if (dpi[0] == 0) dpi[0] = 96; | |||
if (dpi[1] == 0) dpi[1] = 96; | |||
if (dpi[0] == 0) dpi[0] = PIXEL_DPI; | |||
if (dpi[1] == 0) dpi[1] = PIXEL_DPI; | |||
size.width = img.getWidth()*96/dpi[0]; | |||
size.height = img.getHeight()*96/dpi[1]; | |||
size.width = img.getWidth()*PIXEL_DPI/dpi[0]; | |||
size.height = img.getHeight()*PIXEL_DPI/dpi[1]; | |||
} catch (IOException e){ | |||
//silently return if ImageIO failed to read the image | |||
@@ -282,7 +281,7 @@ public class XSSFPicture extends XSSFShape { | |||
* {96, 96} is the default. | |||
*/ | |||
protected static int[] getResolution(ImageReader r) throws IOException { | |||
int hdpi=96, vdpi=96; | |||
int hdpi = PIXEL_DPI, vdpi = PIXEL_DPI; | |||
double mm2inch = 25.4; | |||
NodeList lst; | |||
@@ -296,16 +295,6 @@ public class XSSFPicture extends XSSFShape { | |||
return new int[]{hdpi, vdpi}; | |||
} | |||
/** | |||
* return the anchor that is used by this shape. | |||
* | |||
* @return the anchor that is used by this shape. | |||
*/ | |||
public XSSFClientAnchor getAnchor(){ | |||
CTTwoCellAnchor ctAnchor = (CTTwoCellAnchor)getShapeContainer(); | |||
return new XSSFClientAnchor(ctAnchor.getFrom(), ctAnchor.getTo()); | |||
} | |||
/** | |||
* Return picture data for this shape | |||
* | |||
@@ -322,4 +311,8 @@ public class XSSFPicture extends XSSFShape { | |||
return null; | |||
} | |||
protected CTShapeProperties getShapeProperties(){ | |||
return ctPicture.getSpPr(); | |||
} | |||
} |
@@ -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); | |||
} |
@@ -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) { |
@@ -21,73 +21,135 @@ import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAn | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTAbsoluteAnchor; | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTOneCellAnchor; | |||
import org.openxmlformats.schemas.drawingml.x2006.chartDrawing.CTGroupShape; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.*; | |||
/** | |||
* Represents a shape in a SpreadsheetML drawing. | |||
* | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public abstract class XSSFShape { | |||
public static final int EMU_PER_PIXEL = 9525; | |||
public static final int EMU_PER_POINT = 12700; | |||
public static final int POINT_DPI = 72; | |||
public static final int PIXEL_DPI = 96; | |||
/** | |||
* Shape container. Can be CTTwoCellAnchor, CTOneCellAnchor, CTAbsoluteAnchor or CTGroupShape | |||
* Parent drawing | |||
*/ | |||
private XmlObject spContainer; | |||
protected XSSFDrawing drawing; | |||
/** | |||
* Parent drawing | |||
* The parent shape, always not-null for shapes in groups | |||
*/ | |||
private XSSFDrawing drawing; | |||
protected XSSFShapeGroup parent; | |||
/** | |||
* The parent shape, always not-null for shapes in groups | |||
* anchor that is used by this shape | |||
*/ | |||
protected XSSFAnchor anchor; | |||
/** | |||
* Return the drawing that owns this shape | |||
* | |||
* @return the parent drawing that owns this shape | |||
*/ | |||
public XSSFDrawing getDrawing(){ | |||
return drawing; | |||
} | |||
/** | |||
* Gets the parent shape. | |||
*/ | |||
public XSSFShapeGroup getParent() | |||
{ | |||
return parent; | |||
} | |||
/** | |||
* @return the anchor that is used by this shape. | |||
*/ | |||
private XSSFShape parent; | |||
public XSSFAnchor getAnchor() | |||
{ | |||
return anchor; | |||
} | |||
/** | |||
* Returns xml bean with shape properties. | |||
* | |||
* @return xml bean with shape properties. | |||
*/ | |||
protected abstract CTShapeProperties getShapeProperties(); | |||
/** | |||
* Construct a new XSSFSimpleShape object. | |||
* Whether this shape is not filled with a color | |||
* | |||
* @param parent the XSSFDrawing that owns this shape | |||
* @param anchor an object that encloses the shape bean, | |||
* can be CTTwoCellAnchor, CTOneCellAnchor, CTAbsoluteAnchor or CTGroupShape | |||
* @return true if this shape is not filled with a color. | |||
*/ | |||
protected XSSFShape(XSSFDrawing parent, XmlObject anchor){ | |||
drawing = parent; | |||
if(!(anchor instanceof CTTwoCellAnchor) && !(anchor instanceof CTOneCellAnchor) && | |||
!(anchor instanceof CTAbsoluteAnchor) && !(anchor instanceof CTGroupShape)) { | |||
throw new IllegalArgumentException("anchor must be one of the following types: " + | |||
"CTTwoCellAnchor, CTOneCellAnchor, CTAbsoluteAnchor or CTGroupShape"); | |||
} | |||
spContainer = anchor; | |||
public boolean isNoFill() { | |||
return getShapeProperties().isSetNoFill(); | |||
} | |||
/** | |||
* Return the anchor bean that encloses this shape. | |||
* Can be CTTwoCellAnchor, CTOneCellAnchor, CTAbsoluteAnchor or CTGroupShape. | |||
* Sets whether this shape is filled or transparent. | |||
* | |||
* @return the anchor bean that encloses this shape | |||
* @param noFill if true then no fill will be applied to the shape element. | |||
*/ | |||
public XmlObject getShapeContainer(){ | |||
return spContainer; | |||
public void setNoFill(boolean noFill) { | |||
CTShapeProperties props = getShapeProperties(); | |||
//unset solid and pattern fills if they are set | |||
if (props.isSetPattFill()) props.unsetPattFill(); | |||
if (props.isSetSolidFill()) props.unsetSolidFill(); | |||
props.setNoFill(CTNoFillProperties.Factory.newInstance()); | |||
} | |||
/** | |||
* Return the drawing that owns this shape | |||
* Sets the color used to fill this shape using the solid fill pattern. | |||
*/ | |||
public void setFillColor(int red, int green, int blue) { | |||
CTShapeProperties props = getShapeProperties(); | |||
CTSolidColorFillProperties fill = props.isSetSolidFill() ? props.getSolidFill() : props.addNewSolidFill(); | |||
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance(); | |||
rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue}); | |||
fill.setSrgbClr(rgb); | |||
} | |||
/** | |||
* The color applied to the lines of this shape. | |||
*/ | |||
public void setLineStyleColor( int red, int green, int blue ) { | |||
CTShapeProperties props = getShapeProperties(); | |||
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn(); | |||
CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln.getSolidFill() : ln.addNewSolidFill(); | |||
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance(); | |||
rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue}); | |||
fill.setSrgbClr(rgb); | |||
} | |||
/** | |||
* Specifies the width to be used for the underline stroke. | |||
* | |||
* @return the parent drawing that owns this shape | |||
* @param lineWidth width in points | |||
*/ | |||
public XSSFDrawing getDrawing(){ | |||
return drawing; | |||
public void setLineWidth( double lineWidth ) { | |||
CTShapeProperties props = getShapeProperties(); | |||
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn(); | |||
ln.setW((int)(lineWidth*EMU_PER_POINT)); | |||
} | |||
/** | |||
* Gets the parent shape. | |||
* Sets the line style. | |||
* | |||
* @param lineStyle | |||
*/ | |||
public XSSFShape getParent() | |||
{ | |||
return parent; | |||
public void setLineStyle( int lineStyle ) { | |||
CTShapeProperties props = getShapeProperties(); | |||
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn(); | |||
CTPresetLineDashProperties dashStyle = CTPresetLineDashProperties.Factory.newInstance(); | |||
dashStyle.setVal(STPresetLineDashVal.Enum.forInt(lineStyle+1)); | |||
ln.setPrstDash(dashStyle); | |||
} | |||
} |
@@ -0,0 +1,189 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.xssf.usermodel; | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.*; | |||
import org.openxml4j.opc.PackagePartName; | |||
import org.openxml4j.opc.PackageRelationship; | |||
import org.openxml4j.opc.TargetMode; | |||
import java.util.List; | |||
/** | |||
* This object specifies a group shape that represents many shapes grouped together. This shape is to be treated | |||
* just as if it were a regular shape but instead of being described by a single geometry it is made up of all the | |||
* shape geometries encompassed within it. Within a group shape each of the shapes that make up the group are | |||
* specified just as they normally would. | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public class XSSFShapeGroup extends XSSFShape { | |||
private static CTGroupShape prototype = null; | |||
private CTGroupShape ctGroup; | |||
/** | |||
* Construct a new XSSFSimpleShape object. | |||
* | |||
* @param drawing the XSSFDrawing that owns this shape | |||
* @param ctGroup the XML bean that stores this group content | |||
*/ | |||
public XSSFShapeGroup(XSSFDrawing drawing, CTGroupShape ctGroup) { | |||
this.drawing = drawing; | |||
this.ctGroup = ctGroup; | |||
} | |||
/** | |||
* Initialize default structure of a new shape group | |||
*/ | |||
protected static CTGroupShape prototype() { | |||
if (prototype == null) { | |||
CTGroupShape shape = CTGroupShape.Factory.newInstance(); | |||
CTGroupShapeNonVisual nv = shape.addNewNvGrpSpPr(); | |||
CTNonVisualDrawingProps nvpr = nv.addNewCNvPr(); | |||
nvpr.setId(0); | |||
nvpr.setName("Group 0"); | |||
nv.addNewCNvGrpSpPr(); | |||
CTGroupShapeProperties sp = shape.addNewGrpSpPr(); | |||
CTGroupTransform2D t2d = sp.addNewXfrm(); | |||
CTPositiveSize2D p1 = t2d.addNewExt(); | |||
p1.setCx(0); | |||
p1.setCy(0); | |||
CTPoint2D p2 = t2d.addNewOff(); | |||
p2.setX(0); | |||
p2.setY(0); | |||
CTPositiveSize2D p3 = t2d.addNewChExt(); | |||
p3.setCx(0); | |||
p3.setCy(0); | |||
CTPoint2D p4 = t2d.addNewChOff(); | |||
p4.setX(0); | |||
p4.setY(0); | |||
prototype = shape; | |||
} | |||
return prototype; | |||
} | |||
/** | |||
* Constructs a textbox. | |||
* | |||
* @param anchor the child anchor describes how this shape is attached | |||
* to the group. | |||
* @return the newly created textbox. | |||
*/ | |||
public XSSFTextBox createTextbox(XSSFChildAnchor anchor){ | |||
CTShape ctShape = ctGroup.addNewSp(); | |||
ctShape.set(XSSFSimpleShape.prototype()); | |||
XSSFTextBox shape = new XSSFTextBox(getDrawing(), ctShape); | |||
shape.parent = this; | |||
shape.anchor = anchor; | |||
shape.getCTShape().getSpPr().setXfrm(anchor.getCTTransform2D()); | |||
return shape; | |||
} | |||
/** | |||
* Creates a simple shape. This includes such shapes as lines, rectangles, | |||
* and ovals. | |||
* | |||
* @param anchor the child anchor describes how this shape is attached | |||
* to the group. | |||
* @return the newly created shape. | |||
*/ | |||
public XSSFSimpleShape createSimpleShape(XSSFChildAnchor anchor) { | |||
CTShape ctShape = ctGroup.addNewSp(); | |||
ctShape.set(XSSFSimpleShape.prototype()); | |||
XSSFSimpleShape shape = new XSSFSimpleShape(getDrawing(), ctShape); | |||
shape.parent = this; | |||
shape.anchor = anchor; | |||
shape.getCTShape().getSpPr().setXfrm(anchor.getCTTransform2D()); | |||
return shape; | |||
} | |||
/** | |||
* Creates a simple shape. This includes such shapes as lines, rectangles, | |||
* and ovals. | |||
* | |||
* @param anchor the child anchor describes how this shape is attached | |||
* to the group. | |||
* @return the newly created shape. | |||
*/ | |||
public XSSFConnector createConnector(XSSFChildAnchor anchor) { | |||
CTConnector ctShape = ctGroup.addNewCxnSp(); | |||
ctShape.set(XSSFConnector.prototype()); | |||
XSSFConnector shape = new XSSFConnector(getDrawing(), ctShape); | |||
shape.parent = this; | |||
shape.anchor = anchor; | |||
shape.getCTConnector().getSpPr().setXfrm(anchor.getCTTransform2D()); | |||
return shape; | |||
} | |||
/** | |||
* Creates a picture. | |||
* | |||
* @param anchor the client anchor describes how this picture is attached to the sheet. | |||
* @param pictureIndex the index of the picture in the workbook collection of pictures, | |||
* {@link XSSFWorkbook#getAllPictures()} . | |||
* @return the newly created picture shape. | |||
*/ | |||
public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex) { | |||
PackageRelationship rel = getDrawing().addPictureReference(pictureIndex); | |||
CTPicture ctShape = ctGroup.addNewPic(); | |||
ctShape.set(XSSFPicture.prototype()); | |||
XSSFPicture shape = new XSSFPicture(getDrawing(), ctShape); | |||
shape.parent = this; | |||
shape.anchor = anchor; | |||
shape.setPictureReference(rel); | |||
return shape; | |||
} | |||
public CTGroupShape getCTGroupShape() { | |||
return ctGroup; | |||
} | |||
/** | |||
* Sets the coordinate space of this group. All children are constrained | |||
* to these coordinates. | |||
*/ | |||
public void setCoordinates(int x1, int y1, int x2, int y2) { | |||
CTGroupTransform2D t2d = ctGroup.getGrpSpPr().getXfrm(); | |||
CTPoint2D off = t2d.getOff(); | |||
off.setX(x1); | |||
off.setY(y1); | |||
CTPositiveSize2D ext = t2d.getExt(); | |||
ext.setCx(x2); | |||
ext.setCy(y2); | |||
CTPoint2D chOff = t2d.getChOff(); | |||
chOff.setX(x1); | |||
chOff.setY(y1); | |||
CTPositiveSize2D chExt = t2d.getChExt(); | |||
chExt.setCx(x2); | |||
chExt.setCy(y2); | |||
} | |||
protected CTShapeProperties getShapeProperties() { | |||
throw new IllegalStateException("Not supported for shape group"); | |||
} | |||
} |
@@ -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()); |
@@ -16,85 +16,96 @@ | |||
==================================================================== */ | |||
package org.apache.poi.xssf.usermodel; | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor; | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape; | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShapeNonVisual; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.*; | |||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*; | |||
/** | |||
* Represents an auto-shape in a SpreadsheetML drawing. | |||
* Represents a shape with a predefined geometry in a SpreadsheetML drawing. | |||
* Possible shape types are defined in {@link ShapeTypes} | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public class XSSFSimpleShape extends XSSFShape { | |||
private CTShape ctShape; | |||
/** | |||
* A default instance of CTShape used for creating new shapes. | |||
*/ | |||
private static CTShape prototype = null; | |||
/** | |||
* Construct a new XSSFSimpleShape object. | |||
* | |||
* @param parent the XSSFDrawing that owns this shape | |||
* @param anchor the two cell anchor placeholder for this shape, | |||
* this object encloses the shape bean that holds all the shape properties | |||
* Xml bean that stores properties of this shape | |||
*/ | |||
protected XSSFSimpleShape(XSSFDrawing parent, CTTwoCellAnchor anchor) { | |||
super(parent, anchor); | |||
ctShape = anchor.addNewSp(); | |||
newShape(ctShape); | |||
private CTShape ctShape; | |||
protected XSSFSimpleShape(XSSFDrawing drawing, CTShape ctShape) { | |||
this.drawing = drawing; | |||
this.ctShape = ctShape; | |||
} | |||
/** | |||
* Initialize default structure of a new auto-shape | |||
* | |||
* @param shape newly created shape to initialize | |||
* Prototype with the default structure of a new auto-shape. | |||
*/ | |||
private static void newShape(CTShape shape) { | |||
CTShapeNonVisual nv = shape.addNewNvSpPr(); | |||
CTNonVisualDrawingProps nvp = nv.addNewCNvPr(); | |||
int shapeId = 1; | |||
nvp.setId(shapeId); | |||
nvp.setName("Shape " + shapeId); | |||
nv.addNewCNvSpPr(); | |||
CTShapeProperties sp = shape.addNewSpPr(); | |||
CTTransform2D t2d = sp.addNewXfrm(); | |||
CTPositiveSize2D p1 = t2d.addNewExt(); | |||
p1.setCx(0); | |||
p1.setCy(0); | |||
CTPoint2D p2 = t2d.addNewOff(); | |||
p2.setX(0); | |||
p2.setY(0); | |||
CTPresetGeometry2D geom = sp.addNewPrstGeom(); | |||
geom.setPrst(STShapeType.RECT); | |||
geom.addNewAvLst(); | |||
CTShapeStyle style = shape.addNewStyle(); | |||
CTSchemeColor scheme = style.addNewLnRef().addNewSchemeClr(); | |||
scheme.setVal(STSchemeColorVal.ACCENT_1); | |||
scheme.addNewShade().setVal(50000); | |||
style.getLnRef().setIdx(2); | |||
CTStyleMatrixReference fillref = style.addNewFillRef(); | |||
fillref.setIdx(1); | |||
fillref.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1); | |||
CTStyleMatrixReference effectRef = style.addNewEffectRef(); | |||
effectRef.setIdx(0); | |||
effectRef.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1); | |||
CTFontReference fontRef = style.addNewFontRef(); | |||
fontRef.setIdx(STFontCollectionIndex.MINOR); | |||
fontRef.addNewSchemeClr().setVal(STSchemeColorVal.LT_1); | |||
CTTextBody body = shape.addNewTxBody(); | |||
CTTextBodyProperties bodypr = body.addNewBodyPr(); | |||
bodypr.setAnchor(STTextAnchoringType.CTR); | |||
bodypr.setRtlCol(false); | |||
CTTextParagraph p = body.addNewP(); | |||
p.addNewPPr().setAlgn(STTextAlignType.CTR); | |||
body.addNewLstStyle(); | |||
protected static CTShape prototype() { | |||
if(prototype == null) { | |||
CTShape shape = CTShape.Factory.newInstance(); | |||
CTShapeNonVisual nv = shape.addNewNvSpPr(); | |||
CTNonVisualDrawingProps nvp = nv.addNewCNvPr(); | |||
nvp.setId(1); | |||
nvp.setName("Shape 1"); | |||
nv.addNewCNvSpPr(); | |||
CTShapeProperties sp = shape.addNewSpPr(); | |||
CTTransform2D t2d = sp.addNewXfrm(); | |||
CTPositiveSize2D p1 = t2d.addNewExt(); | |||
p1.setCx(0); | |||
p1.setCy(0); | |||
CTPoint2D p2 = t2d.addNewOff(); | |||
p2.setX(0); | |||
p2.setY(0); | |||
CTPresetGeometry2D geom = sp.addNewPrstGeom(); | |||
geom.setPrst(STShapeType.RECT); | |||
geom.addNewAvLst(); | |||
CTShapeStyle style = shape.addNewStyle(); | |||
CTSchemeColor scheme = style.addNewLnRef().addNewSchemeClr(); | |||
scheme.setVal(STSchemeColorVal.ACCENT_1); | |||
scheme.addNewShade().setVal(50000); | |||
style.getLnRef().setIdx(2); | |||
CTStyleMatrixReference fillref = style.addNewFillRef(); | |||
fillref.setIdx(1); | |||
fillref.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1); | |||
CTStyleMatrixReference effectRef = style.addNewEffectRef(); | |||
effectRef.setIdx(0); | |||
effectRef.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1); | |||
CTFontReference fontRef = style.addNewFontRef(); | |||
fontRef.setIdx(STFontCollectionIndex.MINOR); | |||
fontRef.addNewSchemeClr().setVal(STSchemeColorVal.LT_1); | |||
CTTextBody body = shape.addNewTxBody(); | |||
CTTextBodyProperties bodypr = body.addNewBodyPr(); | |||
bodypr.setAnchor(STTextAnchoringType.CTR); | |||
bodypr.setRtlCol(false); | |||
CTTextParagraph p = body.addNewP(); | |||
p.addNewPPr().setAlgn(STTextAlignType.CTR); | |||
CTTextCharacterProperties endPr = p.addNewEndParaRPr(); | |||
endPr.setLang("en-US"); | |||
endPr.setSz(1100); | |||
body.addNewLstStyle(); | |||
prototype = shape; | |||
} | |||
return prototype; | |||
} | |||
public CTShape getCTShape(){ | |||
return ctShape; | |||
} | |||
/** | |||
@@ -117,62 +128,52 @@ public class XSSFSimpleShape extends XSSFShape { | |||
ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type)); | |||
} | |||
/** | |||
* Whether this shape is not filled with a color | |||
* | |||
* @return true if this shape is not filled with a color. | |||
*/ | |||
public boolean isNoFill() { | |||
return ctShape.getSpPr().isSetNoFill(); | |||
protected CTShapeProperties getShapeProperties(){ | |||
return ctShape.getSpPr(); | |||
} | |||
/** | |||
* Sets whether this shape is filled or transparent. | |||
* | |||
* @param noFill if true then no fill will be applied to the shape element. | |||
*/ | |||
public void setNoFill(boolean noFill) { | |||
CTShapeProperties props = ctShape.getSpPr(); | |||
//unset solid and pattern fills if they are set | |||
if (props.isSetPattFill()) props.unsetPattFill(); | |||
if (props.isSetSolidFill()) props.unsetSolidFill(); | |||
public void setText(XSSFRichTextString str){ | |||
props.setNoFill(CTNoFillProperties.Factory.newInstance()); | |||
} | |||
XSSFWorkbook wb = (XSSFWorkbook)getDrawing().getParent().getParent(); | |||
str.setStylesTableReference(wb.getStylesSource()); | |||
/** | |||
* Sets the color used to fill this shape using the solid fill pattern. | |||
*/ | |||
public void setFillColor(int red, int green, int blue) { | |||
CTShapeProperties props = ctShape.getSpPr(); | |||
CTSolidColorFillProperties fill = props.isSetSolidFill() ? props.getSolidFill() : props.addNewSolidFill(); | |||
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance(); | |||
rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue}); | |||
fill.setSrgbClr(rgb); | |||
} | |||
CTTextParagraph p = CTTextParagraph.Factory.newInstance(); | |||
if(str.numFormattingRuns() == 0){ | |||
CTRegularTextRun r = p.addNewR(); | |||
CTTextCharacterProperties rPr = r.addNewRPr(); | |||
rPr.setLang("en-US"); | |||
rPr.setSz(1100); | |||
r.setT(str.getString()); | |||
} else { | |||
for (int i = 0; i < str.getCTRst().sizeOfRArray(); i++) { | |||
CTRElt lt = str.getCTRst().getRArray(i); | |||
CTRPrElt ltPr = lt.getRPr(); | |||
CTRegularTextRun r = p.addNewR(); | |||
CTTextCharacterProperties rPr = r.addNewRPr(); | |||
rPr.setLang("en-US"); | |||
applyAttributes(ltPr, rPr); | |||
r.setT(lt.getT()); | |||
} | |||
} | |||
ctShape.getTxBody().setPArray(new CTTextParagraph[]{p}); | |||
/** | |||
* The color applied to the lines of this shape. | |||
*/ | |||
public void setLineStyleColor( int red, int green, int blue ) { | |||
CTShapeProperties props = ctShape.getSpPr(); | |||
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn(); | |||
CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln.getSolidFill() : ln.addNewSolidFill(); | |||
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance(); | |||
rgb.setVal(new byte[]{(byte)red, (byte)green, (byte)blue}); | |||
fill.setSrgbClr(rgb); | |||
} | |||
/** | |||
* Specifies the width to be used for the underline stroke. | |||
* | |||
* @param lineWidth width in points | |||
* CTRPrElt --> CTFont adapter | |||
*/ | |||
public void setLineWidth( double lineWidth ) { | |||
CTShapeProperties props = ctShape.getSpPr(); | |||
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn(); | |||
ln.setW((int)(lineWidth*EMU_PER_POINT)); | |||
} | |||
private static void applyAttributes(CTRPrElt pr, CTTextCharacterProperties rPr){ | |||
if(pr.sizeOfBArray() > 0) rPr.setB(pr.getBArray(0).getVal()); | |||
//if(pr.sizeOfUArray() > 0) rPr.setU(pr.getUArray(0).getVal()); | |||
if(pr.sizeOfIArray() > 0) rPr.setI(pr.getIArray(0).getVal()); | |||
CTTextFont rFont = rPr.addNewLatin(); | |||
rFont.setTypeface(pr.sizeOfRFontArray() > 0 ? pr.getRFontArray(0).getVal() : "Arial"); | |||
} | |||
} |
@@ -0,0 +1,33 @@ | |||
/* ==================================================================== | |||
Licensed to the Apache Software Foundation (ASF) under one or more | |||
contributor license agreements. See the NOTICE file distributed with | |||
this work for additional information regarding copyright ownership. | |||
The ASF licenses this file to You under the Apache License, Version 2.0 | |||
(the "License"); you may not use this file except in compliance with | |||
the License. You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
==================================================================== */ | |||
package org.apache.poi.xssf.usermodel; | |||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*; | |||
import org.openxmlformats.schemas.drawingml.x2006.main.*; | |||
/** | |||
* Represents a text box in a SpreadsheetML drawing. | |||
* | |||
* @author Yegor Kozlov | |||
*/ | |||
public class XSSFTextBox extends XSSFSimpleShape { | |||
protected XSSFTextBox(XSSFDrawing drawing, CTShape ctShape) { | |||
super(drawing, ctShape); | |||
} | |||
} |
@@ -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); |
@@ -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()); | |||
} |
@@ -67,4 +67,13 @@ public class TestXSSFDrawing extends TestCase { | |||
assertEquals(drawingId, sheet.getWorksheet().getDrawing().getId()); | |||
} | |||
public void testMultipleDrawings(){ | |||
XSSFWorkbook wb = new XSSFWorkbook(); | |||
for (int i = 0; i < 3; i++) { | |||
XSSFSheet sheet = wb.createSheet(); | |||
XSSFDrawing drawing = sheet.createDrawingPatriarch(); | |||
} | |||
org.openxml4j.opc.Package pkg = wb.getPackage(); | |||
assertEquals(3, pkg.getPartsByContentType(XSSFRelation.DRAWINGS.getContentType()).size()); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |
@@ -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)); | |||
} | |||
} |
@@ -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); |
@@ -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); |