#60520 - Provide *SSF functionality via Common SS

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1776818 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2016-12-31 21:47:23 +00:00
parent 6507656c44
commit 155bc83d58
20 changed files with 318 additions and 114 deletions

View File

@ -22,12 +22,13 @@ import org.apache.poi.ddf.EscherChildAnchorRecord;
import org.apache.poi.ddf.EscherClientAnchorRecord;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherRecord;
import org.apache.poi.ss.usermodel.ChildAnchor;
/**
* An anchor is what specifics the position of a shape within a client object
* or within another containing shape.
*/
public abstract class HSSFAnchor {
public abstract class HSSFAnchor implements ChildAnchor {
protected boolean _isHorizontallyFlipped = false;
protected boolean _isVerticallyFlipped = false;
@ -55,46 +56,6 @@ public abstract class HSSFAnchor {
}
}
/**
* @return x coordinate of the left up corner
*/
public abstract int getDx1();
/**
* @param dx1 x coordinate of the left up corner
*/
public abstract void setDx1(int dx1);
/**
* @return y coordinate of the left up corner
*/
public abstract int getDy1();
/**
* @param dy1 y coordinate of the left up corner
*/
public abstract void setDy1(int dy1);
/**
* @return y coordinate of the right down corner
*/
public abstract int getDy2();
/**
* @param dy2 y coordinate of the right down corner
*/
public abstract void setDy2(int dy2);
/**
* @return x coordinate of the right down corner
*/
public abstract int getDx2();
/**
* @param dx2 x coordinate of the right down corner
*/
public abstract void setDx2(int dx2);
/**
* @return whether this shape is horizontally flipped
*/

View File

@ -57,7 +57,7 @@ import org.apache.poi.util.StringUtil;
* The patriarch is the toplevel container for shapes in a sheet. It does
* little other than act as a container for other shapes and groups.
*/
public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
public final class HSSFPatriarch implements HSSFShapeContainer, Drawing<HSSFShape> {
// private static POILogger log = POILogFactory.getLogger(HSSFPatriarch.class);
private final List<HSSFShape> _shapes = new ArrayList<HSSFShape>();
@ -279,7 +279,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
String entryName = "MBD"+HexDump.toHex(storageId);
DirectoryEntry oleRoot;
try {
DirectoryNode dn = _sheet.getWorkbook().getRootDirectory();
DirectoryNode dn = _sheet.getWorkbook().getDirectory();
if (dn == null) throw new FileNotFoundException();
oleRoot = (DirectoryEntry)dn.getEntry(entryName);
} catch (FileNotFoundException e) {
@ -541,7 +541,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
for (int i = 0; i < spgrChildren.size(); i++) {
EscherContainerRecord spContainer = spgrChildren.get(i);
if (i != 0) {
HSSFShapeFactory.createShapeTree(spContainer, _boundAggregate, this, _sheet.getWorkbook().getRootDirectory());
HSSFShapeFactory.createShapeTree(spContainer, _boundAggregate, this, _sheet.getWorkbook().getDirectory());
}
}
}
@ -556,6 +556,7 @@ public final class HSSFPatriarch implements HSSFShapeContainer, Drawing {
}
}
@Override
public Iterator<HSSFShape> iterator() {
return _shapes.iterator();
}

View File

@ -23,6 +23,7 @@ import java.io.IOException;
import org.apache.poi.ddf.EscherBoolProperty;
import org.apache.poi.ddf.EscherChildAnchorRecord;
import org.apache.poi.ddf.EscherClientAnchorRecord;
import org.apache.poi.ddf.EscherComplexProperty;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherOptRecord;
import org.apache.poi.ddf.EscherProperties;
@ -32,9 +33,11 @@ import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
import org.apache.poi.hssf.record.ObjRecord;
import org.apache.poi.ss.usermodel.Shape;
import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.StringUtil;
/**
* An abstract shape.
@ -44,7 +47,7 @@ import org.apache.poi.util.POILogger;
* reverse them and draw shapes vertically or horizontally flipped via
* setFlipVertical() or setFlipHorizontally().
*/
public abstract class HSSFShape {
public abstract class HSSFShape implements Shape {
private static final POILogger LOG = POILogFactory.getLogger(HSSFShape.class);
public static final int LINEWIDTH_ONE_PT = 12700;
@ -152,9 +155,7 @@ public abstract class HSSFShape {
return _optRecord;
}
/**
* Gets the parent shape.
*/
@Override
public HSSFShape getParent() {
return parent;
}
@ -162,6 +163,7 @@ public abstract class HSSFShape {
/**
* @return the anchor that is used by this shape.
*/
@Override
public HSSFAnchor getAnchor() {
return anchor;
}
@ -231,9 +233,7 @@ public abstract class HSSFShape {
setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor));
}
/**
* The color applied to the lines of this shape.
*/
@Override
public void setLineStyleColor(int red, int green, int blue) {
int lineStyleColor = ((blue) << 16) | ((green) << 8) | red;
setPropertyValue(new EscherRGBProperty(EscherProperties.LINESTYLE__COLOR, lineStyleColor));
@ -254,9 +254,7 @@ public abstract class HSSFShape {
setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor));
}
/**
* The color used to fill this shape.
*/
@Override
public void setFillColor(int red, int green, int blue) {
int fillColor = ((blue) << 16) | ((green) << 8) | red;
setPropertyValue(new EscherRGBProperty(EscherProperties.FILL__FILLCOLOR, fillColor));
@ -308,17 +306,13 @@ public abstract class HSSFShape {
}
}
/**
* @return <code>true</code> if this shape is not filled with a color.
*/
@Override
public boolean isNoFill() {
EscherBoolProperty property = _optRecord.lookup(EscherProperties.FILL__NOFILLHITTEST);
return property == null ? NO_FILL_DEFAULT : property.getPropertyValue() == NO_FILLHITTEST_TRUE;
}
/**
* @param noFill sets whether this shape is filled or transparent.
*/
@Override
public void setNoFill(boolean noFill) {
setPropertyValue(new EscherBoolProperty(EscherProperties.FILL__NOFILLHITTEST, noFill ? NO_FILLHITTEST_TRUE : NO_FILLHITTEST_FALSE));
}
@ -417,4 +411,19 @@ public abstract class HSSFShape {
protected void setParent(HSSFShape parent) {
this.parent = parent;
}
/**
* @return the name of this shape
*/
public String getShapeName() {
EscherOptRecord eor = getOptRecord();
if (eor == null) {
return null;
}
EscherProperty ep = eor.lookup(EscherProperties.GROUPSHAPE__SHAPENAME);
if (ep instanceof EscherComplexProperty) {
return StringUtil.getFromUnicodeLE(((EscherComplexProperty)ep).getComplexData());
}
return null;
}
}

View File

@ -19,10 +19,12 @@ package org.apache.poi.hssf.usermodel;
import java.util.List;
import org.apache.poi.ss.usermodel.ShapeContainer;
/**
* An interface that indicates whether a class can contain children.
*/
public interface HSSFShapeContainer extends Iterable<HSSFShape>
public interface HSSFShapeContainer extends ShapeContainer<HSSFShape>
{
/**
* @return Any children contained by this shape.

View File

@ -381,6 +381,7 @@ public class HSSFShapeGroup extends HSSFShape implements HSSFShapeContainer {
return isRemoved;
}
@Override
public Iterator<HSSFShape> iterator() {
return shapes.iterator();
}

View File

@ -17,14 +17,29 @@
package org.apache.poi.hssf.usermodel;
import org.apache.poi.ddf.*;
import org.apache.poi.hssf.record.*;
import org.apache.poi.ddf.DefaultEscherRecordFactory;
import org.apache.poi.ddf.EscherBoolProperty;
import org.apache.poi.ddf.EscherClientDataRecord;
import org.apache.poi.ddf.EscherContainerRecord;
import org.apache.poi.ddf.EscherOptRecord;
import org.apache.poi.ddf.EscherProperties;
import org.apache.poi.ddf.EscherRGBProperty;
import org.apache.poi.ddf.EscherShapePathProperty;
import org.apache.poi.ddf.EscherSimpleProperty;
import org.apache.poi.ddf.EscherSpRecord;
import org.apache.poi.ddf.EscherTextboxRecord;
import org.apache.poi.hssf.record.CommonObjectDataSubRecord;
import org.apache.poi.hssf.record.EndSubRecord;
import org.apache.poi.hssf.record.EscherAggregate;
import org.apache.poi.hssf.record.ObjRecord;
import org.apache.poi.hssf.record.TextObjectRecord;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.SimpleShape;
/**
* Represents a simple shape such as a line, rectangle or oval.
*/
public class HSSFSimpleShape extends HSSFShape
public class HSSFSimpleShape extends HSSFShape implements SimpleShape
{
// The commented out ones haven't been tested yet or aren't supported
// by HSSFSimpleShape.

View File

@ -0,0 +1,68 @@
/* ====================================================================
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.ss.usermodel;
/**
* Common interface for anchors.<p>
*
* An anchor is what specifics the position of a shape within a client object
* or within another containing shape.
*
* @since POI 3.16-beta2
*/
public interface ChildAnchor {
/**
* @return x coordinate of the left up corner
*/
int getDx1();
/**
* @param dx1 x coordinate of the left up corner
*/
void setDx1(int dx1);
/**
* @return y coordinate of the left up corner
*/
int getDy1();
/**
* @param dy1 y coordinate of the left up corner
*/
void setDy1(int dy1);
/**
* @return y coordinate of the right down corner
*/
int getDy2();
/**
* @param dy2 y coordinate of the right down corner
*/
void setDy2(int dy2);
/**
* @return x coordinate of the right down corner
*/
int getDx2();
/**
* @param dx2 x coordinate of the right down corner
*/
void setDx2(int dx2);
}

View File

@ -18,10 +18,8 @@ package org.apache.poi.ss.usermodel;
/**
* High level representation of spreadsheet drawing.
* @author Yegor Kozlov
* @author Roman Kashitsyn
*/
public interface Drawing {
public interface Drawing<T extends Shape> extends ShapeContainer<T> {
/**
* Creates a picture.
* @param anchor the client anchor describes how this picture is

View File

@ -21,10 +21,8 @@ import java.awt.Dimension;
/**
* Repersents a picture in a SpreadsheetML document
*
* @author Yegor Kozlov
*/
public interface Picture {
public interface Picture extends Shape {
/**
* Reset the image to the dimension of the embedded image

View File

@ -0,0 +1,64 @@
/* ====================================================================
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.ss.usermodel;
/**
* Common interface for all drawing shapes
*
* @since POI 3.16-beta2
*/
public interface Shape {
/**
* @return the name of this shape
*/
String getShapeName();
/**
* @return the parent shape.
*/
Shape getParent();
/**
* @return the anchor that is used by this shape.
*/
ChildAnchor getAnchor();
/**
* Whether this shape is not filled with a color
*
* @return true if this shape is not filled with a color.
*/
boolean isNoFill();
/**
* Sets whether this shape is filled or transparent.
*
* @param noFill if true then no fill will be applied to the shape element.
*/
void setNoFill(boolean noFill);
/**
* Sets the color used to fill this shape using the solid fill pattern.
*/
void setFillColor(int red, int green, int blue);
/**
* The color applied to the lines of this shape.
*/
void setLineStyleColor(int red, int green, int blue);
}

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.ss.usermodel;
/**
* A common interface for shape groups.
*
* @since POI 3.16-beta2
*/
public interface ShapeContainer<T extends Shape> extends Iterable<T> {
}

View File

@ -0,0 +1,28 @@
/* ====================================================================
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.ss.usermodel;
/**
* A common interface for simple shapes.
* (Currently the HSSF and XSSF classes don't share common method signatures ...)
*
* @since POI 3.16-beta2
*/
public interface SimpleShape extends Shape {
}

View File

@ -17,19 +17,22 @@
package org.apache.poi.xssf.streaming;
import java.util.Iterator;
import org.apache.poi.ss.usermodel.Chart;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Comment;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFPicture;
import org.apache.poi.xssf.usermodel.XSSFShape;
/**
* Streaming version of Drawing.
* Delegates most tasks to the non-streaming XSSF code.
* TODO: Potentially, Comment and Chart need a similar streaming wrapper like Picture.
*/
public class SXSSFDrawing implements Drawing {
public class SXSSFDrawing implements Drawing<XSSFShape> {
private final SXSSFWorkbook _wb;
private final XSSFDrawing _drawing;
@ -58,5 +61,10 @@ public class SXSSFDrawing implements Drawing {
public ClientAnchor createAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2) {
return _drawing.createAnchor(dx1, dy1, dx2, dy2, col1, row1, col2, row2);
}
@Override
public Iterator<XSSFShape> iterator() {
return _drawing.getShapes().iterator();
}
}

View File

@ -20,6 +20,7 @@ package org.apache.poi.xssf.streaming;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Shape;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.ImageUtils;
import org.apache.poi.util.Internal;
@ -182,7 +183,7 @@ public final class SXSSFPicture implements Picture {
}
private float getColumnWidthInPixels(int columnIndex){
XSSFSheet sheet = getParent();
XSSFSheet sheet = getSheet();
CTCol col = sheet.getColumnHelper().getColumn(columnIndex, false);
double numChars = col == null || !col.isSetWidth() ? DEFAULT_COLUMN_WIDTH : col.getWidth();
@ -193,7 +194,7 @@ public final class SXSSFPicture implements Picture {
private float getRowHeightInPixels(int rowIndex) {
// THE FOLLOWING THREE LINES ARE THE MAIN CHANGE compared to the non-streaming version: use the SXSSF sheet,
// not the XSSF sheet (which never contais rows when using SXSSF)
XSSFSheet xssfSheet = getParent();
XSSFSheet xssfSheet = getSheet();
SXSSFSheet sheet = _wb.getSXSSFSheet(xssfSheet);
Row row = sheet.getRow(rowIndex);
float height = row != null ? row.getHeightInPoints() : sheet.getDefaultRowHeightInPoints();
@ -232,11 +233,8 @@ public final class SXSSFPicture implements Picture {
return getCTPicture().getSpPr();
}
private XSSFSheet getParent() {
return (XSSFSheet)_picture.getDrawing().getParent();
}
private XSSFAnchor getAnchor() {
@Override
public XSSFAnchor getAnchor() {
return _picture.getAnchor();
}
@ -269,4 +267,34 @@ public final class SXSSFPicture implements Picture {
public XSSFSheet getSheet() {
return _picture.getSheet();
}
@Override
public String getShapeName() {
return _picture.getShapeName();
}
@Override
public Shape getParent() {
return _picture.getParent();
}
@Override
public boolean isNoFill() {
return _picture.isNoFill();
}
@Override
public void setNoFill(boolean noFill) {
_picture.setNoFill(noFill);
}
@Override
public void setFillColor(int red, int green, int blue) {
_picture.setFillColor(red, green, blue);
}
@Override
public void setLineStyleColor( int red, int green, int blue ) {
_picture.setLineStyleColor(red, green, blue);
}
}

View File

@ -17,21 +17,11 @@
package org.apache.poi.xssf.usermodel;
import org.apache.poi.ss.usermodel.ChildAnchor;
/**
* 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 {
public abstract int getDx1();
public abstract void setDx1( int dx1 );
public abstract int getDy1();
public abstract void setDy1( int dy1 );
public abstract int getDy2();
public abstract void setDy2( int dy2 );
public abstract int getDx2();
public abstract void setDx2( int dx2 );
public abstract class XSSFAnchor implements ChildAnchor {
}

View File

@ -134,4 +134,8 @@ public final class XSSFConnector extends XSSFShape {
return ctShape.getSpPr();
}
@Override
public String getShapeName() {
return ctShape.getNvCxnSpPr().getCNvPr().getName();
}
}

View File

@ -187,4 +187,9 @@ public final class XSSFGraphicFrame extends XSSFShape {
protected CTShapeProperties getShapeProperties(){
return null;
}
@Override
public String getShapeName() {
return graphicFrame.getNvGraphicFramePr().getCNvPr().getName();
}
}

View File

@ -284,4 +284,9 @@ public final class XSSFPicture extends XSSFShape implements Picture {
public XSSFSheet getSheet() {
return (XSSFSheet)getDrawing().getParent();
}
@Override
public String getShapeName() {
return ctPicture.getNvPicPr().getCNvPr().getName();
}
}

View File

@ -17,6 +17,7 @@
package org.apache.poi.xssf.usermodel;
import org.apache.poi.ss.usermodel.Shape;
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNoFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties;
@ -27,10 +28,8 @@ import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
/**
* Represents a shape in a SpreadsheetML drawing.
*
* @author Yegor Kozlov
*/
public abstract class XSSFShape {
public abstract class XSSFShape implements Shape {
public static final int EMU_PER_PIXEL = 9525;
public static final int EMU_PER_POINT = 12700;
@ -61,9 +60,7 @@ public abstract class XSSFShape {
return drawing;
}
/**
* Gets the parent shape.
*/
@Override
public XSSFShapeGroup getParent()
{
return parent;
@ -72,6 +69,7 @@ public abstract class XSSFShape {
/**
* @return the anchor that is used by this shape.
*/
@Override
public XSSFAnchor getAnchor()
{
return anchor;
@ -84,20 +82,12 @@ public abstract class XSSFShape {
*/
protected abstract CTShapeProperties getShapeProperties();
/**
* Whether this shape is not filled with a color
*
* @return true if this shape is not filled with a color.
*/
@Override
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.
*/
@Override
public void setNoFill(boolean noFill) {
CTShapeProperties props = getShapeProperties();
//unset solid and pattern fills if they are set
@ -107,9 +97,7 @@ public abstract class XSSFShape {
props.setNoFill(CTNoFillProperties.Factory.newInstance());
}
/**
* Sets the color used to fill this shape using the solid fill pattern.
*/
@Override
public void setFillColor(int red, int green, int blue) {
CTShapeProperties props = getShapeProperties();
CTSolidColorFillProperties fill = props.isSetSolidFill() ? props.getSolidFill() : props.addNewSolidFill();
@ -118,9 +106,7 @@ public abstract class XSSFShape {
fill.setSrgbClr(rgb);
}
/**
* The color applied to the lines of this shape.
*/
@Override
public void setLineStyleColor( int red, int green, int blue ) {
CTShapeProperties props = getShapeProperties();
CTLineProperties ln = props.isSetLn() ? props.getLn() : props.addNewLn();

View File

@ -23,6 +23,7 @@ import java.util.List;
import java.util.Locale;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.SimpleShape;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.util.Internal;
import org.apache.poi.util.Units;
@ -37,7 +38,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnderlineValues;
* Represents a shape with a predefined geometry in a SpreadsheetML drawing.
* Possible shape types are defined in {@link org.apache.poi.ss.usermodel.ShapeTypes}
*/
public class XSSFSimpleShape extends XSSFShape implements Iterable<XSSFTextParagraph> { // TODO - instantiable superclass
public class XSSFSimpleShape extends XSSFShape implements Iterable<XSSFTextParagraph>, SimpleShape {
/**
* List of the paragraphs that make up the text in this shape
*/
@ -863,4 +864,9 @@ public class XSSFSimpleShape extends XSSFShape implements Iterable<XSSFTextParag
}
}
}
@Override
public String getShapeName() {
return ctShape.getNvSpPr().getCNvPr().getName();
}
}