more progress on SpreadsheetML drawing layer;finished XSSFPicture, auto-sizing is supported; implemented initial support for shape groups. Common HSSF-XSSF drawing interfaces are still TODO.

git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@705638 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yegor Kozlov 2008-10-17 15:14:00 +00:00
parent 9c094be425
commit 59b02716ac
28 changed files with 1261 additions and 389 deletions

View File

@ -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();
}
}

View File

@ -176,11 +176,6 @@ public interface Row extends Iterable<Cell> {
*/ */
Iterator<Cell> iterator(); Iterator<Cell> iterator();
int compareTo(Object obj);
boolean equals(Object obj);
/** /**
* Used to specify the different possible policies * Used to specify the different possible policies
* if for the case of null and blank cells * if for the case of null and blank cells

View File

@ -98,32 +98,6 @@ public interface Sheet extends Iterable<Row> {
int getLastRowNum(); 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. * Get the visibility state for a given column.
* @param columnIndex - the column to get (0-based) * @param columnIndex - the column to get (0-based)

View File

@ -110,7 +110,7 @@ public class POIXMLDocumentPart {
/** /**
* Save the content in the underlying package part. * 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. * 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 * XmlObject bean = getXmlBean(); //the "model" which holds changes in memory
* bean.save(out, DEFAULT_XML_OPTIONS); * bean.save(out, DEFAULT_XML_OPTIONS);
* out.close(); * out.close();
* }
* </code></pre> * </code></pre>
* *
*/ */

View File

@ -41,7 +41,7 @@ public abstract class POIXMLFactory {
* Create a new POIXMLDocumentPart using the supplied descriptor. This method is used when adding new parts * 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. * 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. * @return A new instance of a POIXMLDocumentPart.
*/ */
public abstract POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor); public abstract POIXMLDocumentPart newDocumentPart(POIXMLRelation descriptor);

View File

@ -34,7 +34,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CommentsDocument;
import org.openxml4j.opc.PackagePart; import org.openxml4j.opc.PackagePart;
import org.openxml4j.opc.PackageRelationship; import org.openxml4j.opc.PackageRelationship;
public class CommentsTable extends POIXMLDocumentPart implements CommentsSource, XSSFModel { public class CommentsTable extends POIXMLDocumentPart implements CommentsSource {
private CTComments comments; private CTComments comments;
public CommentsTable(InputStream is) throws IOException { public CommentsTable(InputStream is) throws IOException {

View File

@ -60,7 +60,7 @@ import org.openxml4j.opc.PackageRelationship;
* @author Nick Birch * @author Nick Birch
* @author Yegor Kozlov * @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. * Array of individual string items in the Shared String table.

View File

@ -64,15 +64,15 @@ import org.openxml4j.opc.PackageRelationship;
* *
* @author ugo * @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 Hashtable<Long,String> numberFormats = new Hashtable<Long,String>();
private final List<XSSFFont> fonts = new ArrayList<XSSFFont>(); private final List<XSSFFont> fonts = new ArrayList<XSSFFont>();
private final List<XSSFCellFill> fills = new ArrayList<XSSFCellFill>(); private final List<XSSFCellFill> fills = new ArrayList<XSSFCellFill>();
private final List<XSSFCellBorder> borders = new ArrayList<XSSFCellBorder>(); private final List<XSSFCellBorder> borders = new ArrayList<XSSFCellBorder>();
private final List<CTXf> styleXfs = new LinkedList<CTXf>(); private final List<CTXf> styleXfs = new ArrayList<CTXf>();
private final List<CTXf> xfs = new LinkedList<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 * The first style id available for use as a custom style

View File

@ -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 {
}

View File

@ -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());
}
}

View File

@ -20,11 +20,11 @@ import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
/** /**
* A client anchor is attached to an excel worksheet. It anchors against * 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 * @author Yegor Kozlov
*/ */
public class XSSFClientAnchor { public class XSSFClientAnchor extends XSSFAnchor {
/** /**
* Starting anchor point * Starting anchor point
@ -92,7 +92,7 @@ public class XSSFClientAnchor {
return cell1.getCol(); return cell1.getCol();
} }
public void setCol1(short col1) { public void setCol1(int col1) {
cell1.setCol(col1); cell1.setCol(col1);
} }
@ -100,7 +100,7 @@ public class XSSFClientAnchor {
return cell2.getCol(); return cell2.getCol();
} }
public void setCol2(short col2) { public void setCol2(int col2) {
cell2.setCol(col2); cell2.setCol(col2);
} }
@ -176,6 +176,10 @@ public class XSSFClientAnchor {
return cell1; return cell1;
} }
protected void setFrom(CTMarker from){
cell1 = from;
}
/** /**
* Return ending anchor point * Return ending anchor point
* *
@ -184,4 +188,8 @@ public class XSSFClientAnchor {
public CTMarker getTo(){ public CTMarker getTo(){
return cell2; return cell2;
} }
protected void setTo(CTMarker to){
cell2 = to;
}
} }

View File

@ -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();
}
}

View File

@ -19,10 +19,9 @@ package org.apache.poi.xssf.usermodel;
import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.POIXMLDocumentPart;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions; import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlObject;
import org.openxml4j.opc.*; import org.openxml4j.opc.*;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTDrawing; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.STEditAs;
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
@ -30,6 +29,8 @@ import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Map; import java.util.Map;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.LinkedList;
/** /**
* Represents a SpreadsheetML drawing * Represents a SpreadsheetML drawing
@ -105,6 +106,23 @@ public class XSSFDrawing extends POIXMLDocumentPart {
out.close(); 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. * Creates a picture.
* *
@ -116,13 +134,32 @@ public class XSSFDrawing extends POIXMLDocumentPart {
*/ */
public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex) 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(); XSSFWorkbook wb = (XSSFWorkbook)getParent().getParent();
XSSFPictureData data = wb.getAllPictures().get(pictureIndex); XSSFPictureData data = wb.getAllPictures().get(pictureIndex);
PackagePartName ppName = data.getPackagePart().getPartName(); PackagePartName ppName = data.getPackagePart().getPartName();
PackageRelationship rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, XSSFRelation.IMAGES.getRelation()); PackageRelationship rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, XSSFRelation.IMAGES.getRelation());
addRelation(new XSSFPictureData(data.getPackagePart(), rel)); addRelation(new XSSFPictureData(data.getPackagePart(), rel));
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor); return rel;
return new XSSFPicture(this, rel, ctAnchor);
} }
/** /**
@ -136,7 +173,49 @@ public class XSSFDrawing extends POIXMLDocumentPart {
public XSSFSimpleShape createSimpleShape(XSSFClientAnchor anchor) public XSSFSimpleShape createSimpleShape(XSSFClientAnchor anchor)
{ {
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(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 * @return a new CTTwoCellAnchor
*/ */
private CTTwoCellAnchor createTwoCellAnchor(XSSFClientAnchor anchor){ private CTTwoCellAnchor createTwoCellAnchor(XSSFClientAnchor anchor) {
CTTwoCellAnchor ctAnchor = drawing.addNewTwoCellAnchor(); CTTwoCellAnchor ctAnchor = drawing.addNewTwoCellAnchor();
ctAnchor.setEditAs(STEditAs.ONE_CELL);
ctAnchor.setFrom(anchor.getFrom()); ctAnchor.setFrom(anchor.getFrom());
ctAnchor.setTo(anchor.getTo()); ctAnchor.setTo(anchor.getTo());
ctAnchor.addNewClientData(); ctAnchor.addNewClientData();
anchor.setTo(ctAnchor.getTo());
anchor.setFrom(ctAnchor.getFrom());
return ctAnchor; return ctAnchor;
} }
} }

