git-svn-id: https://svn.apache.org/repos/asf/poi/branches/ooxml@703490 13f79535-47bb-0310-9956-ffa450edef68tags/ooxml_20081107
@@ -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; | |||
/** | |||
* 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); | |||
} | |||
public void writeTo(OutputStream out) throws IOException { | |||
IOUtils.copy(packagePart.getInputStream(), out); | |||
} | |||
/** | |||
* 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"); |