123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458 |
- /* ====================================================================
- 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 static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
-
- import java.io.IOException;
- import java.io.OutputStream;
- import java.util.ArrayList;
- import java.util.List;
-
- import javax.xml.namespace.QName;
-
- import org.apache.poi.openxml4j.opc.PackagePart;
- import org.apache.poi.ss.usermodel.Chart;
- import org.apache.poi.ss.usermodel.charts.ChartAxis;
- import org.apache.poi.ss.usermodel.charts.ChartAxisFactory;
- import org.apache.poi.ss.usermodel.charts.ChartData;
- import org.apache.poi.util.Removal;
- import org.apache.poi.xddf.usermodel.chart.XDDFChart;
- import org.apache.poi.xssf.usermodel.charts.XSSFCategoryAxis;
- import org.apache.poi.xssf.usermodel.charts.XSSFChartAxis;
- import org.apache.poi.xssf.usermodel.charts.XSSFChartDataFactory;
- import org.apache.poi.xssf.usermodel.charts.XSSFChartLegend;
- import org.apache.poi.xssf.usermodel.charts.XSSFDateAxis;
- import org.apache.poi.xssf.usermodel.charts.XSSFManualLayout;
- import org.apache.poi.xssf.usermodel.charts.XSSFValueAxis;
- import org.apache.xmlbeans.XmlException;
- import org.apache.xmlbeans.XmlObject;
- import org.apache.xmlbeans.XmlOptions;
- import org.openxmlformats.schemas.drawingml.x2006.chart.CTCatAx;
- import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace;
- import org.openxmlformats.schemas.drawingml.x2006.chart.CTDateAx;
- import org.openxmlformats.schemas.drawingml.x2006.chart.CTPageMargins;
- import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea;
- import org.openxmlformats.schemas.drawingml.x2006.chart.CTPrintSettings;
- import org.openxmlformats.schemas.drawingml.x2006.chart.CTStrRef;
- import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle;
- import org.openxmlformats.schemas.drawingml.x2006.chart.CTTx;
- import org.openxmlformats.schemas.drawingml.x2006.chart.CTValAx;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTRegularTextRun;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTTextField;
- import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
- import org.w3c.dom.Node;
- import org.w3c.dom.NodeList;
- import org.w3c.dom.Text;
-
- /**
- * Represents a SpreadsheetML Chart
- */
- public final class XSSFChart extends XDDFChart implements Chart, ChartAxisFactory {
-
- /**
- * Parent graphic frame.
- */
- private XSSFGraphicFrame frame;
-
- @Deprecated
- @Removal(version="4.2")
- List<XSSFChartAxis> axis = new ArrayList<>();
-
- /**
- * 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>
- *
- * @since POI 3.14-Beta1
- */
- protected XSSFChart(PackagePart part) throws IOException, XmlException {
- super(part);
- }
-
- /**
- * Construct a new CTChartSpace bean. By default, it's just an empty placeholder for chart objects.
- */
- private void createChart() {
- CTPlotArea plotArea = getCTPlotArea();
-
- plotArea.addNewLayout();
- chart.addNewPlotVisOnly().setVal(true);
-
- CTPrintSettings printSettings = chartSpace.addNewPrintSettings();
- printSettings.addNewHeaderFooter();
-
- CTPageMargins pageMargins = printSettings.addNewPageMargins();
- pageMargins.setB(0.75);
- pageMargins.setL(0.70);
- pageMargins.setR(0.70);
- pageMargins.setT(0.75);
- pageMargins.setHeader(0.30);
- pageMargins.setFooter(0.30);
- printSettings.addNewPageSetup();
- }
-
- @Override
- protected void commit() throws IOException {
- XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
-
- /*
- * Saved chart space must have the following namespaces set: <c:chartSpace
- * xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"
- * xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r=
- * "http://schemas.openxmlformats.org/officeDocument/2006/relationships">
- */
- xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c"));
-
- PackagePart part = getPackagePart();
- try (OutputStream out = part.getOutputStream()) {
- chartSpace.save(out, xmlOptions);
- }
- }
-
- /**
- * Returns the parent graphic frame.
- *
- * @return the graphic frame this chart belongs to
- */
- public XSSFGraphicFrame getGraphicFrame() {
- return frame;
- }
-
- /**
- * Sets the parent graphic frame.
- */
- protected void setGraphicFrame(XSSFGraphicFrame frame) {
- this.frame = frame;
- }
-
- @Override
- @Deprecated
- @Removal(version="4.2")
- public XSSFChartDataFactory getChartDataFactory() {
- return XSSFChartDataFactory.getInstance();
- }
-
- @Override
- @Deprecated
- @Removal(version="4.2")
- public XSSFChart getChartAxisFactory() {
- return this;
- }
-
- @Override
- @Deprecated
- @Removal(version="4.2")
- public void plot(ChartData data, ChartAxis... chartAxis) {
- data.fillChart(this, chartAxis);
- }
-
- @Override
- @Deprecated
- @Removal(version="4.2")
- public XSSFValueAxis createValueAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) {
- long id = axis.size() + 1;
- XSSFValueAxis valueAxis = new XSSFValueAxis(this, id, pos);
- if (axis.size() == 1) {
- ChartAxis ax = axis.get(0);
- ax.crossAxis(valueAxis);
- valueAxis.crossAxis(ax);
- }
- axis.add(valueAxis);
- return valueAxis;
- }
-
- @Override
- @Deprecated
- @Removal(version="4.2")
- public XSSFCategoryAxis createCategoryAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) {
- long id = axis.size() + 1;
- XSSFCategoryAxis categoryAxis = new XSSFCategoryAxis(this, id, pos);
- if (axis.size() == 1) {
- ChartAxis ax = axis.get(0);
- ax.crossAxis(categoryAxis);
- categoryAxis.crossAxis(ax);
- }
- axis.add(categoryAxis);
- return categoryAxis;
- }
-
- @Override
- @Deprecated
- @Removal(version="4.2")
- public XSSFDateAxis createDateAxis(org.apache.poi.ss.usermodel.charts.AxisPosition pos) {
- long id = axis.size() + 1;
- XSSFDateAxis dateAxis = new XSSFDateAxis(this, id, pos);
- if (axis.size() == 1) {
- ChartAxis ax = axis.get(0);
- ax.crossAxis(dateAxis);
- dateAxis.crossAxis(ax);
- }
- axis.add(dateAxis);
- return dateAxis;
- }
-
- /**
- * @deprecated use {@link getAxes} instead
- */
- @Override
- @Deprecated
- @Removal(version="4.2")
- public List<? extends XSSFChartAxis> getAxis() {
- if (axis.isEmpty() && hasAxis()) {
- parseAxis();
- }
- return axis;
- }
-
- @Override
- @Deprecated
- @Removal(version="4.2")
- public XSSFManualLayout getManualLayout() {
- return new XSSFManualLayout(this);
- }
-
- /**
- * Returns the title static text, or null if none is set.
- * Note that a title formula may be set instead.
- * @return static title text, if set
- * @deprecated POI 3.16, use {@link #getTitleText()} instead.
- */
- @Deprecated
- @Removal(version="4.0")
- public XSSFRichTextString getTitle() {
- return getTitleText();
- }
-
- /**
- * Returns the title static text, or null if none is set.
- * Note that a title formula may be set instead.
- * Empty text result is for backward compatibility, and could mean the title text is empty or there is a formula instead.
- * Check for a formula first, falling back on text for cleaner logic.
- * @return static title text if set,
- * null if there is no title,
- * empty string if the title text is empty or the title uses a formula instead
- */
- public XSSFRichTextString getTitleText() {
- if(! chart.isSetTitle()) {
- return null;
- }
-
- // TODO Do properly
- CTTitle title = chart.getTitle();
-
- StringBuilder text = new StringBuilder(64);
- XmlObject[] t = title
- .selectPath("declare namespace a='"+XSSFDrawing.NAMESPACE_A+"' .//a:t");
- for (XmlObject element : t) {
- NodeList kids = element.getDomNode().getChildNodes();
- final int count = kids.getLength();
- for (int n = 0; n < count; n++) {
- Node kid = kids.item(n);
- if (kid instanceof Text) {
- text.append(kid.getNodeValue());
- }
- }
- }
-
- return new XSSFRichTextString(text.toString());
- }
-
- /**
- * Sets the title text as a static string.
- * @param newTitle to use
- * @deprecated POI 3.16, use {@link #setTitleText(String)} instead.
- */
- @Deprecated
- @Removal(version = "4.0")
- public void setTitle(String newTitle) {
-
- }
-
- /**
- * Sets the title text as a static string.
- *
- * @param newTitle
- * to use
- */
- public void setTitleText(String newTitle) {
- CTTitle ctTitle;
- if (chart.isSetTitle()) {
- ctTitle = chart.getTitle();
- } else {
- ctTitle = chart.addNewTitle();
- }
-
- CTTx tx;
- if (ctTitle.isSetTx()) {
- tx = ctTitle.getTx();
- } else {
- tx = ctTitle.addNewTx();
- }
-
- if (tx.isSetStrRef()) {
- tx.unsetStrRef();
- }
-
- CTTextBody rich;
- if (tx.isSetRich()) {
- rich = tx.getRich();
- } else {
- rich = tx.addNewRich();
- rich.addNewBodyPr(); // body properties must exist (but can be
- // empty)
- }
-
- CTTextParagraph para;
- if (rich.sizeOfPArray() > 0) {
- para = rich.getPArray(0);
- } else {
- para = rich.addNewP();
- }
-
- if (para.sizeOfRArray() > 0) {
- CTRegularTextRun run = para.getRArray(0);
- run.setT(newTitle);
- } else if (para.sizeOfFldArray() > 0) {
- CTTextField fld = para.getFldArray(0);
- fld.setT(newTitle);
- } else {
- CTRegularTextRun run = para.addNewR();
- run.setT(newTitle);
- }
- }
-
- /**
- * Get the chart title formula expression if there is one
- *
- * @return formula expression or null
- */
- public String getTitleFormula() {
- if (!chart.isSetTitle()) {
- return null;
- }
-
- CTTitle title = chart.getTitle();
-
- if (!title.isSetTx()) {
- return null;
- }
-
- CTTx tx = title.getTx();
-
- if (!tx.isSetStrRef()) {
- return null;
- }
-
- return tx.getStrRef().getF();
- }
-
- /**
- * Set the formula expression to use for the chart title
- *
- * @param formula
- */
- public void setTitleFormula(String formula) {
- CTTitle ctTitle;
- if (chart.isSetTitle()) {
- ctTitle = chart.getTitle();
- } else {
- ctTitle = chart.addNewTitle();
- }
-
- CTTx tx;
- if (ctTitle.isSetTx()) {
- tx = ctTitle.getTx();
- } else {
- tx = ctTitle.addNewTx();
- }
-
- if (tx.isSetRich()) {
- tx.unsetRich();
- }
-
- CTStrRef strRef;
- if (tx.isSetStrRef()) {
- strRef = tx.getStrRef();
- } else {
- strRef = tx.addNewStrRef();
- }
-
- strRef.setF(formula);
- }
-
- @Override
- @Deprecated
- @Removal(version="4.2")
- public XSSFChartLegend getOrCreateLegend() {
- return new XSSFChartLegend(this);
- }
-
- @Deprecated
- @Removal(version="4.2")
- private boolean hasAxis() {
- CTPlotArea ctPlotArea = chart.getPlotArea();
- int totalAxisCount = ctPlotArea.sizeOfValAxArray() + ctPlotArea.sizeOfCatAxArray() + ctPlotArea.sizeOfDateAxArray() + ctPlotArea.sizeOfSerAxArray();
- return totalAxisCount > 0;
- }
-
- @Deprecated
- @Removal(version="4.2")
- private void parseAxis() {
- // TODO: add other axis types
- parseCategoryAxis();
- parseDateAxis();
- parseValueAxis();
- }
-
- @Deprecated
- @Removal(version="4.2")
- private void parseCategoryAxis() {
- for (CTCatAx catAx : chart.getPlotArea().getCatAxArray()) {
- axis.add(new XSSFCategoryAxis(this, catAx));
- }
- }
-
- @Deprecated
- @Removal(version="4.2")
- private void parseDateAxis() {
- for (CTDateAx dateAx : chart.getPlotArea().getDateAxArray()) {
- axis.add(new XSSFDateAxis(this, dateAx));
- }
- }
-
- @Deprecated
- @Removal(version="4.2")
- private void parseValueAxis() {
- for (CTValAx valAx : chart.getPlotArea().getValAxArray()) {
- axis.add(new XSSFValueAxis(this, valAx));
- }
- }
-
- }
|