View File

@ -43,18 +43,15 @@ public class XSSFPicture extends XSSFShape {
private static final POILogger logger = POILogFactory.getLogger(XSSFPicture.class); 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; private static CTPicture prototype = null;
/**
* width of 1px in columns with overridden width
*/
private static final float PX_MODIFIED = 0.143f;
/** /**
* 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 * This object specifies a picture object and all its properties
@ -65,39 +62,31 @@ public class XSSFPicture extends XSSFShape {
* Construct a new XSSFPicture object. This constructor is called from * Construct a new XSSFPicture object. This constructor is called from
* {@link XSSFDrawing#createPicture(XSSFClientAnchor, int)} * {@link XSSFDrawing#createPicture(XSSFClientAnchor, int)}
* *
* @param parent the XSSFDrawing that owns this picture * @param drawing 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
*/ */
protected XSSFPicture(XSSFDrawing parent, PackageRelationship rel, CTTwoCellAnchor anchor){ protected XSSFPicture(XSSFDrawing drawing, CTPicture ctPicture){
super(parent, anchor); this.drawing = drawing;
//Create a new picture and attach it to the specified two-cell anchor this.ctPicture = ctPicture;
ctPicture = newPicture(rel);
anchor.setPic(ctPicture);
} }
/** /**
* Create a new CTPicture bean and initialize its required attributes * Returns a prototype that is used to construct new shapes
* *
* @param rel the relationship to the picture data * @return a prototype that is used to construct new shapes
* @return a new CTPicture bean
*/ */
private static CTPicture newPicture(PackageRelationship rel){ protected static CTPicture prototype(){
if(prototype == null) {
CTPicture pic = CTPicture.Factory.newInstance(); CTPicture pic = CTPicture.Factory.newInstance();
CTPictureNonVisual nvpr = pic.addNewNvPicPr(); CTPictureNonVisual nvpr = pic.addNewNvPicPr();
CTNonVisualDrawingProps nvProps = nvpr.addNewCNvPr(); CTNonVisualDrawingProps nvProps = nvpr.addNewCNvPr();
//YK: TODO shape IDs must be unique across workbook nvProps.setId(1);
int shapeId = 1; nvProps.setName("Picture 1");
nvProps.setId(shapeId); nvProps.setDescr("Picture");
nvProps.setName("Picture " + shapeId);
nvProps.setDescr(rel.getTargetURI().toString());
CTNonVisualPictureProperties nvPicProps = nvpr.addNewCNvPicPr(); CTNonVisualPictureProperties nvPicProps = nvpr.addNewCNvPicPr();
nvPicProps.addNewPicLocks().setNoChangeAspect(true); nvPicProps.addNewPicLocks().setNoChangeAspect(true);
CTBlipFillProperties blip = pic.addNewBlipFill(); CTBlipFillProperties blip = pic.addNewBlipFill();
blip.addNewBlip().setEmbed(rel.getId()); blip.addNewBlip().setEmbed("");
blip.addNewStretch().addNewFillRect(); blip.addNewStretch().addNewFillRect();
CTShapeProperties sppr = pic.addNewSpPr(); CTShapeProperties sppr = pic.addNewSpPr();
@ -114,7 +103,19 @@ public class XSSFPicture extends XSSFShape {
CTPresetGeometry2D prstGeom = sppr.addNewPrstGeom(); CTPresetGeometry2D prstGeom = sppr.addNewPrstGeom();
prstGeom.setPrst(STShapeType.RECT); prstGeom.setPrst(STShapeType.RECT);
prstGeom.addNewAvLst(); prstGeom.addNewAvLst();
return pic;
prototype = pic;
}
return prototype;
}
/**
* Link this shape with the picture data
*
* @param rel relationship referring the picture data
*/
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. * Reset the image to the original size.
*/ */
public void resize(){ public void resize(){
XSSFClientAnchor anchor = getAnchor(); XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor();
XSSFClientAnchor pref = getPreferredSize(); XSSFClientAnchor pref = getPreferredSize();
@ -152,78 +153,76 @@ public class XSSFPicture extends XSSFShape {
* @return XSSFClientAnchor with the preferred size for this image * @return XSSFClientAnchor with the preferred size for this image
*/ */
public XSSFClientAnchor getPreferredSize(){ public XSSFClientAnchor getPreferredSize(){
XSSFClientAnchor anchor = getAnchor(); XSSFClientAnchor anchor = (XSSFClientAnchor)getAnchor();
XSSFPictureData data = getPictureData(); XSSFPictureData data = getPictureData();
Dimension size = getImageDimension(data.getPackagePart(), data.getPictureType()); Dimension size = getImageDimension(data.getPackagePart(), data.getPictureType());
float w = 0; float w = 0;
int col2 = anchor.getCol1();
//space in the leftmost cell
w += anchor.getDx1()/EMU_PER_POINT;
short col2 = (short)(anchor.getCol1() + 1);
int dx2 = 0; int dx2 = 0;
if(anchor.getDx1() > 0){
w += getColumnWidthInPixels(col2) - anchor.getDx1();
col2++;
}
while(w < size.width){ for (;;) {
w += getColumnWidthInPixels(col2++); w += getColumnWidthInPixels(col2);
if(w > size.width) break;
col2++;
} }
if(w > size.width) { if(w > size.width) {
//calculate dx2, offset in the rightmost cell float cw = getColumnWidthInPixels(col2 + 1);
col2--;
float cw = getColumnWidthInPixels(col2);
float delta = w - size.width; float delta = w - size.width;
dx2 = (int)(EMU_PER_POINT*(cw-delta)); dx2 = (int)(EMU_PER_PIXEL*(cw-delta));
} }
anchor.setCol2(col2); anchor.setCol2(col2);
anchor.setDx2(dx2); anchor.setDx2(dx2);
float h = 0; float h = 0;
h += (1 - anchor.getDy1()/256)* getRowHeightInPixels(anchor.getRow1()); int row2 = anchor.getRow1();
int row2 = anchor.getRow1() + 1;
int dy2 = 0; int dy2 = 0;
while(h < size.height){ if(anchor.getDy1() > 0){
h += getRowHeightInPixels(row2++); h += getRowHeightInPixels(row2) - anchor.getDy1();
row2++;
} }
for (;;) {
h += getRowHeightInPixels(row2);
if(h > size.height) break;
row2++;
}
if(h > size.height) { if(h > size.height) {
row2--; float ch = getRowHeightInPixels(row2 + 1);
float ch = getRowHeightInPixels(row2);
float delta = h - size.height; float delta = h - size.height;
dy2 = (int)((ch-delta)/ch*256); dy2 = (int)(EMU_PER_PIXEL*(ch-delta));
} }
anchor.setRow2(row2); anchor.setRow2(row2);
anchor.setDy2(dy2); anchor.setDy2(dy2);
CTPositiveSize2D size2d = ctPicture.getSpPr().getXfrm().getExt();
size2d.setCx(size.width*EMU_PER_PIXEL);
size2d.setCy(size.height*EMU_PER_PIXEL);
return anchor; return anchor;
} }
private float getColumnWidthInPixels(int column){ private float getColumnWidthInPixels(int columnIndex){
XSSFSheet sheet = (XSSFSheet)getDrawing().getParent(); XSSFSheet sheet = (XSSFSheet)getDrawing().getParent();
int cw = sheet.getColumnWidth(column); float numChars = (float)sheet.getColumnWidth(columnIndex)/256;
float px = getPixelWidth(column);
return cw/px; return numChars*CHARACTER_WIDTH;
} }
private float getRowHeightInPixels(int i){ private float getRowHeightInPixels(int rowIndex){
XSSFSheet sheet = (XSSFSheet)getDrawing().getParent(); XSSFSheet sheet = (XSSFSheet)getDrawing().getParent();
XSSFRow row = sheet.getRow(i); XSSFRow row = sheet.getRow(rowIndex);
float height; float height = row != null ? row.getHeightInPoints() : sheet.getDefaultRowHeightInPoints();
if(row != null) height = row.getHeight(); return height*PIXEL_DPI/POINT_DPI;
else height = sheet.getDefaultRowHeight();
return height/PX_ROW;
}
private float getPixelWidth(int column){
XSSFSheet sheet = (XSSFSheet)getDrawing().getParent();
int def = sheet.getDefaultColumnWidth();
int cw = sheet.getColumnWidth(column);
return cw == def ? PX_DEFAULT : PX_MODIFIED;
} }
/** /**
@ -238,7 +237,7 @@ public class XSSFPicture extends XSSFShape {
Dimension size = new Dimension(); Dimension size = new Dimension();
switch (type){ 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 //other formats like WMF, EMF and PICT are not supported in Java
case Workbook.PICTURE_TYPE_JPEG: case Workbook.PICTURE_TYPE_JPEG:
case Workbook.PICTURE_TYPE_PNG: case Workbook.PICTURE_TYPE_PNG:
@ -255,11 +254,11 @@ public class XSSFPicture extends XSSFShape {
//if DPI is zero then assume standard 96 DPI //if DPI is zero then assume standard 96 DPI
//since cannot divide by zero //since cannot divide by zero
if (dpi[0] == 0) dpi[0] = 96; if (dpi[0] == 0) dpi[0] = PIXEL_DPI;
if (dpi[1] == 0) dpi[1] = 96; if (dpi[1] == 0) dpi[1] = PIXEL_DPI;
size.width = img.getWidth()*96/dpi[0]; size.width = img.getWidth()*PIXEL_DPI/dpi[0];
size.height = img.getHeight()*96/dpi[1]; size.height = img.getHeight()*PIXEL_DPI/dpi[1];
} catch (IOException e){ } catch (IOException e){
//silently return if ImageIO failed to read the image //silently return if ImageIO failed to read the image
@ -282,7 +281,7 @@ public class XSSFPicture extends XSSFShape {
* {96, 96} is the default. * {96, 96} is the default.
*/ */
protected static int[] getResolution(ImageReader r) throws IOException { protected static int[] getResolution(ImageReader r) throws IOException {
int hdpi=96, vdpi=96; int hdpi = PIXEL_DPI, vdpi = PIXEL_DPI;
double mm2inch = 25.4; double mm2inch = 25.4;
NodeList lst; NodeList lst;
@ -296,16 +295,6 @@ public class XSSFPicture extends XSSFShape {
return new int[]{hdpi, vdpi}; 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 * Return picture data for this shape
* *
@ -322,4 +311,8 @@ public class XSSFPicture extends XSSFShape {
return null; return null;
} }
protected CTShapeProperties getShapeProperties(){
return ctPicture.getSpPr();
}
} }

View File

@ -108,7 +108,7 @@ public class XSSFRichTextString implements RichTextString {
font.setFontName("#" + fontIndex); font.setFontName("#" + fontIndex);
fontIdRuns = new ArrayList<CTRPrElt>(); fontIdRuns = new ArrayList<CTRPrElt>();
} else { } else {
font = (XSSFFont)styles.getFontAt(fontIndex); font = styles.getFontAt(fontIndex);
} }
applyFont(startIndex, endIndex, font); applyFont(startIndex, endIndex, font);
} }
@ -219,7 +219,7 @@ public class XSSFRichTextString implements RichTextString {
font.setFontName("#" + fontIndex); font.setFontName("#" + fontIndex);
fontIdRuns = new ArrayList<CTRPrElt>(); fontIdRuns = new ArrayList<CTRPrElt>();
} else { } else {
font = (XSSFFont)styles.getFontAt(fontIndex); font = styles.getFontAt(fontIndex);
} }
applyFont(font); applyFont(font);
} }
@ -425,7 +425,7 @@ public class XSSFRichTextString implements RichTextString {
String fontName = pr.getRFontArray(0).getVal(); String fontName = pr.getRFontArray(0).getVal();
if(fontName.startsWith("#")){ if(fontName.startsWith("#")){
int idx = Integer.parseInt(fontName.substring(1)); int idx = Integer.parseInt(fontName.substring(1));
XSSFFont font = (XSSFFont)styles.getFontAt(idx); XSSFFont font = styles.getFontAt(idx);
pr.removeRFont(0); pr.removeRFont(0);
setRunAttributes(font.getCTFont(), pr); setRunAttributes(font.getCTFont(), pr);
} }

View File

@ -28,7 +28,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCell;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;
public class XSSFRow implements Row { public class XSSFRow implements Row, Comparable {
private CTRow row; private CTRow row;
@ -76,9 +76,21 @@ public class XSSFRow implements Row {
} }
public int compareTo(Object obj) { public int compareTo(Object obj) {
// TODO Auto-generated method stub XSSFRow loc = (XSSFRow) obj;
if (this.getRowNum() == loc.getRowNum())
{
return 0; return 0;
} }
if (this.getRowNum() < loc.getRowNum())
{
return -1;
}
if (this.getRowNum() > loc.getRowNum())
{
return 1;
}
return -1;
}
public XSSFCell createCell(int column) { public XSSFCell createCell(int column) {
return createCell(column, Cell.CELL_TYPE_BLANK); return createCell(column, Cell.CELL_TYPE_BLANK);
@ -184,18 +196,29 @@ public class XSSFRow implements Row {
return -1; 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() { public short getHeight() {
if (this.row.getHt() > 0) { return (short)(getHeightInPoints()*20);
return (short) (this.row.getHt());
}
return -1;
} }
/**
* 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() { public float getHeightInPoints() {
if (this.row.getHt() > 0) { if (this.row.isSetHt()) {
return (short) this.row.getHt(); return (float) this.row.getHt();
} else {
return sheet.getDefaultRowHeightInPoints();
} }
return -1;
} }
/** /**
@ -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) { public void setHeight(short height) {
this.row.setHt((double) height); if(height == -1){
this.row.unsetHt();
this.row.unsetCustomHeight();
} else {
this.row.setHt((double)height/20);
this.row.setCustomHeight(true); 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) { public void setHeightInPoints(float height) {
setHeight((short)height); setHeight((short)(height*20));
} }
public void setRowNum(int rowNum) { public void setRowNum(int rowNum) {

View File

@ -21,6 +21,7 @@ import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAn
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTAbsoluteAnchor; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTAbsoluteAnchor;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTOneCellAnchor; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTOneCellAnchor;
import org.openxmlformats.schemas.drawingml.x2006.chartDrawing.CTGroupShape; import org.openxmlformats.schemas.drawingml.x2006.chartDrawing.CTGroupShape;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
/** /**
* Represents a shape in a SpreadsheetML drawing. * Represents a shape in a SpreadsheetML drawing.
@ -28,50 +29,26 @@ import org.openxmlformats.schemas.drawingml.x2006.chartDrawing.CTGroupShape;
* @author Yegor Kozlov * @author Yegor Kozlov
*/ */
public abstract class XSSFShape { public abstract class XSSFShape {
public static final int EMU_PER_PIXEL = 9525;
public static final int EMU_PER_POINT = 12700; 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
*/
private XmlObject spContainer;
/** /**
* Parent drawing * Parent drawing
*/ */
private XSSFDrawing drawing; protected XSSFDrawing drawing;
/** /**
* The parent shape, always not-null for shapes in groups * The parent shape, always not-null for shapes in groups
*/ */
private XSSFShape parent; protected XSSFShapeGroup parent;
/** /**
* Construct a new XSSFSimpleShape object. * anchor that is used by this shape
*
* @param parent the XSSFDrawing that owns this shape
* @param anchor an object that encloses the shape bean,
* can be CTTwoCellAnchor, CTOneCellAnchor, CTAbsoluteAnchor or CTGroupShape
*/ */
protected XSSFShape(XSSFDrawing parent, XmlObject anchor){ protected XSSFAnchor 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;
}
/**
* Return the anchor bean that encloses this shape.
* Can be CTTwoCellAnchor, CTOneCellAnchor, CTAbsoluteAnchor or CTGroupShape.
*
* @return the anchor bean that encloses this shape
*/
public XmlObject getShapeContainer(){
return spContainer;
}
/** /**
* Return the drawing that owns this shape * Return the drawing that owns this shape
@ -85,9 +62,94 @@ public abstract class XSSFShape {
/** /**
* Gets the parent shape. * Gets the parent shape.
*/ */
public XSSFShape getParent() public XSSFShapeGroup getParent()
{ {
return parent; return parent;
} }
/**
* @return the anchor that is used by this shape.
*/
public XSSFAnchor getAnchor()
{
return anchor;
}
/**
* Returns xml bean with shape properties.
*
* @return xml bean with shape properties.
*/
protected abstract CTShapeProperties getShapeProperties();
/**
* Whether this shape is not filled with a color
*
* @return true if this shape is not filled with a color.
*/
public boolean isNoFill() {
return getShapeProperties().isSetNoFill();
}
/**
* 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 = 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());
}
/**
* 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.
*
* @param lineWidth width in points
*/
public void setLineWidth( double lineWidth ) {
CTShapeProperties props = getShapeProperties();
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();
ln.setW((int)(lineWidth*EMU_PER_POINT));
}
/**
* Sets the line style.
*
* @param lineStyle
*/
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);
}
} }

View File

@ -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");
}
}

View File

@ -60,6 +60,15 @@ import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelations
public class XSSFSheet extends POIXMLDocumentPart implements Sheet { public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
private static POILogger logger = POILogFactory.getLogger(XSSFSheet.class); 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 CTSheet sheet;
protected CTWorksheet worksheet; protected CTWorksheet worksheet;
protected CTDialogsheet dialogsheet; protected CTDialogsheet dialogsheet;
@ -260,7 +269,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
CTDrawing ctDrawing = worksheet.getDrawing(); CTDrawing ctDrawing = worksheet.getDrawing();
if(ctDrawing == null) { if(ctDrawing == null) {
//drawingNumber = #drawings.size() + 1 //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); drawing = (XSSFDrawing)createRelationship(XSSFRelation.DRAWINGS, XSSFFactory.getInstance(), drawingNumber);
String relId = drawing.getPackageRelationship().getId(); String relId = drawing.getPackageRelationship().getId();
@ -425,32 +434,62 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
return worksheet.getColBreaks(); 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) { public int getColumnWidth(int columnIndex) {
CTCol col = columnHelper.getColumn(columnIndex, false); CTCol col = columnHelper.getColumn(columnIndex, false);
return col == null ? getDefaultColumnWidth() : (int)col.getWidth(); double width = col == null || !col.isSetWidth() ? DEFAULT_COLUMN_WIDTH : col.getWidth();
} return (int)(width*256);
public short getColumnWidth(short column) {
return (short) getColumnWidth(column & 0xFFFF);
} }
/**
* 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() { public int getDefaultColumnWidth() {
CTSheetFormatPr pr = getSheetTypeSheetFormatPr(); 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() { public short getDefaultRowHeight() {
return (short) (getSheetTypeSheetFormatPr().getDefaultRowHeight() * 20); return (short) (getSheetTypeSheetFormatPr().getDefaultRowHeight() * 20);
} }
protected CTSheetFormatPr getSheetTypeSheetFormatPr() { /**
if (worksheet.getSheetFormatPr() == null) { * Get the default row height for the sheet measued in point size (if the rows do not define their own height).
worksheet.setSheetFormatPr(CTSheetFormatPr.Factory.newInstance()); *
} * @return default row height in points
return worksheet.getSheetFormatPr(); */
public float getDefaultRowHeightInPoints() {
return (float)getSheetTypeSheetFormatPr().getDefaultRowHeight();
} }
public float getDefaultRowHeightInPoints() { protected CTSheetFormatPr getSheetTypeSheetFormatPr() {
return (short) getSheetTypeSheetFormatPr().getDefaultRowHeight(); return worksheet.isSetSheetFormatPr() ?
worksheet.getSheetFormatPr() :
worksheet.addNewSheetFormatPr();
} }
public boolean getDialog() { public boolean getDialog() {
@ -589,8 +628,7 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
* when set, used on even pages. * when set, used on even pages.
*/ */
public Header getEvenHeader() { public Header getEvenHeader() {
return new XSSFEvenHeader(getSheetTypeHeaderFooter() return new XSSFEvenHeader(getSheetTypeHeaderFooter());
);
} }
/** /**
* Returns the first page header. Not there by * Returns the first page header. Not there by
@ -931,21 +969,39 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
return false; 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) { public boolean isColumnHidden(int columnIndex) {
return columnHelper.getColumn(columnIndex, false).getHidden(); 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() { public boolean isDisplayFormulas() {
return getSheetTypeSheetView().getShowFormulas(); 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() { public boolean isDisplayGridlines() {
return getSheetTypeSheetView().getShowGridLines(); 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() { public boolean isDisplayRowColHeadings() {
return getSheetTypeSheetView().getShowRowColHeaders(); return getSheetTypeSheetView().getShowRowColHeaders();
} }
@ -1098,36 +1154,57 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
} }
/**
* 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) { public void setColumnHidden(int columnIndex, boolean hidden) {
columnHelper.setColHidden(columnIndex, 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) { public void setColumnWidth(int columnIndex, int width) {
columnHelper.setColWidth(columnIndex, width); columnHelper.setColWidth(columnIndex, (double)width/256);
}
public void setColumnWidth(short column, short width) {
setColumnWidth(column & 0xFFFF, width & 0xFFFF);
} }
public void setDefaultColumnStyle(short column, CellStyle style) { public void setDefaultColumnStyle(short column, CellStyle style) {
columnHelper.setColDefaultStyle(column, 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) { public void setDefaultColumnWidth(int width) {
getSheetTypeSheetFormatPr().setDefaultColWidth(width); getSheetTypeSheetFormatPr().setBaseColWidth(width);
}
public void setDefaultColumnWidth(short width) {
setDefaultColumnWidth(width & 0xFFFF);
} }
/**
* 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) { 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) { public void setDefaultRowHeightInPoints(float height) {
getSheetTypeSheetFormatPr().setDefaultRowHeight(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) { public void setDisplayFormulas(boolean show) {
getSheetTypeSheetView().setShowFormulas(show); getSheetTypeSheetView().setShowFormulas(show);
} }
@ -1153,14 +1235,29 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
return getDefaultSheetView(); 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) { public void setDisplayGridlines(boolean show) {
getSheetTypeSheetView().setShowGridLines(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) { public void setDisplayRowColHeadings(boolean show) {
getSheetTypeSheetView().setShowRowColHeaders(show); getSheetTypeSheetView().setShowRowColHeaders(show);
} }
/**
* 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) { public void setFitToPage(boolean b) {
getSheetTypePageSetUpPr().setFitToPage(b); getSheetTypePageSetUpPr().setFitToPage(b);
} }
@ -1169,6 +1266,11 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
setPrintGridlines(value); setPrintGridlines(value);
} }
/**
* Center on page horizontally when printing.
*
* @param value whether to center on page horizontally when printing.
*/
public void setHorizontallyCenter(boolean value) { public void setHorizontallyCenter(boolean value) {
getSheetTypePrintOptions().setHorizontalCentered(value); getSheetTypePrintOptions().setHorizontalCentered(value);
} }
@ -1306,15 +1408,45 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
getSheetTypeSheetView().setZoomScaleSheetLayoutView(scale); 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) { public void shiftRows(int startRow, int endRow, int n) {
shiftRows(startRow, endRow, n, false, false); 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) { public void shiftRows(int startRow, int endRow, int n, boolean copyRowHeight, boolean resetOriginalRowHeight) {
for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) { for (Iterator<Row> it = rowIterator() ; it.hasNext() ; ) {
Row row = it.next(); Row row = it.next();
if (!copyRowHeight) { if (!copyRowHeight) {
row.setHeight((short)0); row.setHeight((short)-1);
} }
if (resetOriginalRowHeight && getDefaultRowHeight() >= 0) { if (resetOriginalRowHeight && getDefaultRowHeight() >= 0) {
row.setHeight(getDefaultRowHeight()); row.setHeight(getDefaultRowHeight());

View File

@ -16,44 +16,44 @@
==================================================================== */ ==================================================================== */
package org.apache.poi.xssf.usermodel; 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.CTShape;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShapeNonVisual; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShapeNonVisual;
import org.openxmlformats.schemas.drawingml.x2006.main.*; 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 * @author Yegor Kozlov
*/ */
public class XSSFSimpleShape extends XSSFShape { 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. * Xml bean that stores properties of this shape
*
* @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
*/ */
protected XSSFSimpleShape(XSSFDrawing parent, CTTwoCellAnchor anchor) { private CTShape ctShape;
super(parent, anchor);
ctShape = anchor.addNewSp(); protected XSSFSimpleShape(XSSFDrawing drawing, CTShape ctShape) {
newShape(ctShape); this.drawing = drawing;
this.ctShape = ctShape;
} }
/** /**
* Initialize default structure of a new auto-shape * Prototype with the default structure of a new auto-shape.
*
* @param shape newly created shape to initialize
*/ */
private static void newShape(CTShape shape) { protected static CTShape prototype() {
if(prototype == null) {
CTShape shape = CTShape.Factory.newInstance();
CTShapeNonVisual nv = shape.addNewNvSpPr(); CTShapeNonVisual nv = shape.addNewNvSpPr();
CTNonVisualDrawingProps nvp = nv.addNewCNvPr(); CTNonVisualDrawingProps nvp = nv.addNewCNvPr();
int shapeId = 1; nvp.setId(1);
nvp.setId(shapeId); nvp.setName("Shape 1");
nvp.setName("Shape " + shapeId);
nv.addNewCNvSpPr(); nv.addNewCNvSpPr();
CTShapeProperties sp = shape.addNewSpPr(); CTShapeProperties sp = shape.addNewSpPr();
@ -93,8 +93,19 @@ public class XSSFSimpleShape extends XSSFShape {
bodypr.setRtlCol(false); bodypr.setRtlCol(false);
CTTextParagraph p = body.addNewP(); CTTextParagraph p = body.addNewP();
p.addNewPPr().setAlgn(STTextAlignType.CTR); p.addNewPPr().setAlgn(STTextAlignType.CTR);
CTTextCharacterProperties endPr = p.addNewEndParaRPr();
endPr.setLang("en-US");
endPr.setSz(1100);
body.addNewLstStyle(); 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)); ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type));
} }
protected CTShapeProperties getShapeProperties(){
return ctShape.getSpPr();
}
public void setText(XSSFRichTextString str){
XSSFWorkbook wb = (XSSFWorkbook)getDrawing().getParent().getParent();
str.setStylesTableReference(wb.getStylesSource());
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});
}
/** /**
* Whether this shape is not filled with a color
* *
* @return true if this shape is not filled with a color. * CTRPrElt --> CTFont adapter
*/ */
public boolean isNoFill() { private static void applyAttributes(CTRPrElt pr, CTTextCharacterProperties rPr){
return ctShape.getSpPr().isSetNoFill();
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");
} }
/**
* 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();
props.setNoFill(CTNoFillProperties.Factory.newInstance());
}
/**
* 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);
}
/**
* 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
*/
public void setLineWidth( double lineWidth ) {
CTShapeProperties props = ctShape.getSpPr();
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();
ln.setW((int)(lineWidth*EMU_PER_POINT));
}
} }

View File

@ -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);
}
}

View File

@ -19,6 +19,7 @@ package org.apache.poi.xssf.usermodel;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.InputStream;
import java.util.*; import java.util.*;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import org.apache.poi.POIXMLDocument; 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.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.poi.util.PackageHelper; import org.apache.poi.util.PackageHelper;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.model.*; import org.apache.poi.xssf.model.*;
import org.apache.poi.POIXMLException; import org.apache.poi.POIXMLException;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
@ -279,6 +281,31 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
return imageNumber - 1; 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) { public XSSFSheet cloneSheet(int sheetNum) {
XSSFSheet srcSheet = sheets.get(sheetNum); XSSFSheet srcSheet = sheets.get(sheetNum);
String srcName = getSheetName(sheetNum); String srcName = getSheetName(sheetNum);

View File

@ -400,13 +400,11 @@ public final class TestXSSFCell extends TestCase {
//BLANK //BLANK
assertEquals(hcell.toString(),xcell.toString()); assertEquals(hcell.toString(),xcell.toString());
System.out.println("BLANK==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
//BOOLEAN //BOOLEAN
xcell.setCellValue(true); xcell.setCellValue(true);
xcell.setCellType(Cell.CELL_TYPE_BOOLEAN); xcell.setCellType(Cell.CELL_TYPE_BOOLEAN);
hcell.setCellValue(true); hcell.setCellValue(true);
hcell.setCellType(Cell.CELL_TYPE_BOOLEAN); hcell.setCellType(Cell.CELL_TYPE_BOOLEAN);
System.out.println("BOOLEAN==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
assertEquals(hcell.toString(),xcell.toString()); assertEquals(hcell.toString(),xcell.toString());
//NUMERIC //NUMERIC
@ -415,7 +413,6 @@ public final class TestXSSFCell extends TestCase {
xcell.setCellType(Cell.CELL_TYPE_NUMERIC); xcell.setCellType(Cell.CELL_TYPE_NUMERIC);
hcell.setCellValue(1234); hcell.setCellValue(1234);
hcell.setCellType(Cell.CELL_TYPE_NUMERIC); hcell.setCellType(Cell.CELL_TYPE_NUMERIC);
System.out.println("NUMERIC==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
assertEquals(hcell.toString(),xcell.toString()); assertEquals(hcell.toString(),xcell.toString());
//DATE ******************** //DATE ********************
@ -434,7 +431,6 @@ public final class TestXSSFCell extends TestCase {
hstyle.setDataFormat(hformat.getFormat("YYYY-MM-DD")); hstyle.setDataFormat(hformat.getFormat("YYYY-MM-DD"));
hcell.setCellStyle(hstyle); hcell.setCellStyle(hstyle);
System.out.println("DATE==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
assertEquals(hcell.toString(),xcell.toString()); assertEquals(hcell.toString(),xcell.toString());
@ -443,7 +439,6 @@ public final class TestXSSFCell extends TestCase {
xcell.setCellType(Cell.CELL_TYPE_STRING); xcell.setCellType(Cell.CELL_TYPE_STRING);
hcell.setCellValue(new HSSFRichTextString("text string")); hcell.setCellValue(new HSSFRichTextString("text string"));
hcell.setCellType(Cell.CELL_TYPE_STRING); hcell.setCellType(Cell.CELL_TYPE_STRING);
System.out.println("STRING==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
assertEquals(hcell.toString(),xcell.toString()); assertEquals(hcell.toString(),xcell.toString());
//ERROR //ERROR
@ -453,13 +448,11 @@ public final class TestXSSFCell extends TestCase {
hcell.setCellErrorValue((byte)0); hcell.setCellErrorValue((byte)0);
hcell.setCellType(Cell.CELL_TYPE_ERROR); hcell.setCellType(Cell.CELL_TYPE_ERROR);
System.out.println("ERROR==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
assertEquals(hcell.toString(),xcell.toString()); assertEquals(hcell.toString(),xcell.toString());
//FORMULA //FORMULA
xcell.setCellFormula("A1+B2"); xcell.setCellFormula("A1+B2");
hcell.setCellValue("A1+B2"); hcell.setCellValue("A1+B2");
System.out.println("FORMULA==> xssf="+xcell.toString() + " - hssf="+hcell.toString());
assertEquals(hcell.toString(),xcell.toString()); assertEquals(hcell.toString(),xcell.toString());
} }

View File

@ -67,4 +67,13 @@ public class TestXSSFDrawing extends TestCase {
assertEquals(drawingId, sheet.getWorksheet().getDrawing().getId()); 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());
}
} }

View File

@ -25,6 +25,8 @@ import junit.framework.TestCase;
import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row; 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.model.SharedStringsTable;
import org.apache.poi.xssf.XSSFTestDataSamples; import org.apache.poi.xssf.XSSFTestDataSamples;
import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFSheet;
@ -131,15 +133,15 @@ public final class TestXSSFRow extends TestCase {
XSSFRow row = getSampleRow(); XSSFRow row = getSampleRow();
// I assume that "ht" attribute value is in 'points', please verify that // I assume that "ht" attribute value is in 'points', please verify that
// Test that no rowHeight is set // 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 // Set a rowHeight and test the new value
row.setHeight((short) 240); row.setHeight((short) 240);
assertEquals((short) 240.0, row.getHeight()); 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 // Set a new rowHeight in points and test the new value
row.setHeightInPoints(13); row.setHeightInPoints(13);
assertEquals((float) 13.0, row.getHeightInPoints()); assertEquals((float) 13.0, row.getHeightInPoints());
assertEquals((short) 13.0, row.getHeight()); assertEquals((short)(13.0*20), row.getHeight());
} }
public void testGetSetZeroHeight() throws Exception { public void testGetSetZeroHeight() throws Exception {
@ -225,8 +227,7 @@ public final class TestXSSFRow extends TestCase {
private static XSSFSheet createParentObjects() { private static XSSFSheet createParentObjects() {
XSSFWorkbook wb = new XSSFWorkbook(); XSSFWorkbook wb = new XSSFWorkbook();
wb.setSharedStringSource(new SharedStringsTable()); return wb.createSheet();
return new XSSFSheet(wb);
} }
/** /**
@ -298,4 +299,37 @@ public final class TestXSSFRow extends TestCase {
assertEquals(-1, sheet.getRow(0).getLastCellNum()); assertEquals(-1, sheet.getRow(0).getLastCellNum());
assertEquals(-1, sheet.getRow(0).getFirstCellNum()); 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());
}
} }

View File

@ -29,6 +29,7 @@ import org.apache.poi.xssf.model.CommentsTable;
import org.apache.poi.xssf.model.StylesTable; import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.helpers.ColumnHelper; import org.apache.poi.xssf.usermodel.helpers.ColumnHelper;
import org.apache.poi.xssf.XSSFTestDataSamples; 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.CTCol;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTCols;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment; import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTComment;
@ -126,7 +127,7 @@ public class TestXSSFSheet extends TestCase {
assertEquals((float) 18, sheet.getDefaultRowHeightInPoints()); assertEquals((float) 18, sheet.getDefaultRowHeightInPoints());
// Test that defaultRowHeight is a truncated short: E.G. 360inPoints -> 18; 361inPoints -> 18 // Test that defaultRowHeight is a truncated short: E.G. 360inPoints -> 18; 361inPoints -> 18
sheet.setDefaultRowHeight((short) 361); 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 // Set a new default row height in points and test getting the value in twips
sheet.setDefaultRowHeightInPoints((short) 17); sheet.setDefaultRowHeightInPoints((short) 17);
assertEquals((short) 340, sheet.getDefaultRowHeight()); assertEquals((short) 340, sheet.getDefaultRowHeight());
@ -398,13 +399,13 @@ public class TestXSSFSheet extends TestCase {
public void testGetSetColumnWidth() { public void testGetSetColumnWidth() {
XSSFWorkbook workbook = new XSSFWorkbook(); XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Sheet 1"); XSSFSheet sheet = workbook.createSheet("Sheet 1");
sheet.setColumnWidth((short) 1,(short) 22); sheet.setColumnWidth(1, 22*256);
assertEquals(22, sheet.getColumnWidth((short) 1)); assertEquals(22*256, sheet.getColumnWidth(1));
// Now check the low level stuff, and check that's all // Now check the low level stuff, and check that's all
// been set correctly // been set correctly
XSSFSheet xs = (XSSFSheet)sheet; XSSFSheet xs = sheet;
CTWorksheet cts = xs.getWorksheet(); CTWorksheet cts = xs.getWorksheet();
CTCols[] cols_s = cts.getColsArray(); CTCols[] cols_s = cts.getColsArray();
@ -420,7 +421,7 @@ public class TestXSSFSheet extends TestCase {
// Now set another // Now set another
sheet.setColumnWidth((short) 3,(short) 33); sheet.setColumnWidth(3, 33*256);
cols_s = cts.getColsArray(); cols_s = cts.getColsArray();
assertEquals(1, cols_s.length); assertEquals(1, cols_s.length);
@ -534,7 +535,7 @@ public class TestXSSFSheet extends TestCase {
public void testTopRowLeftCol() { public void testTopRowLeftCol() {
XSSFWorkbook workbook = new XSSFWorkbook(); XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = (XSSFSheet) workbook.createSheet("Sheet 1"); XSSFSheet sheet = workbook.createSheet("Sheet 1");
sheet.showInPane((short)1, (short)1); sheet.showInPane((short)1, (short)1);
assertEquals((short) 1, sheet.getTopRow()); assertEquals((short) 1, sheet.getTopRow());
assertEquals((short) 1, sheet.getLeftCol()); assertEquals((short) 1, sheet.getLeftCol());
@ -546,7 +547,7 @@ public class TestXSSFSheet extends TestCase {
public void testShiftRows() { public void testShiftRows() {
XSSFWorkbook workbook = new XSSFWorkbook(); XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = (XSSFSheet) createSheet(workbook, "Sheet 1"); XSSFSheet sheet = createSheet(workbook, "Sheet 1");
sheet.shiftRows(1, 2, 4, true, false); sheet.shiftRows(1, 2, 4, true, false);
assertEquals((short) 1, sheet.getRow(5).getHeight()); assertEquals((short) 1, sheet.getRow(5).getHeight());
assertEquals((short) 2, sheet.getRow(6).getHeight()); assertEquals((short) 2, sheet.getRow(6).getHeight());
@ -554,7 +555,7 @@ public class TestXSSFSheet extends TestCase {
assertNull(sheet.getRow(2)); assertNull(sheet.getRow(2));
assertEquals(8, sheet.getPhysicalNumberOfRows()); assertEquals(8, sheet.getPhysicalNumberOfRows());
XSSFSheet sheet2 = (XSSFSheet) createSheet(workbook, "Sheet 2"); XSSFSheet sheet2 = createSheet(workbook, "Sheet 2");
sheet2.shiftRows(1, 5, 3, true, false); sheet2.shiftRows(1, 5, 3, true, false);
assertEquals((short) 1, sheet2.getRow(4).getHeight()); assertEquals((short) 1, sheet2.getRow(4).getHeight());
assertEquals((short) 2, sheet2.getRow(5).getHeight()); assertEquals((short) 2, sheet2.getRow(5).getHeight());
@ -566,7 +567,7 @@ public class TestXSSFSheet extends TestCase {
assertNull(sheet2.getRow(3)); assertNull(sheet2.getRow(3));
assertEquals(7, sheet2.getPhysicalNumberOfRows()); assertEquals(7, sheet2.getPhysicalNumberOfRows());
XSSFSheet sheet3 = (XSSFSheet) createSheet(workbook, "Sheet 3"); XSSFSheet sheet3 = createSheet(workbook, "Sheet 3");
sheet3.shiftRows(5, 7, -3, true, false); sheet3.shiftRows(5, 7, -3, true, false);
assertEquals(5, sheet3.getRow(2).getHeight()); assertEquals(5, sheet3.getRow(2).getHeight());
assertEquals(6, sheet3.getRow(3).getHeight()); assertEquals(6, sheet3.getRow(3).getHeight());
@ -576,7 +577,7 @@ public class TestXSSFSheet extends TestCase {
assertNull(sheet3.getRow(7)); assertNull(sheet3.getRow(7));
assertEquals(7, sheet3.getPhysicalNumberOfRows()); assertEquals(7, sheet3.getPhysicalNumberOfRows());
XSSFSheet sheet4 = (XSSFSheet) createSheet(workbook, "Sheet 4"); XSSFSheet sheet4 = createSheet(workbook, "Sheet 4");
sheet4.shiftRows(5, 7, -2, true, false); sheet4.shiftRows(5, 7, -2, true, false);
assertEquals(5, sheet4.getRow(3).getHeight()); assertEquals(5, sheet4.getRow(3).getHeight());
assertEquals(6, sheet4.getRow(4).getHeight()); assertEquals(6, sheet4.getRow(4).getHeight());
@ -586,17 +587,17 @@ public class TestXSSFSheet extends TestCase {
assertEquals(8, sheet4.getPhysicalNumberOfRows()); assertEquals(8, sheet4.getPhysicalNumberOfRows());
// Test without copying rowHeight // Test without copying rowHeight
XSSFSheet sheet5 = (XSSFSheet) createSheet(workbook, "Sheet 5"); XSSFSheet sheet5 = createSheet(workbook, "Sheet 5");
sheet5.shiftRows(5, 7, -2, false, false); sheet5.shiftRows(5, 7, -2, false, false);
assertEquals(-1, sheet5.getRow(3).getHeight()); assertEquals(sheet5.getDefaultRowHeight(), sheet5.getRow(3).getHeight());
assertEquals(-1, sheet5.getRow(4).getHeight()); assertEquals(sheet5.getDefaultRowHeight(), sheet5.getRow(4).getHeight());
assertEquals(-1, sheet5.getRow(5).getHeight()); assertEquals(sheet5.getDefaultRowHeight(), sheet5.getRow(5).getHeight());
assertNull(sheet5.getRow(6)); assertNull(sheet5.getRow(6));
assertNull(sheet5.getRow(7)); assertNull(sheet5.getRow(7));
assertEquals(8, sheet5.getPhysicalNumberOfRows()); assertEquals(8, sheet5.getPhysicalNumberOfRows());
// Test without copying rowHeight and resetting to default height // 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.setDefaultRowHeight((short) 200);
sheet6.shiftRows(5, 7, -2, false, true); sheet6.shiftRows(5, 7, -2, false, true);
assertEquals(200, sheet6.getRow(3).getHeight()); assertEquals(200, sheet6.getRow(3).getHeight());
@ -738,7 +739,7 @@ public class TestXSSFSheet extends TestCase {
private XSSFSheet createSheet(XSSFWorkbook workbook, String name) { private XSSFSheet createSheet(XSSFWorkbook workbook, String name) {
XSSFSheet sheet = (XSSFSheet) workbook.createSheet(name); XSSFSheet sheet = workbook.createSheet(name);
Row row0 = sheet.createRow(0); Row row0 = sheet.createRow(0);
row0.setHeight((short) 1); row0.setHeight((short) 1);
Row row1 = sheet.createRow(1); Row row1 = sheet.createRow(1);
@ -875,4 +876,29 @@ public class TestXSSFSheet extends TestCase {
assertFalse(sheet.getRowSumsRight()); 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));
}
} }

View File

@ -154,16 +154,13 @@ public final class TestXSSFWorkbook extends TestCase {
/** /**
* Tests that we can save a new document * Tests that we can save a new document
*/ */
public void testSaveNew() throws IOException { public void testSaveNew() {
XSSFWorkbook workbook = new XSSFWorkbook(); XSSFWorkbook workbook = new XSSFWorkbook();
workbook.createSheet("sheet1"); workbook.createSheet("sheet1");
workbook.createSheet("sheet2"); workbook.createSheet("sheet2");
workbook.createSheet("sheet3"); workbook.createSheet("sheet3");
File file = File.createTempFile("poi-", ".xlsx");
System.out.println("Saving newly created file to " + file.getAbsolutePath()); XSSFTestDataSamples.writeOutAndReadBack(workbook);
OutputStream out = new FileOutputStream(file);
workbook.write(out);
out.close();
} }
/** /**
@ -258,7 +255,6 @@ public final class TestXSSFWorkbook extends TestCase {
font.setUnderline(Font.U_DOUBLE); font.setUnderline(Font.U_DOUBLE);
StylesTable styleSource=new StylesTable(); StylesTable styleSource=new StylesTable();
long index=styleSource.putFont(font); long index=styleSource.putFont(font);
System.out.println("index="+index);
workbook.setStylesSource(styleSource); workbook.setStylesSource(styleSource);
fontFind=workbook.findFont(Font.BOLDWEIGHT_BOLD, IndexedColors.BLACK.getIndex(), (short)15, "Calibri", false, false, Font.SS_NONE, Font.U_DOUBLE); fontFind=workbook.findFont(Font.BOLDWEIGHT_BOLD, IndexedColors.BLACK.getIndex(), (short)15, "Calibri", false, false, Font.SS_NONE, Font.U_DOUBLE);
assertNull(fontFind); assertNull(fontFind);

View File

@ -186,9 +186,6 @@ public final class TestColumnHelper extends TestCase {
col9.setMax(27); col9.setMax(27);
helper.addCleanColIntoCols(cols1, col9); helper.addCleanColIntoCols(cols1, col9);
if (false) {
System.err.println(cols1);
}
// TODO - assert something interesting // TODO - assert something interesting
CTCol[] colArray = cols1.getColArray(); CTCol[] colArray = cols1.getColArray();
assertEquals(12, colArray.length); assertEquals(12, colArray.length);