mirror of https://github.com/apache/poi.git
Initial support for SpreadsheetML drawings,implemented XSSFPicture, added ability to add pictures to workbook, refactored XSSFPictureData to be a subclass of POIXMLDocumentPart. Also refactored misc odds and ends in order to produce xml better compatible with what MS Office produces
git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@703490 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
91d6061c07
commit
b4e74b306c
|
@ -672,7 +672,7 @@ public interface Sheet extends Iterable<Row> {
|
|||
*
|
||||
* @return The new patriarch.
|
||||
*/
|
||||
Patriarch createDrawingPatriarch();
|
||||
//Patriarch createDrawingPatriarch();
|
||||
|
||||
/**
|
||||
* Expands or collapses a column group.
|
||||
|
|
|
@ -43,6 +43,7 @@ public class POIXMLDocumentPart {
|
|||
DEFAULT_XML_OPTIONS = new XmlOptions();
|
||||
DEFAULT_XML_OPTIONS.setSaveOuter();
|
||||
DEFAULT_XML_OPTIONS.setUseDefaultNamespace();
|
||||
DEFAULT_XML_OPTIONS.setSaveAggressiveNamespaces();
|
||||
}
|
||||
|
||||
protected PackagePart packagePart;
|
||||
|
@ -158,16 +159,30 @@ public class POIXMLDocumentPart {
|
|||
* @return the created child POIXMLDocumentPart
|
||||
*/
|
||||
protected POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, Class<? extends POIXMLDocumentPart> cls, int idx){
|
||||
return createRelationship(descriptor, cls, idx, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new child POIXMLDocumentPart
|
||||
*
|
||||
* @param descriptor the part descriptor
|
||||
* @param cls the Class object identifying the type of instance to create
|
||||
* @param idx part number
|
||||
* @param norel if true, then no relationship is added.
|
||||
* @return the created child POIXMLDocumentPart
|
||||
*/
|
||||
protected POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, Class<? extends POIXMLDocumentPart> cls, int idx, boolean norel){
|
||||
try {
|
||||
|
||||
PackagePartName ppName = PackagingURIHelper.createPartName(descriptor.getFileName(idx));
|
||||
PackageRelationship rel =
|
||||
packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation());
|
||||
PackageRelationship rel = null;
|
||||
if(!norel) rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation());
|
||||
|
||||
PackagePart part = packagePart.getPackage().createPart(ppName, descriptor.getContentType());
|
||||
POIXMLDocumentPart doc = cls.newInstance();
|
||||
doc.packageRel = rel;
|
||||
doc.packagePart = part;
|
||||
doc.parent = this;
|
||||
addRelation(doc);
|
||||
return doc;
|
||||
} catch (Exception e){
|
||||
|
|
|
@ -23,22 +23,64 @@ package org.apache.poi;
|
|||
*/
|
||||
public class POIXMLRelation {
|
||||
|
||||
/**
|
||||
* Describes the content stored in a part.
|
||||
*/
|
||||
protected String _type;
|
||||
|
||||
/**
|
||||
* The kind of connection between a source part and a target part in a package.
|
||||
*/
|
||||
protected String _relation;
|
||||
|
||||
/**
|
||||
* The path component of a pack URI.
|
||||
*/
|
||||
protected String _defaultName;
|
||||
|
||||
/**
|
||||
* Instantiates a POIXMLRelation.
|
||||
*
|
||||
* @param type content type
|
||||
* @param rel relationship
|
||||
* @param defaultName default item name
|
||||
*/
|
||||
protected POIXMLRelation(String type, String rel, String defaultName) {
|
||||
public POIXMLRelation(String type, String rel, String defaultName) {
|
||||
_type = type;
|
||||
_relation = rel;
|
||||
_defaultName = defaultName;
|
||||
}
|
||||
|
||||
public String getContentType() { return _type; }
|
||||
public String getRelation() { return _relation; }
|
||||
public String getDefaultFileName() { return _defaultName; }
|
||||
/**
|
||||
* Return the content type. Content types define a media type, a subtype, and an
|
||||
* optional set of parameters, as defined in RFC 2616.
|
||||
*
|
||||
* @return the content type
|
||||
*/
|
||||
public String getContentType() {
|
||||
return _type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the relationship, the kind of connection between a source part and a target part in a package.
|
||||
* Relationships make the connections between parts directly discoverable without looking at the content
|
||||
* in the parts, and without altering the parts themselves.
|
||||
*
|
||||
* @return the relationship
|
||||
*/
|
||||
public String getRelation() {
|
||||
return _relation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default part name. Part names are used to refer to a part in the context of a
|
||||
* package, typically as part of a URI.
|
||||
*
|
||||
* @return the default part name
|
||||
*/
|
||||
public String getDefaultFileName() {
|
||||
return _defaultName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the filename for the nth one of these,
|
||||
|
|
|
@ -31,7 +31,6 @@ public class XSSFSave {
|
|||
for (int i = 0; i < args.length; i++) {
|
||||
XSSFWorkbook wb = new XSSFWorkbook(args[i]);
|
||||
|
||||
System.out.println("wb.getNumberOfSheets(): " + wb.getNumberOfSheets());
|
||||
int sep = args[i].lastIndexOf('.');
|
||||
String outfile = args[i].substring(0, sep) + "-save.xlsx";
|
||||
FileOutputStream out = new FileOutputStream(outfile);
|
||||
|
|
|
@ -16,7 +16,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTDrawing;
|
|||
* A drawing object in XSSF. May well have raw pictures
|
||||
* attached to it as children.
|
||||
*/
|
||||
public class Drawing implements XSSFChildContainingModel {
|
||||
public class Drawing implements XSSFModel {
|
||||
private CTDrawing drawing;
|
||||
private String originalId;
|
||||
|
||||
|
@ -77,20 +77,11 @@ public class Drawing implements XSSFChildContainingModel {
|
|||
* Generates and adds XSSFActiveXData children
|
||||
*/
|
||||
public void generateChild(PackagePart childPart, String childRelId) {
|
||||
XSSFPictureData pd = new XSSFPictureData(childPart, childRelId);
|
||||
pictures.add(pd);
|
||||
}
|
||||
//XSSFPictureData pd = new XSSFPictureData(childPart, childRelId);
|
||||
//pictures.add(pd);
|
||||
throw new RuntimeException("deprecated");
|
||||
}
|
||||
|
||||
public WritableChild getChildForWriting(int index) {
|
||||
if(index >= pictures.size()) {
|
||||
throw new IllegalArgumentException("Can't get child at " + index + " when size is " + getNumberOfChildren());
|
||||
}
|
||||
return new WritableChild(
|
||||
pictures.get(index),
|
||||
XSSFRelation.IMAGES
|
||||
);
|
||||
}
|
||||
|
||||
public ArrayList<XSSFPictureData> getPictures()
|
||||
{
|
||||
return this.pictures;
|
||||
|
|
|
@ -198,9 +198,7 @@ public class SharedStringsTable extends POIXMLDocumentPart implements XSSFModel,
|
|||
* @throws IOException if an error occurs while writing.
|
||||
*/
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
XmlOptions options = new XmlOptions();
|
||||
options.setSaveOuter();
|
||||
options.setUseDefaultNamespace();
|
||||
XmlOptions options = new XmlOptions(DEFAULT_XML_OPTIONS);
|
||||
|
||||
//re-create the sst table every time saving a workbook
|
||||
SstDocument doc = SstDocument.Factory.newInstance();
|
||||
|
|
|
@ -330,13 +330,7 @@ public class StylesTable extends POIXMLDocumentPart implements StylesSource, XSS
|
|||
* @throws IOException if an error occurs while writing.
|
||||
*/
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
XmlOptions options = new XmlOptions();
|
||||
options.setSaveOuter();
|
||||
options.setUseDefaultNamespace();
|
||||
|
||||
// Requests use of whitespace for easier reading
|
||||
options.setSavePrettyPrint();
|
||||
|
||||
XmlOptions options = new XmlOptions(DEFAULT_XML_OPTIONS);
|
||||
|
||||
// Work on the current one
|
||||
// Need to do this, as we don't handle
|
||||
|
|
|
@ -0,0 +1,212 @@
|
|||
/* ====================================================================
|
||||
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;
|
||||
|
||||
/**
|
||||
* All know type of automatic shapes in DrawingML
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class ShapeTypes {
|
||||
public static final int LINE = 1;
|
||||
public static final int LINE_INV = 2;
|
||||
public static final int TRIANGLE = 3;
|
||||
public static final int RT_TRIANGLE = 4;
|
||||
public static final int RECT = 5;
|
||||
public static final int DIAMOND = 6;
|
||||
public static final int PARALLELOGRAM = 7;
|
||||
public static final int TRAPEZOID = 8;
|
||||
public static final int NON_ISOSCELES_TRAPEZOID = 9;
|
||||
public static final int PENTAGON = 10;
|
||||
public static final int HEXAGON = 11;
|
||||
public static final int HEPTAGON = 12;
|
||||
public static final int OCTAGON = 13;
|
||||
public static final int DECAGON = 14;
|
||||
public static final int DODECAGON = 15;
|
||||
public static final int STAR_4 = 16;
|
||||
public static final int STAR_5 = 17;
|
||||
public static final int STAR_6 = 18;
|
||||
public static final int STAR_7 = 19;
|
||||
public static final int STAR_8 = 20;
|
||||
public static final int STAR_10 = 21;
|
||||
public static final int STAR_12 = 22;
|
||||
public static final int STAR_16 = 23;
|
||||
public static final int STAR_24 = 24;
|
||||
public static final int STAR_32 = 25;
|
||||
public static final int ROUND_RECT = 26;
|
||||
public static final int ROUND_1_RECT = 27;
|
||||
public static final int ROUND_2_SAME_RECT = 28;
|
||||
public static final int ROUND_2_DIAG_RECT = 29;
|
||||
public static final int SNIP_ROUND_RECT = 30;
|
||||
public static final int SNIP_1_RECT = 31;
|
||||
public static final int SNIP_2_SAME_RECT = 32;
|
||||
public static final int SNIP_2_DIAG_RECT = 33;
|
||||
public static final int PLAQUE = 34;
|
||||
public static final int ELLIPSE = 35;
|
||||
public static final int TEARDROP = 36;
|
||||
public static final int HOME_PLATE = 37;
|
||||
public static final int CHEVRON = 38;
|
||||
public static final int PIE_WEDGE = 39;
|
||||
public static final int PIE = 40;
|
||||
public static final int BLOCK_ARC = 41;
|
||||
public static final int DONUT = 42;
|
||||
public static final int NO_SMOKING = 43;
|
||||
public static final int RIGHT_ARROW = 44;
|
||||
public static final int LEFT_ARROW = 45;
|
||||
public static final int UP_ARROW = 46;
|
||||
public static final int DOWN_ARROW = 47;
|
||||
public static final int STRIPED_RIGHT_ARROW = 48;
|
||||
public static final int NOTCHED_RIGHT_ARROW = 49;
|
||||
public static final int BENT_UP_ARROW = 50;
|
||||
public static final int LEFT_RIGHT_ARROW = 51;
|
||||
public static final int UP_DOWN_ARROW = 52;
|
||||
public static final int LEFT_UP_ARROW = 53;
|
||||
public static final int LEFT_RIGHT_UP_ARROW = 54;
|
||||
public static final int QUAD_ARROW = 55;
|
||||
public static final int LEFT_ARROW_CALLOUT = 56;
|
||||
public static final int RIGHT_ARROW_CALLOUT = 57;
|
||||
public static final int UP_ARROW_CALLOUT = 58;
|
||||
public static final int DOWN_ARROW_CALLOUT = 59;
|
||||
public static final int LEFT_RIGHT_ARROW_CALLOUT = 60;
|
||||
public static final int UP_DOWN_ARROW_CALLOUT = 61;
|
||||
public static final int QUAD_ARROW_CALLOUT = 62;
|
||||
public static final int BENT_ARROW = 63;
|
||||
public static final int UTURN_ARROW = 64;
|
||||
public static final int CIRCULAR_ARROW = 65;
|
||||
public static final int LEFT_CIRCULAR_ARROW = 66;
|
||||
public static final int LEFT_RIGHT_CIRCULAR_ARROW = 67;
|
||||
public static final int CURVED_RIGHT_ARROW = 68;
|
||||
public static final int CURVED_LEFT_ARROW = 69;
|
||||
public static final int CURVED_UP_ARROW = 70;
|
||||
public static final int CURVED_DOWN_ARROW = 71;
|
||||
public static final int SWOOSH_ARROW = 72;
|
||||
public static final int CUBE = 73;
|
||||
public static final int CAN = 74;
|
||||
public static final int LIGHTNING_BOLT = 75;
|
||||
public static final int HEART = 76;
|
||||
public static final int SUN = 77;
|
||||
public static final int MOON = 78;
|
||||
public static final int SMILEY_FACE = 79;
|
||||
public static final int IRREGULAR_SEAL_1 = 80;
|
||||
public static final int IRREGULAR_SEAL_2 = 81;
|
||||
public static final int FOLDED_CORNER = 82;
|
||||
public static final int BEVEL = 83;
|
||||
public static final int FRAME = 84;
|
||||
public static final int HALF_FRAME = 85;
|
||||
public static final int CORNER = 86;
|
||||
public static final int DIAG_STRIPE = 87;
|
||||
public static final int CHORD = 88;
|
||||
public static final int ARC = 89;
|
||||
public static final int LEFT_BRACKET = 90;
|
||||
public static final int RIGHT_BRACKET = 91;
|
||||
public static final int LEFT_BRACE = 92;
|
||||
public static final int RIGHT_BRACE = 93;
|
||||
public static final int BRACKET_PAIR = 94;
|
||||
public static final int BRACE_PAIR = 95;
|
||||
public static final int STRAIGHT_CONNECTOR_1 = 96;
|
||||
public static final int BENT_CONNECTOR_2 = 97;
|
||||
public static final int BENT_CONNECTOR_3 = 98;
|
||||
public static final int BENT_CONNECTOR_4 = 99;
|
||||
public static final int BENT_CONNECTOR_5 = 100;
|
||||
public static final int CURVED_CONNECTOR_2 = 101;
|
||||
public static final int CURVED_CONNECTOR_3 = 102;
|
||||
public static final int CURVED_CONNECTOR_4 = 103;
|
||||
public static final int CURVED_CONNECTOR_5 = 104;
|
||||
public static final int CALLOUT_1 = 105;
|
||||
public static final int CALLOUT_2 = 106;
|
||||
public static final int CALLOUT_3 = 107;
|
||||
public static final int ACCENT_CALLOUT_1 = 108;
|
||||
public static final int ACCENT_CALLOUT_2 = 109;
|
||||
public static final int ACCENT_CALLOUT_3 = 110;
|
||||
public static final int BORDER_CALLOUT_1 = 111;
|
||||
public static final int BORDER_CALLOUT_2 = 112;
|
||||
public static final int BORDER_CALLOUT_3 = 113;
|
||||
public static final int ACCENT_BORDER_CALLOUT_1 = 114;
|
||||
public static final int ACCENT_BORDER_CALLOUT_2 = 115;
|
||||
public static final int ACCENT_BORDER_CALLOUT_3 = 116;
|
||||
public static final int WEDGE_RECT_CALLOUT = 117;
|
||||
public static final int WEDGE_ROUND_RECT_CALLOUT = 118;
|
||||
public static final int WEDGE_ELLIPSE_CALLOUT = 119;
|
||||
public static final int CLOUD_CALLOUT = 120;
|
||||
public static final int CLOUD = 121;
|
||||
public static final int RIBBON = 122;
|
||||
public static final int RIBBON_2 = 123;
|
||||
public static final int ELLIPSE_RIBBON = 124;
|
||||
public static final int ELLIPSE_RIBBON_2 = 125;
|
||||
public static final int LEFT_RIGHT_RIBBON = 126;
|
||||
public static final int VERTICAL_SCROLL = 127;
|
||||
public static final int HORIZONTAL_SCROLL = 128;
|
||||
public static final int WAVE = 129;
|
||||
public static final int DOUBLE_WAVE = 130;
|
||||
public static final int PLUS = 131;
|
||||
public static final int FLOW_CHART_PROCESS = 132;
|
||||
public static final int FLOW_CHART_DECISION = 133;
|
||||
public static final int FLOW_CHART_INPUT_OUTPUT = 134;
|
||||
public static final int FLOW_CHART_PREDEFINED_PROCESS = 135;
|
||||
public static final int FLOW_CHART_INTERNAL_STORAGE = 136;
|
||||
public static final int FLOW_CHART_DOCUMENT = 137;
|
||||
public static final int FLOW_CHART_MULTIDOCUMENT = 138;
|
||||
public static final int FLOW_CHART_TERMINATOR = 139;
|
||||
public static final int FLOW_CHART_PREPARATION = 140;
|
||||
public static final int FLOW_CHART_MANUAL_INPUT = 141;
|
||||
public static final int FLOW_CHART_MANUAL_OPERATION = 142;
|
||||
public static final int FLOW_CHART_CONNECTOR = 143;
|
||||
public static final int FLOW_CHART_PUNCHED_CARD = 144;
|
||||
public static final int FLOW_CHART_PUNCHED_TAPE = 145;
|
||||
public static final int FLOW_CHART_SUMMING_JUNCTION = 146;
|
||||
public static final int FLOW_CHART_OR = 147;
|
||||
public static final int FLOW_CHART_COLLATE = 148;
|
||||
public static final int FLOW_CHART_SORT = 149;
|
||||
public static final int FLOW_CHART_EXTRACT = 150;
|
||||
public static final int FLOW_CHART_MERGE = 151;
|
||||
public static final int FLOW_CHART_OFFLINE_STORAGE = 152;
|
||||
public static final int FLOW_CHART_ONLINE_STORAGE = 153;
|
||||
public static final int FLOW_CHART_MAGNETIC_TAPE = 154;
|
||||
public static final int FLOW_CHART_MAGNETIC_DISK = 155;
|
||||
public static final int FLOW_CHART_MAGNETIC_DRUM = 156;
|
||||
public static final int FLOW_CHART_DISPLAY = 157;
|
||||
public static final int FLOW_CHART_DELAY = 158;
|
||||
public static final int FLOW_CHART_ALTERNATE_PROCESS = 159;
|
||||
public static final int FLOW_CHART_OFFPAGE_CONNECTOR = 160;
|
||||
public static final int ACTION_BUTTON_BLANK = 161;
|
||||
public static final int ACTION_BUTTON_HOME = 162;
|
||||
public static final int ACTION_BUTTON_HELP = 163;
|
||||
public static final int ACTION_BUTTON_INFORMATION = 164;
|
||||
public static final int ACTION_BUTTON_FORWARD_NEXT = 165;
|
||||
public static final int ACTION_BUTTON_BACK_PREVIOUS = 166;
|
||||
public static final int ACTION_BUTTON_END = 167;
|
||||
public static final int ACTION_BUTTON_BEGINNING = 168;
|
||||
public static final int ACTION_BUTTON_RETURN = 169;
|
||||
public static final int ACTION_BUTTON_DOCUMENT = 170;
|
||||
public static final int ACTION_BUTTON_SOUND = 171;
|
||||
public static final int ACTION_BUTTON_MOVIE = 172;
|
||||
public static final int GEAR_6 = 173;
|
||||
public static final int GEAR_9 = 174;
|
||||
public static final int FUNNEL = 175;
|
||||
public static final int MATH_PLUS = 176;
|
||||
public static final int MATH_MINUS = 177;
|
||||
public static final int MATH_MULTIPLY = 178;
|
||||
public static final int MATH_DIVIDE = 179;
|
||||
public static final int MATH_EQUAL = 180;
|
||||
public static final int MATH_NOT_EQUAL = 181;
|
||||
public static final int CORNER_TABS = 182;
|
||||
public static final int SQUARE_TABS = 183;
|
||||
public static final int PLAQUE_TABS = 184;
|
||||
public static final int CHART_X = 185;
|
||||
public static final int CHART_STAR = 186;
|
||||
public static final int CHART_PLUS = 187;
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/* ====================================================================
|
||||
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.CTMarker;
|
||||
|
||||
/**
|
||||
* A client anchor is attached to an excel worksheet. It anchors against
|
||||
* top-left and buttom-right cells.
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class XSSFClientAnchor {
|
||||
|
||||
/**
|
||||
* Starting anchor point
|
||||
*/
|
||||
private CTMarker cell1;
|
||||
|
||||
/**
|
||||
* Ending anchor point
|
||||
*/
|
||||
private CTMarker cell2;
|
||||
|
||||
/**
|
||||
* Creates a new client anchor and defaults all the anchor positions to 0.
|
||||
*/
|
||||
public XSSFClientAnchor() {
|
||||
cell1 = CTMarker.Factory.newInstance();
|
||||
cell1.setCol(0);
|
||||
cell1.setColOff(0);
|
||||
cell1.setRow(0);
|
||||
cell1.setRowOff(0);
|
||||
cell2 = CTMarker.Factory.newInstance();
|
||||
cell2.setCol(0);
|
||||
cell2.setColOff(0);
|
||||
cell2.setRow(0);
|
||||
cell2.setRowOff(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new client anchor and sets the top-left and bottom-right
|
||||
* coordinates of the anchor.
|
||||
*
|
||||
* @param dx1 the x coordinate within the first cell.
|
||||
* @param dy1 the y coordinate within the first cell.
|
||||
* @param dx2 the x coordinate within the second cell.
|
||||
* @param dy2 the y coordinate within the second cell.
|
||||
* @param col1 the column (0 based) of the first cell.
|
||||
* @param row1 the row (0 based) of the first cell.
|
||||
* @param col2 the column (0 based) of the second cell.
|
||||
* @param row2 the row (0 based) of the second cell.
|
||||
*/
|
||||
public XSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2) {
|
||||
this();
|
||||
cell1.setCol(col1);
|
||||
cell1.setColOff(dx1);
|
||||
cell1.setRow(row1);
|
||||
cell1.setRowOff(dy1);
|
||||
cell2.setCol(col2);
|
||||
cell2.setColOff(dx2);
|
||||
cell2.setRow(row2);
|
||||
cell2.setRowOff(dy2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create XSSFClientAnchor from existing xml beans
|
||||
*
|
||||
* @param cell1 starting anchor point
|
||||
* @param cell2 ending anchor point
|
||||
*/
|
||||
protected XSSFClientAnchor(CTMarker cell1, CTMarker cell2) {
|
||||
this.cell1 = cell1;
|
||||
this.cell2 = cell2;
|
||||
}
|
||||
|
||||
public int getCol1() {
|
||||
return cell1.getCol();
|
||||
}
|
||||
|
||||
public void setCol1(short col1) {
|
||||
cell1.setCol(col1);
|
||||
}
|
||||
|
||||
public int getCol2() {
|
||||
return cell2.getCol();
|
||||
}
|
||||
|
||||
public void setCol2(short col2) {
|
||||
cell2.setCol(col2);
|
||||
}
|
||||
|
||||
public int getRow1() {
|
||||
return cell1.getRow();
|
||||
}
|
||||
|
||||
public void setRow1(int row1) {
|
||||
cell1.setRow(row1);
|
||||
}
|
||||
|
||||
public int getRow2() {
|
||||
return cell2.getRow();
|
||||
}
|
||||
|
||||
public void setRow2(int row2) {
|
||||
cell2.setRow(row2);
|
||||
}
|
||||
|
||||
public int getDx1() {
|
||||
return (int)cell1.getColOff();
|
||||
}
|
||||
|
||||
public void setDx1(int dx1) {
|
||||
cell1.setColOff(dx1);
|
||||
}
|
||||
|
||||
public int getDy1() {
|
||||
return (int)cell1.getRowOff();
|
||||
}
|
||||
|
||||
public void setDy1(int dy1) {
|
||||
cell1.setRowOff(dy1);
|
||||
}
|
||||
|
||||
public int getDy2() {
|
||||
return (int)cell2.getRowOff();
|
||||
}
|
||||
|
||||
public void setDy2(int dy2) {
|
||||
cell2.setRowOff(dy2);
|
||||
}
|
||||
|
||||
public int getDx2() {
|
||||
return (int)cell2.getColOff();
|
||||
}
|
||||
|
||||
public void setDx2(int dx2) {
|
||||
cell2.setColOff(dx2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null || !(o instanceof XSSFClientAnchor)) return false;
|
||||
|
||||
XSSFClientAnchor anchor = (XSSFClientAnchor) o;
|
||||
return cell1.toString().equals(anchor.getFrom().toString()) &&
|
||||
cell2.toString().equals(anchor.getTo().toString()) ;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "from : " + cell1.toString() + "; to: " + cell2.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return starting anchor point
|
||||
*
|
||||
* @return starting anchor point
|
||||
*/
|
||||
public CTMarker getFrom(){
|
||||
return cell1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return ending anchor point
|
||||
*
|
||||
* @return ending anchor point
|
||||
*/
|
||||
public CTMarker getTo(){
|
||||
return cell2;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,155 @@
|
|||
/* ====================================================================
|
||||
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.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.openxml4j.opc.*;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTDrawing;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.STEditAs;
|
||||
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
|
||||
|
||||
import javax.xml.namespace.QName;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* Represents a SpreadsheetML drawing
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class XSSFDrawing extends POIXMLDocumentPart {
|
||||
/**
|
||||
* Root element of the SpreadsheetML Drawing part
|
||||
*/
|
||||
private CTDrawing drawing;
|
||||
|
||||
/**
|
||||
* Create a new SpreadsheetML drawing
|
||||
*
|
||||
* @see org.apache.poi.xssf.usermodel.XSSFWorksheet#createDrawingPatriarch()
|
||||
*/
|
||||
public XSSFDrawing() {
|
||||
super(null, null);
|
||||
drawing = newDrawing();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a SpreadsheetML drawing from a package part
|
||||
*
|
||||
* @param part the package part holding the drawing data,
|
||||
* the content type must be <code>application/vnd.openxmlformats-officedocument.drawing+xml</code>
|
||||
* @param rel the package relationship holding this drawing,
|
||||
* the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing
|
||||
*/
|
||||
public XSSFDrawing(PackagePart part, PackageRelationship rel) throws IOException, XmlException {
|
||||
super(part, rel);
|
||||
drawing = CTDrawing.Factory.parse(part.getInputStream());
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new CTDrawing bean. By default, it's just an empty placeholder for drawing objects
|
||||
*
|
||||
* @return a new CTDrawing bean
|
||||
*/
|
||||
private static CTDrawing newDrawing(){
|
||||
return CTDrawing.Factory.newInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying CTDrawing bean, the root element of the SpreadsheetML Drawing part.
|
||||
*
|
||||
* @return the underlying CTDrawing bean
|
||||
*/
|
||||
public CTDrawing getCTDrawing(){
|
||||
return drawing;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void commit() throws IOException {
|
||||
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
|
||||
|
||||
/*
|
||||
Saved drawings must have the following namespaces set:
|
||||
<xdr:wsDr
|
||||
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"
|
||||
xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">
|
||||
*/
|
||||
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTDrawing.type.getName().getNamespaceURI(), "wsDr", "xdr"));
|
||||
Map map = new HashMap();
|
||||
map.put("http://schemas.openxmlformats.org/drawingml/2006/main", "a");
|
||||
map.put(STRelationshipId.type.getName().getNamespaceURI(), "r");
|
||||
xmlOptions.setSaveSuggestedPrefixes(map);
|
||||
|
||||
PackagePart part = getPackagePart();
|
||||
OutputStream out = part.getOutputStream();
|
||||
drawing.save(out, xmlOptions);
|
||||
out.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 org.apache.poi.xssf.usermodel.XSSFWorkbook#getAllPictures()} .
|
||||
*
|
||||
* @return the newly created picture shape.
|
||||
*/
|
||||
public XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex)
|
||||
{
|
||||
XSSFWorkbook wb = (XSSFWorkbook)getParent().getParent();
|
||||
XSSFPictureData data = wb.getAllPictures().get(pictureIndex);
|
||||
PackagePartName ppName = data.getPackagePart().getPartName();
|
||||
PackageRelationship rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, XSSFRelation.IMAGES.getRelation());
|
||||
addRelation(new XSSFPictureData(data.getPackagePart(), rel));
|
||||
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
|
||||
return new XSSFPicture(this, rel, ctAnchor);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 XSSFSimpleShape createSimpleShape(XSSFClientAnchor anchor)
|
||||
{
|
||||
CTTwoCellAnchor ctAnchor = createTwoCellAnchor(anchor);
|
||||
return new XSSFSimpleShape(this, ctAnchor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and initialize a CTTwoCellAnchor that anchors a shape against top-left and bottom-right cells.
|
||||
*
|
||||
* @return a new CTTwoCellAnchor
|
||||
*/
|
||||
private CTTwoCellAnchor createTwoCellAnchor(XSSFClientAnchor anchor){
|
||||
CTTwoCellAnchor ctAnchor = drawing.addNewTwoCellAnchor();
|
||||
ctAnchor.setEditAs(STEditAs.ONE_CELL);
|
||||
ctAnchor.setFrom(anchor.getFrom());
|
||||
ctAnchor.setTo(anchor.getTo());
|
||||
ctAnchor.addNewClientData();
|
||||
return ctAnchor;
|
||||
}
|
||||
}
|
|
@ -41,6 +41,8 @@ public class XSSFFactory extends POIXMLFactory {
|
|||
parts.put(XSSFRelation.SHARED_STRINGS.getRelation(), SharedStringsTable.class);
|
||||
parts.put(XSSFRelation.STYLES.getRelation(), StylesTable.class);
|
||||
parts.put(XSSFRelation.SHEET_COMMENTS.getRelation(), CommentsTable.class);
|
||||
parts.put(XSSFRelation.DRAWINGS.getRelation(), XSSFDrawing.class);
|
||||
parts.put(XSSFRelation.IMAGES.getRelation(), XSSFPictureData.class);
|
||||
}
|
||||
|
||||
public POIXMLDocumentPart create(PackageRelationship rel, PackagePart p){
|
||||
|
|
|
@ -0,0 +1,325 @@
|
|||
/* ====================================================================
|
||||
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.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.Element;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageReader;
|
||||
import javax.imageio.stream.ImageInputStream;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Represents a picture shape in a SpreadsheetML drawing.
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class XSSFPicture extends XSSFShape {
|
||||
private static final POILogger logger = POILogFactory.getLogger(XSSFPicture.class);
|
||||
|
||||
/**
|
||||
* width of 1px in columns with default width
|
||||
*/
|
||||
private static final float PX_DEFAULT = 0.125f;
|
||||
/**
|
||||
* width of 1px in columns with overridden width
|
||||
*/
|
||||
private static final float PX_MODIFIED = 0.143f;
|
||||
|
||||
/**
|
||||
* Height of 1px of a row
|
||||
*/
|
||||
private static final int PX_ROW = 15;
|
||||
|
||||
/**
|
||||
* This object specifies a picture object and all its properties
|
||||
*/
|
||||
private CTPicture ctPicture;
|
||||
|
||||
/**
|
||||
* Construct a new XSSFPicture object. This constructor is called from
|
||||
* {@link XSSFDrawing#createPicture(XSSFClientAnchor, int)}
|
||||
*
|
||||
* @param parent the XSSFDrawing that owns this picture
|
||||
* @param rel the relationship to the picture data
|
||||
* @param anchor the two cell anchor placeholder for this picture,
|
||||
* this object encloses the CTPicture bean that holds all the picture properties
|
||||
*/
|
||||
protected XSSFPicture(XSSFDrawing parent, PackageRelationship rel, CTTwoCellAnchor anchor){
|
||||
super(parent, anchor);
|
||||
//Create a new picture and attach it to the specified two-cell anchor
|
||||
ctPicture = newPicture(rel);
|
||||
anchor.setPic(ctPicture);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new CTPicture bean and initialize its required attributes
|
||||
*
|
||||
* @param rel the relationship to the picture data
|
||||
* @return a new CTPicture bean
|
||||
*/
|
||||
private static CTPicture newPicture(PackageRelationship rel){
|
||||
CTPicture pic = CTPicture.Factory.newInstance();
|
||||
|
||||
CTPictureNonVisual nvpr = pic.addNewNvPicPr();
|
||||
CTNonVisualDrawingProps nvProps = nvpr.addNewCNvPr();
|
||||
//YK: TODO shape IDs must be unique across workbook
|
||||
int shapeId = 1;
|
||||
nvProps.setId(shapeId);
|
||||
nvProps.setName("Picture " + shapeId);
|
||||
nvProps.setDescr(rel.getTargetURI().toString());
|
||||
CTNonVisualPictureProperties nvPicProps = nvpr.addNewCNvPicPr();
|
||||
nvPicProps.addNewPicLocks().setNoChangeAspect(true);
|
||||
|
||||
CTBlipFillProperties blip = pic.addNewBlipFill();
|
||||
blip.addNewBlip().setEmbed(rel.getId());
|
||||
blip.addNewStretch().addNewFillRect();
|
||||
|
||||
CTShapeProperties sppr = pic.addNewSpPr();
|
||||
CTTransform2D t2d = sppr.addNewXfrm();
|
||||
CTPositiveSize2D ext = t2d.addNewExt();
|
||||
//should be original picture width and height expressed in EMUs
|
||||
ext.setCx(0);
|
||||
ext.setCy(0);
|
||||
|
||||
CTPoint2D off = t2d.addNewOff();
|
||||
off.setX(0);
|
||||
off.setY(0);
|
||||
|
||||
CTPresetGeometry2D prstGeom = sppr.addNewPrstGeom();
|
||||
prstGeom.setPrst(STShapeType.RECT);
|
||||
prstGeom.addNewAvLst();
|
||||
return pic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying CTPicture bean that holds all properties for this picture
|
||||
*
|
||||
* @return the underlying CTPicture bean
|
||||
*/
|
||||
public CTPicture getCTPicture(){
|
||||
return ctPicture;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the image to the original size.
|
||||
*/
|
||||
public void resize(){
|
||||
XSSFClientAnchor anchor = getAnchor();
|
||||
|
||||
XSSFClientAnchor pref = getPreferredSize();
|
||||
|
||||
int row2 = anchor.getRow1() + (pref.getRow2() - pref.getRow1());
|
||||
int col2 = anchor.getCol1() + (pref.getCol2() - pref.getCol1());
|
||||
|
||||
anchor.setCol2((short)col2);
|
||||
anchor.setDx1(0);
|
||||
anchor.setDx2(pref.getDx2());
|
||||
|
||||
anchor.setRow2(row2);
|
||||
anchor.setDy1(0);
|
||||
anchor.setDy2(pref.getDy2());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the preferred size for this picture.
|
||||
*
|
||||
* @return XSSFClientAnchor with the preferred size for this image
|
||||
*/
|
||||
public XSSFClientAnchor getPreferredSize(){
|
||||
XSSFClientAnchor anchor = getAnchor();
|
||||
|
||||
XSSFPictureData data = getPictureData();
|
||||
Dimension size = getImageDimension(data.getPackagePart(), data.getPictureType());
|
||||
|
||||
float w = 0;
|
||||
|
||||
//space in the leftmost cell
|
||||
w += anchor.getDx1()/EMU_PER_POINT;
|
||||
short col2 = (short)(anchor.getCol1() + 1);
|
||||
int dx2 = 0;
|
||||
|
||||
while(w < size.width){
|
||||
w += getColumnWidthInPixels(col2++);
|
||||
}
|
||||
|
||||
if(w > size.width) {
|
||||
//calculate dx2, offset in the rightmost cell
|
||||
col2--;
|
||||
float cw = getColumnWidthInPixels(col2);
|
||||
float delta = w - size.width;
|
||||
dx2 = (int)(EMU_PER_POINT*(cw-delta));
|
||||
}
|
||||
anchor.setCol2(col2);
|
||||
anchor.setDx2(dx2);
|
||||
|
||||
float h = 0;
|
||||
h += (1 - anchor.getDy1()/256)* getRowHeightInPixels(anchor.getRow1());
|
||||
int row2 = anchor.getRow1() + 1;
|
||||
int dy2 = 0;
|
||||
|
||||
while(h < size.height){
|
||||
h += getRowHeightInPixels(row2++);
|
||||
}
|
||||
if(h > size.height) {
|
||||
row2--;
|
||||
float ch = getRowHeightInPixels(row2);
|
||||
float delta = h - size.height;
|
||||
dy2 = (int)((ch-delta)/ch*256);
|
||||
}
|
||||
anchor.setRow2(row2);
|
||||
anchor.setDy2(dy2);
|
||||
|
||||
return anchor;
|
||||
}
|
||||
|
||||
private float getColumnWidthInPixels(int column){
|
||||
XSSFSheet sheet = (XSSFSheet)getDrawing().getParent();
|
||||
int cw = sheet.getColumnWidth(column);
|
||||
float px = getPixelWidth(column);
|
||||
|
||||
return cw/px;
|
||||
}
|
||||
|
||||
private float getRowHeightInPixels(int i){
|
||||
XSSFSheet sheet = (XSSFSheet)getDrawing().getParent();
|
||||
|
||||
XSSFRow row = sheet.getRow(i);
|
||||
float height;
|
||||
if(row != null) height = row.getHeight();
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the dimension of this image
|
||||
*
|
||||
* @param part the package part holding raw picture data
|
||||
* @param type type of the picture: {@link Workbook#PICTURE_TYPE_JPEG, Workbook#PICTURE_TYPE_PNG or Workbook#PICTURE_TYPE_DIB)
|
||||
*
|
||||
* @return image dimension in pixels
|
||||
*/
|
||||
protected static Dimension getImageDimension(PackagePart part, int type){
|
||||
Dimension size = new Dimension();
|
||||
|
||||
switch (type){
|
||||
//we can calculate the preferred size only for JPEG and PNG
|
||||
//other formats like WMF, EMF and PICT are not supported in Java
|
||||
case Workbook.PICTURE_TYPE_JPEG:
|
||||
case Workbook.PICTURE_TYPE_PNG:
|
||||
case Workbook.PICTURE_TYPE_DIB:
|
||||
try {
|
||||
//read the image using javax.imageio.*
|
||||
ImageInputStream iis = ImageIO.createImageInputStream( part.getInputStream() );
|
||||
Iterator i = ImageIO.getImageReaders( iis );
|
||||
ImageReader r = (ImageReader) i.next();
|
||||
r.setInput( iis );
|
||||
BufferedImage img = r.read(0);
|
||||
|
||||
int[] dpi = getResolution(r);
|
||||
|
||||
//if DPI is zero then assume standard 96 DPI
|
||||
//since cannot divide by zero
|
||||
if (dpi[0] == 0) dpi[0] = 96;
|
||||
if (dpi[1] == 0) dpi[1] = 96;
|
||||
|
||||
size.width = img.getWidth()*96/dpi[0];
|
||||
size.height = img.getHeight()*96/dpi[1];
|
||||
|
||||
} catch (IOException e){
|
||||
//silently return if ImageIO failed to read the image
|
||||
logger.log(POILogger.WARN, e);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
logger.log(POILogger.WARN, "Only JPEG, PNG and DIB pictures can be automatically sized");
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* The metadata of PNG and JPEG can contain the width of a pixel in millimeters.
|
||||
* Return the the "effective" dpi calculated as <code>25.4/HorizontalPixelSize</code>
|
||||
* and <code>25.4/VerticalPixelSize</code>. Where 25.4 is the number of mm in inch.
|
||||
*
|
||||
* @return array of two elements: <code>{horisontalPdi, verticalDpi}</code>.
|
||||
* {96, 96} is the default.
|
||||
*/
|
||||
protected static int[] getResolution(ImageReader r) throws IOException {
|
||||
int hdpi=96, vdpi=96;
|
||||
double mm2inch = 25.4;
|
||||
|
||||
NodeList lst;
|
||||
Element node = (Element)r.getImageMetadata(0).getAsTree("javax_imageio_1.0");
|
||||
lst = node.getElementsByTagName("HorizontalPixelSize");
|
||||
if(lst != null && lst.getLength() == 1) hdpi = (int)(mm2inch/Float.parseFloat(((Element)lst.item(0)).getAttribute("value")));
|
||||
|
||||
lst = node.getElementsByTagName("VerticalPixelSize");
|
||||
if(lst != null && lst.getLength() == 1) vdpi = (int)(mm2inch/Float.parseFloat(((Element)lst.item(0)).getAttribute("value")));
|
||||
|
||||
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
|
||||
*/
|
||||
public XSSFPictureData getPictureData() {
|
||||
String blipId = ctPicture.getBlipFill().getBlip().getEmbed();
|
||||
for (POIXMLDocumentPart part : getDrawing().getRelations()) {
|
||||
if(part.getPackageRelationship().getId().equals(blipId)){
|
||||
return (XSSFPictureData)part;
|
||||
}
|
||||
}
|
||||
logger.log(POILogger.WARN, "Picture data was not found for blipId=" + blipId);
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -18,51 +18,105 @@
|
|||
package org.apache.poi.xssf.usermodel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.apache.poi.ss.usermodel.PictureData;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.xssf.model.XSSFWritableModel;
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.POIXMLException;
|
||||
import org.apache.poi.POIXMLRelation;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
|
||||
/**
|
||||
* Raw picture data, normally attached to a
|
||||
* vmlDrawing
|
||||
* Raw picture data, normally attached to a SpreadsheetML Drawing.
|
||||
* As a rule, pictures are stored in the /xl/media/ part of a SpreadsheetML package.
|
||||
*/
|
||||
public class XSSFPictureData implements PictureData, XSSFWritableModel {
|
||||
private PackagePart packagePart;
|
||||
private String originalId;
|
||||
public class XSSFPictureData extends POIXMLDocumentPart implements PictureData {
|
||||
|
||||
public XSSFPictureData(PackagePart packagePart, String originalId) {
|
||||
this(packagePart);
|
||||
this.originalId = originalId;
|
||||
}
|
||||
|
||||
public XSSFPictureData(PackagePart packagePart) {
|
||||
this.packagePart = packagePart;
|
||||
/**
|
||||
* Relationships for each known picture type
|
||||
*/
|
||||
protected static final POIXMLRelation[] RELATIONS;
|
||||
static {
|
||||
RELATIONS = new POIXMLRelation[8];
|
||||
RELATIONS[Workbook.PICTURE_TYPE_EMF] = new POIXMLRelation("image/x-emf", XSSFRelation.IMAGES.getRelation(), "/xl/media/image#.emf");
|
||||
RELATIONS[Workbook.PICTURE_TYPE_WMF] = new POIXMLRelation("image/x-wmf", XSSFRelation.IMAGES.getRelation(), "/xl/media/image#.wmf");
|
||||
RELATIONS[Workbook.PICTURE_TYPE_PICT] = new POIXMLRelation("image/pict", XSSFRelation.IMAGES.getRelation(), "/xl/media/image#.pict");
|
||||
RELATIONS[Workbook.PICTURE_TYPE_JPEG] = new POIXMLRelation("image/jpeg", XSSFRelation.IMAGES.getRelation(), "/xl/media/image#.jpeg");
|
||||
RELATIONS[Workbook.PICTURE_TYPE_PNG] = new POIXMLRelation("image/png", XSSFRelation.IMAGES.getRelation(), "/xl/media/image#.png");
|
||||
RELATIONS[Workbook.PICTURE_TYPE_DIB] = new POIXMLRelation("image/dib", XSSFRelation.IMAGES.getRelation(), "/xl/media/image#.dib");
|
||||
}
|
||||
|
||||
public String getOriginalId() {
|
||||
return originalId;
|
||||
/**
|
||||
* Create a new XSSFPictureData node
|
||||
*
|
||||
* @see org.apache.poi.xssf.usermodel.XSSFWorkbook#addPicture(byte[], int)
|
||||
*/
|
||||
public XSSFPictureData() {
|
||||
super(null, null);
|
||||
}
|
||||
|
||||
protected PackagePart getPart() {
|
||||
return packagePart;
|
||||
}
|
||||
|
||||
public void writeTo(OutputStream out) throws IOException {
|
||||
IOUtils.copy(packagePart.getInputStream(), out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct XSSFPictureData from a package part
|
||||
*
|
||||
* @param part the package part holding the drawing data,
|
||||
* @param rel the package relationship holding this drawing,
|
||||
* the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/image
|
||||
*/
|
||||
public XSSFPictureData(PackagePart part, PackageRelationship rel) {
|
||||
super(part, rel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the picture data as a byte array.
|
||||
* <p>
|
||||
* Note, that this call might be expensive since all the picture data is copied into a temporary byte array.
|
||||
* You can grab the picture data directly from the underlying package part as follows:
|
||||
* <br/>
|
||||
* <code>
|
||||
* InputStream is = getPackagePart().getInputStream();
|
||||
* </code>
|
||||
* </p>
|
||||
*
|
||||
* @return the picture data.
|
||||
*/
|
||||
public byte[] getData() {
|
||||
try {
|
||||
return IOUtils.toByteArray(packagePart.getInputStream());
|
||||
} catch(IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
return IOUtils.toByteArray(getPackagePart().getInputStream());
|
||||
} catch(IOException e) {
|
||||
throw new POIXMLException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Suggests a file extension for this image.
|
||||
*
|
||||
* @return the file extension.
|
||||
*/
|
||||
public String suggestFileExtension() {
|
||||
return packagePart.getPartName().getExtension();
|
||||
return getPackagePart().getPartName().getExtension();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an integer constant that specifies type of this picture
|
||||
*
|
||||
* @return an integer constant that specifies type of this picture
|
||||
* @see Workbook#PICTURE_TYPE_EMF
|
||||
* @see Workbook#PICTURE_TYPE_WMF
|
||||
* @see Workbook#PICTURE_TYPE_PICT
|
||||
* @see Workbook#PICTURE_TYPE_JPEG
|
||||
* @see Workbook#PICTURE_TYPE_PNG
|
||||
* @see Workbook#PICTURE_TYPE_DIB
|
||||
*/
|
||||
public int getPictureType(){
|
||||
String contentType = getPackagePart().getContentType();
|
||||
for (int i = 0; i < RELATIONS.length; i++) {
|
||||
if(RELATIONS[i] == null) continue;
|
||||
|
||||
if(RELATIONS[i].getContentType().equals(contentType)){
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ public final class XSSFRelation<W extends XSSFModel> extends POIXMLRelation {
|
|||
StylesTable.class
|
||||
);
|
||||
public static final XSSFRelation DRAWINGS = new XSSFRelation(
|
||||
"application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
|
||||
"application/vnd.openxmlformats-officedocument.drawing+xml",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
|
||||
"/xl/drawings/drawing#.xml",
|
||||
null
|
||||
|
@ -95,9 +95,10 @@ public final class XSSFRelation<W extends XSSFModel> extends POIXMLRelation {
|
|||
Drawing.class
|
||||
);
|
||||
public static final XSSFRelation IMAGES = new XSSFRelation(
|
||||
"image/x-emf", // TODO
|
||||
//client will substitute $type and $ext with the appropriate values depending on the passed data
|
||||
"image/$type",
|
||||
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
|
||||
"/xl/media/image#.emf",
|
||||
"/xl/media/image#.$ext",
|
||||
null
|
||||
);
|
||||
public static final XSSFRelation<CommentsTable> SHEET_COMMENTS = create(
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/* ====================================================================
|
||||
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.apache.xmlbeans.XmlObject;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTAbsoluteAnchor;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTOneCellAnchor;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.chartDrawing.CTGroupShape;
|
||||
|
||||
/**
|
||||
* Represents a shape in a SpreadsheetML drawing.
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public abstract class XSSFShape {
|
||||
public static final int EMU_PER_POINT = 12700;
|
||||
|
||||
|
||||
/**
|
||||
* Shape container. Can be CTTwoCellAnchor, CTOneCellAnchor, CTAbsoluteAnchor or CTGroupShape
|
||||
*/
|
||||
private XmlObject spContainer;
|
||||
|
||||
/**
|
||||
* Parent drawing
|
||||
*/
|
||||
private XSSFDrawing drawing;
|
||||
|
||||
/**
|
||||
* The parent shape, always not-null for shapes in groups
|
||||
*/
|
||||
private XSSFShape parent;
|
||||
|
||||
/**
|
||||
* Construct a new XSSFSimpleShape object.
|
||||
*
|
||||
* @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){
|
||||
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 parent drawing that owns this shape
|
||||
*/
|
||||
public XSSFDrawing getDrawing(){
|
||||
return drawing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent shape.
|
||||
*/
|
||||
public XSSFShape getParent()
|
||||
{
|
||||
return parent;
|
||||
}
|
||||
|
||||
}
|
|
@ -19,11 +19,7 @@ package org.apache.poi.xssf.usermodel;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import javax.xml.namespace.QName;
|
||||
|
||||
import org.apache.poi.hssf.util.PaneInformation;
|
||||
|
@ -31,7 +27,6 @@ import org.apache.poi.ss.usermodel.CellStyle;
|
|||
import org.apache.poi.ss.usermodel.CommentsSource;
|
||||
import org.apache.poi.ss.usermodel.Footer;
|
||||
import org.apache.poi.ss.usermodel.Header;
|
||||
import org.apache.poi.ss.usermodel.Patriarch;
|
||||
import org.apache.poi.ss.usermodel.PrintSetup;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
|
@ -40,16 +35,18 @@ import org.apache.poi.ss.util.CellReference;
|
|||
import org.apache.poi.ss.util.Region;
|
||||
import org.apache.poi.xssf.model.CommentsTable;
|
||||
import org.apache.poi.xssf.model.Control;
|
||||
import org.apache.poi.xssf.model.Drawing;
|
||||
import org.apache.poi.xssf.usermodel.helpers.ColumnHelper;
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.POIXMLException;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.xmlbeans.XmlOptions;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.openxml4j.opc.PackagePart;
|
||||
import org.openxml4j.opc.PackageRelationship;
|
||||
import org.openxml4j.opc.PackageRelationshipCollection;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
|
||||
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -62,6 +59,8 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
|
|||
* </p>
|
||||
*/
|
||||
public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
||||
private static POILogger logger = POILogFactory.getLogger(XSSFSheet.class);
|
||||
|
||||
protected CTSheet sheet;
|
||||
protected CTWorksheet worksheet;
|
||||
protected CTDialogsheet dialogsheet;
|
||||
|
@ -72,7 +71,6 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
|||
protected CTMergeCells ctMergeCells;
|
||||
|
||||
|
||||
protected List<Drawing> drawings;
|
||||
protected List<Control> controls;
|
||||
|
||||
|
||||
|
@ -149,7 +147,6 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
|||
ctFormat.setDefaultRowHeight(15.0);
|
||||
|
||||
CTSheetView ctView = worksheet.addNewSheetViews().addNewSheetView();
|
||||
ctView.setTabSelected(true);
|
||||
ctView.setWorkbookViewId(0);
|
||||
|
||||
worksheet.addNewDimension().setRef("A1");
|
||||
|
@ -167,11 +164,6 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
|||
return worksheet;
|
||||
}
|
||||
|
||||
public List<Drawing> getDrawings()
|
||||
{
|
||||
return drawings;
|
||||
}
|
||||
|
||||
public List<Control> getControls()
|
||||
{
|
||||
return controls;
|
||||
|
@ -263,9 +255,42 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
|||
columnHelper.setColBestFit(column, true);
|
||||
}
|
||||
|
||||
public Patriarch createDrawingPatriarch() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
/**
|
||||
* Create a new SpreadsheetML drawing. If this sheet already contains a drawing - return that.
|
||||
*
|
||||
* @return a SpreadsheetML drawing
|
||||
*/
|
||||
public XSSFDrawing createDrawingPatriarch() {
|
||||
XSSFDrawing drawing = null;
|
||||
CTDrawing ctDrawing = worksheet.getDrawing();
|
||||
if(ctDrawing == null) {
|
||||
//drawingNumber = #drawings.size() + 1
|
||||
int drawingNumber = getPackagePart().getPackage().getPartsByRelationshipType(XSSFRelation.DRAWINGS.getRelation()).size() + 1;
|
||||
drawing = (XSSFDrawing)createRelationship(XSSFRelation.DRAWINGS, XSSFDrawing.class, drawingNumber);
|
||||
String relId = drawing.getPackageRelationship().getId();
|
||||
|
||||
//add CT_Drawing element which indicates that this sheet contains drawing components built on the drawingML platform.
|
||||
//The relationship Id references the part containing the drawingML definitions.
|
||||
ctDrawing = worksheet.addNewDrawing();
|
||||
ctDrawing.setId(relId);
|
||||
} else {
|
||||
//search the referenced drawing in the list of the sheet's relations
|
||||
for(POIXMLDocumentPart p : getRelations()){
|
||||
if(p instanceof XSSFDrawing) {
|
||||
XSSFDrawing dr = (XSSFDrawing)p;
|
||||
String drId = dr.getPackageRelationship().getId();
|
||||
if(drId.equals(ctDrawing.getId())){
|
||||
drawing = dr;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(drawing == null){
|
||||
logger.log(POILogger.ERROR, "Can't find drawing with id=" + ctDrawing.getId() + " in the list of the sheet's relationships");
|
||||
}
|
||||
}
|
||||
return drawing;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -406,14 +431,16 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
|||
}
|
||||
|
||||
public int getColumnWidth(int columnIndex) {
|
||||
return (int) columnHelper.getColumn(columnIndex, false).getWidth();
|
||||
CTCol col = columnHelper.getColumn(columnIndex, false);
|
||||
return col == null ? getDefaultColumnWidth() : (int)col.getWidth();
|
||||
}
|
||||
public short getColumnWidth(short column) {
|
||||
return (short) getColumnWidth(column & 0xFFFF);
|
||||
}
|
||||
|
||||
public int getDefaultColumnWidth() {
|
||||
return (int)getSheetTypeSheetFormatPr().getDefaultColWidth();
|
||||
CTSheetFormatPr pr = getSheetTypeSheetFormatPr();
|
||||
return pr.isSetDefaultColWidth() ? (int)pr.getDefaultColWidth() : (int)pr.getBaseColWidth();
|
||||
}
|
||||
|
||||
public short getDefaultRowHeight() {
|
||||
|
@ -1570,14 +1597,15 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
|
|||
|
||||
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
|
||||
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorksheet.type.getName().getNamespaceURI(), "worksheet"));
|
||||
|
||||
Map map = new HashMap();
|
||||
map.put(STRelationshipId.type.getName().getNamespaceURI(), "r");
|
||||
xmlOptions.setSaveSuggestedPrefixes(map);
|
||||
|
||||
PackagePart part = getPackagePart();
|
||||
OutputStream out = part.getOutputStream();
|
||||
worksheet.save(out, xmlOptions);
|
||||
out.close();
|
||||
}
|
||||
|
||||
protected void setParent(POIXMLDocumentPart p){
|
||||
this.parent = p;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
/* ====================================================================
|
||||
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.CTTwoCellAnchor;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShapeNonVisual;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.*;
|
||||
|
||||
/**
|
||||
* Represents an auto-shape in a SpreadsheetML drawing.
|
||||
*
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class XSSFSimpleShape extends XSSFShape {
|
||||
|
||||
private CTShape ctShape;
|
||||
|
||||
/**
|
||||
* Construct a new XSSFSimpleShape object.
|
||||
*
|
||||
* @param parent the XSSFDrawing that owns this shape
|
||||
* @param anchor the two cell anchor placeholder for this shape,
|
||||
* this object encloses the shape bean that holds all the shape properties
|
||||
*/
|
||||
protected XSSFSimpleShape(XSSFDrawing parent, CTTwoCellAnchor anchor) {
|
||||
super(parent, anchor);
|
||||
ctShape = anchor.addNewSp();
|
||||
newShape(ctShape);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize default structure of a new auto-shape
|
||||
*
|
||||
* @param shape newly created shape to initialize
|
||||
*/
|
||||
private static void newShape(CTShape shape) {
|
||||
CTShapeNonVisual nv = shape.addNewNvSpPr();
|
||||
CTNonVisualDrawingProps nvp = nv.addNewCNvPr();
|
||||
int shapeId = 1;
|
||||
nvp.setId(shapeId);
|
||||
nvp.setName("Shape " + shapeId);
|
||||
nv.addNewCNvSpPr();
|
||||
|
||||
CTShapeProperties sp = shape.addNewSpPr();
|
||||
CTTransform2D t2d = sp.addNewXfrm();
|
||||
CTPositiveSize2D p1 = t2d.addNewExt();
|
||||
p1.setCx(0);
|
||||
p1.setCy(0);
|
||||
CTPoint2D p2 = t2d.addNewOff();
|
||||
p2.setX(0);
|
||||
p2.setY(0);
|
||||
|
||||
CTPresetGeometry2D geom = sp.addNewPrstGeom();
|
||||
geom.setPrst(STShapeType.RECT);
|
||||
geom.addNewAvLst();
|
||||
|
||||
CTShapeStyle style = shape.addNewStyle();
|
||||
CTSchemeColor scheme = style.addNewLnRef().addNewSchemeClr();
|
||||
scheme.setVal(STSchemeColorVal.ACCENT_1);
|
||||
scheme.addNewShade().setVal(50000);
|
||||
style.getLnRef().setIdx(2);
|
||||
|
||||
CTStyleMatrixReference fillref = style.addNewFillRef();
|
||||
fillref.setIdx(1);
|
||||
fillref.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);
|
||||
|
||||
CTStyleMatrixReference effectRef = style.addNewEffectRef();
|
||||
effectRef.setIdx(0);
|
||||
effectRef.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_1);
|
||||
|
||||
CTFontReference fontRef = style.addNewFontRef();
|
||||
fontRef.setIdx(STFontCollectionIndex.MINOR);
|
||||
fontRef.addNewSchemeClr().setVal(STSchemeColorVal.LT_1);
|
||||
|
||||
CTTextBody body = shape.addNewTxBody();
|
||||
CTTextBodyProperties bodypr = body.addNewBodyPr();
|
||||
bodypr.setAnchor(STTextAnchoringType.CTR);
|
||||
bodypr.setRtlCol(false);
|
||||
CTTextParagraph p = body.addNewP();
|
||||
p.addNewPPr().setAlgn(STTextAlignType.CTR);
|
||||
|
||||
body.addNewLstStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the shape type, one of the constants defined in {@link ShapeTypes}.
|
||||
*
|
||||
* @return the shape type
|
||||
* @see 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 ShapeTypes}.
|
||||
* @see ShapeTypes
|
||||
*/
|
||||
public void setShapeType(int type) {
|
||||
ctShape.getSpPr().getPrstGeom().setPrst(STShapeType.Enum.forInt(type));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Whether this shape is not filled with a color
|
||||
*
|
||||
* @return true if this shape is not filled with a color.
|
||||
*/
|
||||
public boolean isNoFill() {
|
||||
return ctShape.getSpPr().isSetNoFill();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
}
|
||||
|
||||
}
|
|
@ -19,10 +19,9 @@ package org.apache.poi.xssf.usermodel;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.io.InputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.util.*;
|
||||
import javax.xml.namespace.QName;
|
||||
import org.apache.poi.POIXMLDocument;
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
|
@ -35,6 +34,7 @@ import org.apache.poi.ss.usermodel.Row.MissingCellPolicy;
|
|||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
import org.apache.poi.util.PackageHelper;
|
||||
import org.apache.poi.util.IOUtils;
|
||||
import org.apache.poi.xssf.model.*;
|
||||
import org.apache.poi.POIXMLException;
|
||||
import org.apache.xmlbeans.XmlObject;
|
||||
|
@ -44,6 +44,7 @@ import org.openxml4j.exceptions.OpenXML4JException;
|
|||
import org.openxml4j.opc.*;
|
||||
import org.openxml4j.opc.Package;
|
||||
import org.openxmlformats.schemas.spreadsheetml.x2006.main.*;
|
||||
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
|
||||
|
||||
/**
|
||||
* High level representation of a SpreadsheetML workbook. This is the first object most users
|
||||
|
@ -93,6 +94,11 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
|||
*/
|
||||
private MissingCellPolicy missingCellPolicy = Row.RETURN_NULL_AND_BLANK;
|
||||
|
||||
/**
|
||||
* array of pictures for this workbook
|
||||
*/
|
||||
private List<XSSFPictureData> pictures;
|
||||
|
||||
private static POILogger log = POILogFactory.getLogger(XSSFWorkbook.class);
|
||||
|
||||
/**
|
||||
|
@ -250,9 +256,33 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
|||
return this.workbook;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a picture to the workbook.
|
||||
*
|
||||
* @param pictureData The bytes of the picture
|
||||
* @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(byte[] pictureData, int format) {
|
||||
// TODO Auto-generated method stub
|
||||
return 0;
|
||||
int imageNumber = getAllPictures().size() + 1;
|
||||
XSSFPictureData img = (XSSFPictureData)createRelationship(XSSFPictureData.RELATIONS[format], XSSFPictureData.class, imageNumber, true);
|
||||
try {
|
||||
OutputStream out = img.getPackagePart().getOutputStream();
|
||||
out.write(pictureData);
|
||||
out.close();
|
||||
} catch (IOException e){
|
||||
throw new POIXMLException(e);
|
||||
}
|
||||
pictures.add(img);
|
||||
return imageNumber - 1;
|
||||
}
|
||||
|
||||
public XSSFSheet cloneSheet(int sheetNum) {
|
||||
|
@ -363,13 +393,12 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
|||
|
||||
int sheetNumber = getNumberOfSheets() + 1;
|
||||
XSSFSheet wrapper = (XSSFSheet)createRelationship(XSSFRelation.WORKSHEET, XSSFSheet.class, sheetNumber);
|
||||
wrapper.setParent(this);
|
||||
|
||||
CTSheet sheet = addSheet(sheetname);
|
||||
wrapper.sheet = sheet;
|
||||
sheet.setId(wrapper.getPackageRelationship().getId());
|
||||
sheet.setSheetId(sheetNumber);
|
||||
|
||||
if(sheets.size() == 0) wrapper.setSelected(true);
|
||||
this.sheets.add(wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
@ -438,27 +467,21 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
|||
*
|
||||
* @return the list of pictures (a list of {@link XSSFPictureData} objects.)
|
||||
*/
|
||||
public List<PictureData> getAllPictures() {
|
||||
// In OOXML pictures are referred to in sheets
|
||||
List<PictureData> pictures = new LinkedList<PictureData>();
|
||||
for(POIXMLDocumentPart p : getRelations()){
|
||||
if (p instanceof XSSFSheet) {
|
||||
PackagePart sheetPart = p.getPackagePart();
|
||||
try {
|
||||
PackageRelationshipCollection prc = sheetPart.getRelationshipsByType(XSSFRelation.DRAWINGS.getRelation());
|
||||
for (PackageRelationship rel : prc) {
|
||||
PackagePart drawingPart = getTargetPart(rel);
|
||||
PackageRelationshipCollection prc2 = drawingPart.getRelationshipsByType(XSSFRelation.IMAGES.getRelation());
|
||||
for (PackageRelationship rel2 : prc2) {
|
||||
PackagePart imagePart = getTargetPart(rel2);
|
||||
XSSFPictureData pd = new XSSFPictureData(imagePart);
|
||||
pictures.add(pd);
|
||||
public List<XSSFPictureData> getAllPictures() {
|
||||
if(pictures == null) {
|
||||
//In OOXML pictures are referred to in sheets,
|
||||
//dive into sheet's relations, select drawings and their images
|
||||
pictures = new ArrayList();
|
||||
for(XSSFSheet sh : sheets){
|
||||
for(POIXMLDocumentPart dr : sh.getRelations()){
|
||||
if(dr instanceof XSSFDrawing){
|
||||
for(POIXMLDocumentPart img : dr.getRelations()){
|
||||
if(img instanceof XSSFPictureData){
|
||||
pictures.add((XSSFPictureData)img);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (InvalidFormatException e) {
|
||||
throw new POIXMLException(e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return pictures;
|
||||
|
@ -705,7 +728,7 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
|||
*/
|
||||
public void removeSheetAt(int index) {
|
||||
validateSheetIndex(index);
|
||||
|
||||
|
||||
this.sheets.remove(index);
|
||||
this.workbook.getSheets().removeSheet(index);
|
||||
}
|
||||
|
@ -878,6 +901,10 @@ public class XSSFWorkbook extends POIXMLDocument implements Workbook, Iterable<X
|
|||
|
||||
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
|
||||
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTWorkbook.type.getName().getNamespaceURI(), "workbook"));
|
||||
Map map = new HashMap();
|
||||
map.put(STRelationshipId.type.getName().getNamespaceURI(), "r");
|
||||
xmlOptions.setSaveSuggestedPrefixes(map);
|
||||
|
||||
PackagePart part = getPackagePart();
|
||||
OutputStream out = part.getOutputStream();
|
||||
workbook.save(out, xmlOptions);
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.apache.poi.ss.usermodel.PictureData;
|
|||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFPictureData;
|
||||
|
||||
|
||||
public class TestLoadSaveXSSF extends TestCase {
|
||||
|
@ -42,7 +43,7 @@ public class TestLoadSaveXSSF extends TestCase {
|
|||
filename = "src/ooxml/testcases/org/apache/poi/xssf/data";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testLoadSample() throws Exception {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook(new File(filename, "sample.xlsx").getAbsolutePath());
|
||||
assertEquals(3, workbook.getNumberOfSheets());
|
||||
|
@ -55,7 +56,7 @@ public class TestLoadSaveXSSF extends TestCase {
|
|||
cell = row.getCell((short) 0);
|
||||
assertEquals("Lorem", cell.getRichStringCellValue().getString());
|
||||
}
|
||||
|
||||
|
||||
// TODO filename string hard coded in XSSFWorkbook constructor in order to make ant test-ooxml target be successfull.
|
||||
public void testLoadStyles() throws Exception {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook(new File(filename, "styles.xlsx").getAbsolutePath());
|
||||
|
@ -69,7 +70,7 @@ public class TestLoadSaveXSSF extends TestCase {
|
|||
// TODO filename string hard coded in XSSFWorkbook constructor in order to make ant test-ooxml target be successfull.
|
||||
public void testLoadPictures() throws Exception {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook(new File(filename, "picture.xlsx").getAbsolutePath());
|
||||
List<PictureData> pictures = workbook.getAllPictures();
|
||||
List<XSSFPictureData> pictures = workbook.getAllPictures();
|
||||
assertEquals(1, pictures.size());
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
/* ====================================================================
|
||||
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 junit.framework.TestCase;
|
||||
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTDrawing;
|
||||
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class TestXSSFDrawing extends TestCase {
|
||||
public void testRead(){
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx");
|
||||
XSSFSheet sheet = wb.getSheetAt(0);
|
||||
//the sheet has one relationship and it is XSSFDrawing
|
||||
List<POIXMLDocumentPart> rels = sheet.getRelations();
|
||||
assertEquals(1, rels.size());
|
||||
assertTrue(rels.get(0) instanceof XSSFDrawing);
|
||||
|
||||
XSSFDrawing drawing = (XSSFDrawing)rels.get(0);
|
||||
//sheet.createDrawingPatriarch() should return the same instance of XSSFDrawing
|
||||
assertSame(drawing, sheet.createDrawingPatriarch());
|
||||
String drawingId = drawing.getPackageRelationship().getId();
|
||||
|
||||
//there should be a relation to this drawing in the worksheet
|
||||
assertTrue(sheet.getWorksheet().isSetDrawing());
|
||||
assertEquals(drawingId, sheet.getWorksheet().getDrawing().getId());
|
||||
|
||||
}
|
||||
|
||||
public void testNew(){
|
||||
XSSFWorkbook wb = new XSSFWorkbook();
|
||||
XSSFSheet sheet = wb.createSheet();
|
||||
//multiple calls of createDrawingPatriarch should return the same instance of XSSFDrawing
|
||||
XSSFDrawing dr1 = sheet.createDrawingPatriarch();
|
||||
XSSFDrawing dr2 = sheet.createDrawingPatriarch();
|
||||
assertSame(dr1, dr2);
|
||||
|
||||
List<POIXMLDocumentPart> rels = sheet.getRelations();
|
||||
assertEquals(1, rels.size());
|
||||
assertTrue(rels.get(0) instanceof XSSFDrawing);
|
||||
|
||||
XSSFDrawing drawing = (XSSFDrawing)rels.get(0);
|
||||
String drawingId = drawing.getPackageRelationship().getId();
|
||||
|
||||
//there should be a relation to this drawing in the worksheet
|
||||
assertTrue(sheet.getWorksheet().isSetDrawing());
|
||||
assertEquals(drawingId, sheet.getWorksheet().getDrawing().getId());
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/* ====================================================================
|
||||
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 junit.framework.TestCase;
|
||||
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTDrawing;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class TestXSSFPicture extends TestCase {
|
||||
|
||||
public void testCreate(){
|
||||
XSSFWorkbook wb = new XSSFWorkbook();
|
||||
XSSFSheet sheet = wb.createSheet();
|
||||
XSSFDrawing drawing = sheet.createDrawingPatriarch();
|
||||
|
||||
byte[] jpegData = "test jpeg data".getBytes();
|
||||
|
||||
List<XSSFPictureData> pictures = wb.getAllPictures();
|
||||
assertEquals(0, pictures.size());
|
||||
|
||||
int jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG);
|
||||
assertEquals(1, pictures.size());
|
||||
assertEquals("jpeg", pictures.get(jpegIdx).suggestFileExtension());
|
||||
assertTrue(Arrays.equals(jpegData, pictures.get(jpegIdx).getData()));
|
||||
|
||||
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 10, 30);
|
||||
XSSFPicture shape = drawing.createPicture(anchor, jpegIdx);
|
||||
assertTrue(anchor.equals(shape.getAnchor()));
|
||||
assertNotNull(shape.getPictureData());
|
||||
assertTrue(Arrays.equals(jpegData, shape.getPictureData().getData()));
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/* ====================================================================
|
||||
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 junit.framework.TestCase;
|
||||
import org.apache.poi.xssf.XSSFTestDataSamples;
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTDrawing;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author Yegor Kozlov
|
||||
*/
|
||||
public class TestXSSFPictureData extends TestCase {
|
||||
public void testRead(){
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithDrawing.xlsx");
|
||||
List<XSSFPictureData> pictures = wb.getAllPictures();
|
||||
//wb.getAllPictures() should return the same instance across multiple calls
|
||||
assertSame(pictures, wb.getAllPictures());
|
||||
|
||||
assertEquals(5, pictures.size());
|
||||
String[] ext = {"jpeg", "emf", "png", "emf", "wmf"};
|
||||
for (int i = 0; i < pictures.size(); i++) {
|
||||
assertEquals(ext[i], pictures.get(i).suggestFileExtension());
|
||||
}
|
||||
|
||||
int num = pictures.size();
|
||||
|
||||
byte[] pictureData = {0xA, 0xB, 0XC, 0xD, 0xE, 0xF};
|
||||
|
||||
int idx = wb.addPicture(pictureData, XSSFWorkbook.PICTURE_TYPE_JPEG);
|
||||
assertEquals(num + 1, pictures.size());
|
||||
//idx is 0-based index in the #pictures array
|
||||
assertEquals(pictures.size() - 1, idx);
|
||||
XSSFPictureData pict = pictures.get(idx);
|
||||
assertEquals("jpeg", pict.suggestFileExtension());
|
||||
assertTrue(Arrays.equals(pictureData, pict.getData()));
|
||||
}
|
||||
|
||||
public void testNew(){
|
||||
XSSFWorkbook wb = new XSSFWorkbook();
|
||||
XSSFSheet sheet = wb.createSheet();
|
||||
XSSFDrawing drawing = sheet.createDrawingPatriarch();
|
||||
|
||||
byte[] jpegData = "test jpeg data".getBytes();
|
||||
byte[] wmfData = "test wmf data".getBytes();
|
||||
byte[] pngData = "test png data".getBytes();
|
||||
|
||||
List<XSSFPictureData> pictures = wb.getAllPictures();
|
||||
assertEquals(0, pictures.size());
|
||||
|
||||
int jpegIdx = wb.addPicture(jpegData, XSSFWorkbook.PICTURE_TYPE_JPEG);
|
||||
assertEquals(1, pictures.size());
|
||||
assertEquals("jpeg", pictures.get(jpegIdx).suggestFileExtension());
|
||||
assertTrue(Arrays.equals(jpegData, pictures.get(jpegIdx).getData()));
|
||||
|
||||
int wmfIdx = wb.addPicture(wmfData, XSSFWorkbook.PICTURE_TYPE_WMF);
|
||||
assertEquals(2, pictures.size());
|
||||
assertEquals("wmf", pictures.get(wmfIdx).suggestFileExtension());
|
||||
assertTrue(Arrays.equals(wmfData, pictures.get(wmfIdx).getData()));
|
||||
|
||||
int pngIdx = wb.addPicture(pngData, XSSFWorkbook.PICTURE_TYPE_PNG);
|
||||
assertEquals(3, pictures.size());
|
||||
assertEquals("png", pictures.get(pngIdx).suggestFileExtension());
|
||||
assertTrue(Arrays.equals(pngData, pictures.get(pngIdx).getData()));
|
||||
|
||||
//TODO finish usermodel API for XSSFPicture
|
||||
XSSFPicture p1 = drawing.createPicture(new XSSFClientAnchor(), jpegIdx);
|
||||
XSSFPicture p2 = drawing.createPicture(new XSSFClientAnchor(), wmfIdx);
|
||||
XSSFPicture p3 = drawing.createPicture(new XSSFClientAnchor(), pngIdx);
|
||||
|
||||
//check that the added pictures are accessible after write
|
||||
wb = XSSFTestDataSamples.writeOutAndReadBack(wb);
|
||||
List<XSSFPictureData> pictures2 = wb.getAllPictures();
|
||||
assertEquals(3, pictures2.size());
|
||||
|
||||
assertEquals("jpeg", pictures2.get(jpegIdx).suggestFileExtension());
|
||||
assertTrue(Arrays.equals(jpegData, pictures2.get(jpegIdx).getData()));
|
||||
|
||||
assertEquals("wmf", pictures2.get(wmfIdx).suggestFileExtension());
|
||||
assertTrue(Arrays.equals(wmfData, pictures2.get(wmfIdx).getData()));
|
||||
|
||||
assertEquals("png", pictures2.get(pngIdx).suggestFileExtension());
|
||||
assertTrue(Arrays.equals(pngData, pictures2.get(pngIdx).getData()));
|
||||
|
||||
}
|
||||
}
|
|
@ -41,7 +41,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.STPane;
|
|||
|
||||
|
||||
public class TestXSSFSheet extends TestCase {
|
||||
|
||||
|
||||
public void testRowIterator() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -55,7 +55,7 @@ public class TestXSSFSheet extends TestCase {
|
|||
assertEquals(row2, it.next());
|
||||
assertFalse(it.hasNext());
|
||||
}
|
||||
|
||||
|
||||
public void testGetRow() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -63,17 +63,17 @@ public class TestXSSFSheet extends TestCase {
|
|||
Cell cell = row1.createCell((short) 0);
|
||||
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
|
||||
cell.setCellValue((double) 1000);
|
||||
|
||||
|
||||
// Test getting a row and check its cell's value
|
||||
Row row_got = sheet.getRow(0);
|
||||
Cell cell_got = row_got.getCell((short) 0);
|
||||
assertEquals((double) 1000, cell_got.getNumericCellValue());
|
||||
}
|
||||
|
||||
|
||||
public void testCreateRow() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
||||
|
||||
// Test row creation with consecutive indexes
|
||||
Row row1 = sheet.createRow(0);
|
||||
Row row2 = sheet.createRow(1);
|
||||
|
@ -84,11 +84,11 @@ public class TestXSSFSheet extends TestCase {
|
|||
assertEquals(row1, it.next());
|
||||
assertTrue(it.hasNext());
|
||||
assertEquals(row2, it.next());
|
||||
|
||||
|
||||
// Test row creation with non consecutive index
|
||||
Row row101 = sheet.createRow(100);
|
||||
assertNotNull(row101);
|
||||
|
||||
|
||||
// Test overwriting an existing row
|
||||
Row row2_ovrewritten = sheet.createRow(1);
|
||||
Cell cell = row2_ovrewritten.createCell((short) 0);
|
||||
|
@ -102,7 +102,7 @@ public class TestXSSFSheet extends TestCase {
|
|||
assertEquals(row2_ovrewritten, row2_overwritten_copy);
|
||||
assertEquals(row2_overwritten_copy.getCell((short) 0).getNumericCellValue(), (double) 100);
|
||||
}
|
||||
|
||||
|
||||
public void testRemoveRow() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -114,7 +114,7 @@ public class TestXSSFSheet extends TestCase {
|
|||
assertNull(sheet.getRow(2));
|
||||
assertNotNull(sheet.getRow(1));
|
||||
}
|
||||
|
||||
|
||||
public void testGetSetDefaultRowHeight() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -131,17 +131,17 @@ public class TestXSSFSheet extends TestCase {
|
|||
sheet.setDefaultRowHeightInPoints((short) 17);
|
||||
assertEquals((short) 340, sheet.getDefaultRowHeight());
|
||||
}
|
||||
|
||||
|
||||
public void testGetSetDefaultColumnWidth() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
// Test that default column width set by the constructor
|
||||
assertEquals((short) 0, sheet.getDefaultColumnWidth());
|
||||
assertEquals((short) 8, sheet.getDefaultColumnWidth());
|
||||
// Set a new default column width and get its value
|
||||
sheet.setDefaultColumnWidth((short) 14);
|
||||
assertEquals((short) 14, sheet.getDefaultColumnWidth());
|
||||
}
|
||||
|
||||
|
||||
public void testGetFirstLastRowNum() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -149,9 +149,9 @@ public class TestXSSFSheet extends TestCase {
|
|||
Row row1 = sheet.createRow(0);
|
||||
Row row2 = sheet.createRow(1);
|
||||
assertEquals(0, sheet.getFirstRowNum());
|
||||
assertEquals(9, sheet.getLastRowNum());
|
||||
assertEquals(9, sheet.getLastRowNum());
|
||||
}
|
||||
|
||||
|
||||
public void testGetPhysicalNumberOfRows() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -160,7 +160,7 @@ public class TestXSSFSheet extends TestCase {
|
|||
Row row2 = sheet.createRow(1);
|
||||
assertEquals(3, sheet.getPhysicalNumberOfRows());
|
||||
}
|
||||
|
||||
|
||||
public void testGetSetRowBreaks() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -173,7 +173,7 @@ public class TestXSSFSheet extends TestCase {
|
|||
sheet.setRowBreak(1);
|
||||
assertEquals(2, sheet.getRowBreaks().length);
|
||||
}
|
||||
|
||||
|
||||
public void testRemoveRowBreak() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -184,7 +184,7 @@ public class TestXSSFSheet extends TestCase {
|
|||
sheet.removeRowBreak(1);
|
||||
assertEquals(1, sheet.getRowBreaks().length);
|
||||
}
|
||||
|
||||
|
||||
public void testGetSetColumnBreaks() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -195,7 +195,7 @@ public class TestXSSFSheet extends TestCase {
|
|||
sheet.setColumnBreak((short) 11223);
|
||||
assertEquals(2, sheet.getColumnBreaks().length);
|
||||
}
|
||||
|
||||
|
||||
public void testRemoveColumnBreak() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -209,7 +209,7 @@ public class TestXSSFSheet extends TestCase {
|
|||
sheet.removeColumnBreak((short) 15);
|
||||
assertEquals(1, sheet.getColumnBreaks().length);
|
||||
}
|
||||
|
||||
|
||||
public void testIsRowColumnBroken() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -220,7 +220,7 @@ public class TestXSSFSheet extends TestCase {
|
|||
sheet.setColumnBreak((short) 3);
|
||||
assertTrue(sheet.isColumnBroken((short) 3));
|
||||
}
|
||||
|
||||
|
||||
public void testGetSetAutoBreaks() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -228,7 +228,7 @@ public class TestXSSFSheet extends TestCase {
|
|||
sheet.setAutobreaks(false);
|
||||
assertFalse(sheet.getAutobreaks());
|
||||
}
|
||||
|
||||
|
||||
public void testIsSetFitToPage() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -238,7 +238,7 @@ public class TestXSSFSheet extends TestCase {
|
|||
sheet.setFitToPage(false);
|
||||
assertFalse(sheet.getFitToPage());
|
||||
}
|
||||
|
||||
|
||||
public void testGetSetMargin() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
@ -270,7 +270,7 @@ public class TestXSSFSheet extends TestCase {
|
|||
assertEquals((double) 14, sheet.getMargin((short) 5));
|
||||
sheet.setMargin((short) 5, 15);
|
||||
assertEquals((double) 15, sheet.getMargin((short) 5));
|
||||
|
||||
|
||||
// Test that nothing happens if another margin constant is given (E.G. 65)
|
||||
sheet.setMargin((short) 65, 15);
|
||||
assertEquals((double) 10, sheet.getMargin((short) 0));
|
||||
|
@ -280,83 +280,83 @@ public class TestXSSFSheet extends TestCase {
|
|||
assertEquals((double) 14, sheet.getMargin((short) 4));
|
||||
assertEquals((double) 15, sheet.getMargin((short) 5));
|
||||
}
|
||||
|
||||
|
||||
public void testGetFooter() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
XSSFSheet sheet = (XSSFSheet)workbook.createSheet("Sheet 1");
|
||||
assertNotNull(sheet.getFooter());
|
||||
sheet.getFooter().setCenter("test center footer");
|
||||
assertEquals("test center footer", sheet.getFooter().getCenter());
|
||||
|
||||
|
||||
// Default is odd footer
|
||||
assertNotNull(sheet.getOddFooter());
|
||||
assertEquals("test center footer", sheet.getOddFooter().getCenter());
|
||||
}
|
||||
|
||||
|
||||
public void testExistingHeaderFooter() throws Exception {
|
||||
File xml = new File(
|
||||
System.getProperty("HSSF.testdata.path") +
|
||||
File.separator + "45540_classic_Header.xlsx"
|
||||
);
|
||||
assertTrue(xml.exists());
|
||||
|
||||
|
||||
XSSFWorkbook workbook = new XSSFWorkbook(xml.toString());
|
||||
XSSFOddHeader hdr;
|
||||
XSSFOddFooter ftr;
|
||||
|
||||
|
||||
// Sheet 1 has a header with center and right text
|
||||
XSSFSheet s1 = (XSSFSheet)workbook.getSheetAt(0);
|
||||
assertNotNull(s1.getHeader());
|
||||
assertNotNull(s1.getFooter());
|
||||
hdr = (XSSFOddHeader)s1.getHeader();
|
||||
ftr = (XSSFOddFooter)s1.getFooter();
|
||||
|
||||
hdr = (XSSFOddHeader)s1.getHeader();
|
||||
ftr = (XSSFOddFooter)s1.getFooter();
|
||||
|
||||
assertEquals("&Ctestdoc&Rtest phrase", hdr.getText());
|
||||
assertEquals(null, ftr.getText());
|
||||
|
||||
|
||||
assertEquals("", hdr.getLeft());
|
||||
assertEquals("testdoc", hdr.getCenter());
|
||||
assertEquals("test phrase", hdr.getRight());
|
||||
|
||||
|
||||
assertEquals("", ftr.getLeft());
|
||||
assertEquals("", ftr.getCenter());
|
||||
assertEquals("", ftr.getRight());
|
||||
|
||||
|
||||
|
||||
|
||||
// Sheet 2 has a footer, but it's empty
|
||||
XSSFSheet s2 = (XSSFSheet)workbook.getSheetAt(1);
|
||||
assertNotNull(s2.getHeader());
|
||||
assertNotNull(s2.getFooter());
|
||||
hdr = (XSSFOddHeader)s2.getHeader();
|
||||
ftr = (XSSFOddFooter)s2.getFooter();
|
||||
|
||||
hdr = (XSSFOddHeader)s2.getHeader();
|
||||
ftr = (XSSFOddFooter)s2.getFooter();
|
||||
|
||||
assertEquals(null, hdr.getText());
|
||||
assertEquals("&L&F", ftr.getText());
|
||||
|
||||
|
||||
assertEquals("", hdr.getLeft());
|
||||
assertEquals("", hdr.getCenter());
|
||||
assertEquals("", hdr.getRight());
|
||||
|
||||
|
||||
assertEquals("&F", ftr.getLeft());
|
||||
assertEquals("", ftr.getCenter());
|
||||
assertEquals("", ftr.getRight());
|
||||
|
||||
|
||||
|
||||
|
||||
// Save and reload
|
||||
XSSFWorkbook wb = XSSFTestDataSamples.writeOutAndReadBack(workbook);
|
||||
|
||||
|
||||
hdr = (XSSFOddHeader)wb.getSheetAt(0).getHeader();
|
||||
ftr = (XSSFOddFooter)wb.getSheetAt(0).getFooter();
|
||||
|
||||
ftr = (XSSFOddFooter)wb.getSheetAt(0).getFooter();
|
||||
|
||||
assertEquals("", hdr.getLeft());
|
||||
assertEquals("testdoc", hdr.getCenter());
|
||||
assertEquals("test phrase", hdr.getRight());
|
||||
|
||||
|
||||
assertEquals("", ftr.getLeft());
|
||||
assertEquals("", ftr.getCenter());
|
||||
assertEquals("", ftr.getRight());
|
||||
}
|
||||
|
||||
|
||||
public void testGetAllHeadersFooters() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
XSSFSheet sheet = (XSSFSheet) workbook.createSheet("Sheet 1");
|
||||
|
@ -366,27 +366,27 @@ public class TestXSSFSheet extends TestCase {
|
|||
assertNotNull(sheet.getOddHeader());
|
||||
assertNotNull(sheet.getEvenHeader());
|
||||
assertNotNull(sheet.getFirstHeader());
|
||||
|
||||
|
||||
assertEquals("", sheet.getOddFooter().getLeft());
|
||||
sheet.getOddFooter().setLeft("odd footer left");
|
||||
assertEquals("odd footer left", sheet.getOddFooter().getLeft());
|
||||
|
||||
|
||||
assertEquals("", sheet.getEvenFooter().getLeft());
|
||||
sheet.getEvenFooter().setLeft("even footer left");
|
||||
assertEquals("even footer left", sheet.getEvenFooter().getLeft());
|
||||
|
||||
|
||||
assertEquals("", sheet.getFirstFooter().getLeft());
|
||||
sheet.getFirstFooter().setLeft("first footer left");
|
||||
assertEquals("first footer left", sheet.getFirstFooter().getLeft());
|
||||
|
||||
|
||||
assertEquals("", sheet.getOddHeader().getLeft());
|
||||
sheet.getOddHeader().setLeft("odd header left");
|
||||
assertEquals("odd header left", sheet.getOddHeader().getLeft());
|
||||
|
||||
|
||||
assertEquals("", sheet.getOddHeader().getRight());
|
||||
sheet.getOddHeader().setRight("odd header right");
|
||||
assertEquals("odd header right", sheet.getOddHeader().getRight());
|
||||
|
||||
|
||||
assertEquals("", sheet.getOddHeader().getCenter());
|
||||
sheet.getOddHeader().setCenter("odd header center");
|
||||
assertEquals("odd header center", sheet.getOddHeader().getCenter());
|
||||
|
@ -395,49 +395,49 @@ public class TestXSSFSheet extends TestCase {
|
|||
assertEquals("odd footer left", sheet.getFooter().getLeft());
|
||||
assertEquals("odd header center", sheet.getHeader().getCenter());
|
||||
}
|
||||
|
||||
|
||||
public void testGetSetColumnWidth() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
sheet.setColumnWidth((short) 1,(short) 22);
|
||||
assertEquals(22, sheet.getColumnWidth((short) 1));
|
||||
|
||||
|
||||
// Now check the low level stuff, and check that's all
|
||||
// been set correctly
|
||||
XSSFSheet xs = (XSSFSheet)sheet;
|
||||
CTWorksheet cts = xs.getWorksheet();
|
||||
|
||||
|
||||
CTCols[] cols_s = cts.getColsArray();
|
||||
assertEquals(1, cols_s.length);
|
||||
CTCols cols = cols_s[0];
|
||||
assertEquals(1, cols.sizeOfColArray());
|
||||
CTCol col = cols.getColArray(0);
|
||||
|
||||
|
||||
// XML is 1 based, POI is 0 based
|
||||
assertEquals(2, col.getMin());
|
||||
assertEquals(2, col.getMax());
|
||||
assertEquals(22.0, col.getWidth());
|
||||
|
||||
|
||||
|
||||
|
||||
// Now set another
|
||||
sheet.setColumnWidth((short) 3,(short) 33);
|
||||
|
||||
|
||||
cols_s = cts.getColsArray();
|
||||
assertEquals(1, cols_s.length);
|
||||
cols = cols_s[0];
|
||||
assertEquals(2, cols.sizeOfColArray());
|
||||
|
||||
|
||||
col = cols.getColArray(0);
|
||||
assertEquals(2, col.getMin()); // POI 1
|
||||
assertEquals(2, col.getMax());
|
||||
assertEquals(22.0, col.getWidth());
|
||||
|
||||
|
||||
col = cols.getColArray(1);
|
||||
assertEquals(4, col.getMin()); // POI 3
|
||||
assertEquals(4, col.getMax());
|
||||
assertEquals(33.0, col.getWidth());
|
||||
}
|
||||
|
||||
|
||||
public void testGetSetColumnHidden() {
|
||||
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("Sheet 1");
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue