<changes>
<release version="3.8-beta3" date="2011-??-??">
+ <action dev="poi-developers" type="add">Initial support for XSSF Charts. Provides easy access to the underlying CTChart object via the Sheet Drawing, but no high level interface onto the chart contents as yet.</action>
<action dev="poi-developers" type="fix">50884 - XSSF and HSSF freeze panes now behave the same</action>
<action dev="poi-developers" type="add">Support for adding a table to a XSSFSheet</action>
<action dev="poi-developers" type="add">Improve HSMF MAPIMessage access to the HTML and RTF versions of the message body (where available)</action>
--- /dev/null
+/* ====================================================================
+ 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 java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.util.Internal;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlObject;
+import org.apache.xmlbeans.XmlOptions;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace;
+import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle;
+import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument;
+import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+/**
+ * Represents a SpreadsheetML Chart
+ */
+public final class XSSFChart extends POIXMLDocumentPart {
+ /**
+ * Root element of the SpreadsheetML Chart part
+ */
+ private CTChartSpace chartSpace;
+ /**
+ * The Chart within that
+ */
+ private CTChart chart;
+
+ /**
+ * Create a new SpreadsheetML chart
+ */
+ protected XSSFChart() {
+ super();
+ createChart();
+ }
+
+ /**
+ * Construct a SpreadsheetML chart from a package part
+ *
+ * @param part the package part holding the chart data,
+ * the content type must be <code>application/vnd.openxmlformats-officedocument.drawingml.chart+xml</code>
+ * @param rel the package relationship holding this chart,
+ * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart
+ */
+ protected XSSFChart(PackagePart part, PackageRelationship rel) throws IOException, XmlException {
+ super(part, rel);
+
+ chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream()).getChartSpace();
+ chart = chartSpace.getChart();
+ }
+
+ /**
+ * Construct a new CTChartSpace bean. By default, it's just an empty placeholder for chart objects
+ *
+ * @return a new CTChartSpace bean
+ */
+ private void createChart() {
+ chartSpace = CTChartSpace.Factory.newInstance();
+ chart = chartSpace.addNewChart();
+ }
+
+ /**
+ * Return the underlying CTChartSpace bean, the root element of the SpreadsheetML Chart part.
+ *
+ * @return the underlying CTChartSpace bean
+ */
+ @Internal
+ public CTChartSpace getCTChartSpace(){
+ return chartSpace;
+ }
+
+ /**
+ * Return the underlying CTChart bean, within the Chart Space
+ *
+ * @return the underlying CTChart bean
+ */
+ @Internal
+ public CTChart getCTChart(){
+ return chart;
+ }
+
+ @Override
+ protected void commit() throws IOException {
+ XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+
+ Map<String, String> map = new HashMap<String, String>();
+ map.put(XSSFDrawing.NAMESPACE_A, "a");
+ map.put(STRelationshipId.type.getName().getNamespaceURI(), "r");
+ xmlOptions.setSaveSuggestedPrefixes(map);
+
+ PackagePart part = getPackagePart();
+ OutputStream out = part.getOutputStream();
+ chartSpace.save(out, xmlOptions);
+ out.close();
+ }
+
+ /**
+ * Returns the title, or null if none is set
+ */
+ public XSSFRichTextString getTitle() {
+ if(! chart.isSetTitle()) {
+ return null;
+ }
+
+ // TODO Do properly
+ CTTitle title = chart.getTitle();
+
+ StringBuffer text = new StringBuffer();
+ XmlObject[] t = title
+ .selectPath("declare namespace a='"+XSSFDrawing.NAMESPACE_A+"' .//a:t");
+ for (int m = 0; m < t.length; m++) {
+ NodeList kids = t[m].getDomNode().getChildNodes();
+ for (int n = 0; n < kids.getLength(); n++) {
+ if (kids.item(n) instanceof Text) {
+ text.append(kids.item(n).getNodeValue());
+ }
+ }
+ }
+
+ return new XSSFRichTextString(text.toString());
+ }
+
+}
import java.io.IOException;
import java.io.OutputStream;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.xml.namespace.QName;
import org.apache.poi.POIXMLDocumentPart;
-import org.apache.poi.util.Internal;
-import org.apache.poi.xssf.model.CommentsTable;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Drawing;
+import org.apache.poi.util.Internal;
+import org.apache.poi.xssf.model.CommentsTable;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTConnector;
*/
private CTDrawing drawing;
private boolean isNew;
+
+ protected static final String NAMESPACE_A = "http://schemas.openxmlformats.org/drawingml/2006/main";
/**
* Create a new SpreadsheetML drawing
*/
if(isNew) xmlOptions.setSaveSyntheticDocumentElement(new QName(CTDrawing.type.getName().getNamespaceURI(), "wsDr", "xdr"));
Map<String, String> map = new HashMap<String, String>();
- map.put("http://schemas.openxmlformats.org/drawingml/2006/main", "a");
+ map.put(NAMESPACE_A, "a");
map.put(STRelationshipId.type.getName().getNamespaceURI(), "r");
xmlOptions.setSaveSuggestedPrefixes(map);
shape.setRow(ca.getRow1());
return shape;
}
+
+ /**
+ * Returns all charts in this drawing.
+ */
+ public List<XSSFChart> getCharts() {
+ List<XSSFChart> charts = new ArrayList<XSSFChart>();
+ for(POIXMLDocumentPart part : getRelations()) {
+ if(part instanceof XSSFChart) {
+ charts.add((XSSFChart)part);
+ }
+ }
+ return charts;
+ }
/**
* Create and initialize a CTTwoCellAnchor that anchors a shape against top-left and bottom-right cells.
"/xl/worksheets/sheet#.xml",
XSSFSheet.class
);
- public static final XSSFRelation CHARTSHEET = new XSSFRelation(
+ public static final XSSFRelation CHARTSHEET = new XSSFRelation(
"application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet",
"/xl/chartsheets/sheet#.xml",
XSSFChartSheet.class
- );
+ );
public static final XSSFRelation SHARED_STRINGS = new XSSFRelation(
"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings",
"/xl/drawings/vmlDrawing#.vml",
XSSFVMLDrawing.class
);
+ public static final XSSFRelation CHART = new XSSFRelation(
+ "application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
+ "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
+ "/xl/charts/chart#.xml",
+ XSSFChart.class
+ );
public static final XSSFRelation CUSTOM_XML_MAPPINGS = new XSSFRelation(
"application/xml",
--- /dev/null
+/* ====================================================================
+ 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;
+
+public final class TestXSSFChart extends TestCase {
+
+ public void testGetAccessors() {
+ XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithThreeCharts.xlsx");
+ XSSFSheet s1 = wb.getSheetAt(0);
+ XSSFSheet s2 = wb.getSheetAt(1);
+ XSSFSheet s3 = wb.getSheetAt(2);
+
+ assertEquals(0, s1.getRelations().size());
+ assertEquals(1, s2.getRelations().size());
+ assertEquals(1, s3.getRelations().size());
+ }
+
+ public void testGetCharts() throws Exception {
+ XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("WithThreeCharts.xlsx");
+
+ XSSFSheet s1 = wb.getSheetAt(0);
+ XSSFSheet s2 = wb.getSheetAt(1);
+ XSSFSheet s3 = wb.getSheetAt(2);
+
+ assertEquals(0, s1.createDrawingPatriarch().getCharts().size());
+ assertEquals(2, s2.createDrawingPatriarch().getCharts().size());
+ assertEquals(1, s3.createDrawingPatriarch().getCharts().size());
+
+ // Check the titles
+ XSSFChart chart = s2.createDrawingPatriarch().getCharts().get(0);
+ assertEquals(null, chart.getTitle());
+
+ chart = s2.createDrawingPatriarch().getCharts().get(1);
+ assertEquals("Pie Chart Title Thingy", chart.getTitle().getString());
+
+ chart = s3.createDrawingPatriarch().getCharts().get(0);
+ assertEquals("Sheet 3 Chart with Title", chart.getTitle().getString());
+ }
+}
assertEquals(0, sheet.getColumnBreaks().length);
assertEquals(true, sheet.getRowSumsBelow());
}
+
+ public void testGetCharts() throws Exception {
+ XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("chart_sheet.xlsx");
+
+ XSSFSheet ns = wb.getSheetAt(0);
+ XSSFChartSheet cs = (XSSFChartSheet)wb.getSheetAt(2);
+
+ assertEquals(0, ns.createDrawingPatriarch().getCharts().size());
+ assertEquals(1, cs.createDrawingPatriarch().getCharts().size());
+
+ XSSFChart chart = cs.createDrawingPatriarch().getCharts().get(0);
+ assertEquals(null, chart.getTitle());
+ }
}