Lines 21-31
import java.io.IOException;
Link Here
|
21 |
import java.io.OutputStream; |
21 |
import java.io.OutputStream; |
22 |
import java.util.HashMap; |
22 |
import java.util.HashMap; |
23 |
import java.util.Map; |
23 |
import java.util.Map; |
|
|
24 |
import java.util.List; |
25 |
import java.util.ArrayList; |
26 |
|
27 |
import javax.xml.namespace.QName; |
24 |
|
28 |
|
25 |
import org.apache.poi.POIXMLDocumentPart; |
29 |
import org.apache.poi.POIXMLDocumentPart; |
26 |
import org.apache.poi.openxml4j.opc.PackagePart; |
30 |
import org.apache.poi.openxml4j.opc.PackagePart; |
27 |
import org.apache.poi.openxml4j.opc.PackageRelationship; |
31 |
import org.apache.poi.openxml4j.opc.PackageRelationship; |
28 |
import org.apache.poi.util.Internal; |
32 |
import org.apache.poi.util.Internal; |
|
|
33 |
import org.apache.poi.ss.usermodel.Chart; |
34 |
import org.apache.poi.ss.usermodel.charts.ChartAxis; |
35 |
import org.apache.poi.ss.usermodel.charts.ChartAxisFactory; |
36 |
import org.apache.poi.xssf.usermodel.charts.XSSFChartDataFactory; |
37 |
import org.apache.poi.xssf.usermodel.charts.XSSFChartAxis; |
38 |
import org.apache.poi.xssf.usermodel.charts.XSSFValueAxis; |
39 |
import org.apache.poi.xssf.usermodel.charts.XSSFChartLegend; |
40 |
import org.apache.poi.ss.usermodel.charts.ChartData; |
41 |
import org.apache.poi.ss.usermodel.charts.AxisPosition; |
29 |
import org.apache.xmlbeans.XmlException; |
42 |
import org.apache.xmlbeans.XmlException; |
30 |
import org.apache.xmlbeans.XmlObject; |
43 |
import org.apache.xmlbeans.XmlObject; |
31 |
import org.apache.xmlbeans.XmlOptions; |
44 |
import org.apache.xmlbeans.XmlOptions; |
Lines 33-147
import org.openxmlformats.schemas.drawingml.x2006.chart.CTChart;
Link Here
|
33 |
import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace; |
46 |
import org.openxmlformats.schemas.drawingml.x2006.chart.CTChartSpace; |
34 |
import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle; |
47 |
import org.openxmlformats.schemas.drawingml.x2006.chart.CTTitle; |
35 |
import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument; |
48 |
import org.openxmlformats.schemas.drawingml.x2006.chart.ChartSpaceDocument; |
|
|
49 |
import org.openxmlformats.schemas.drawingml.x2006.chart.CTLayout; |
50 |
import org.openxmlformats.schemas.drawingml.x2006.chart.CTManualLayout; |
51 |
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPlotArea; |
52 |
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPrintSettings; |
53 |
import org.openxmlformats.schemas.drawingml.x2006.chart.CTPageMargins; |
54 |
import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutTarget; |
55 |
import org.openxmlformats.schemas.drawingml.x2006.chart.STLayoutMode; |
36 |
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; |
56 |
import org.openxmlformats.schemas.officeDocument.x2006.relationships.STRelationshipId; |
37 |
import org.w3c.dom.NodeList; |
57 |
import org.w3c.dom.NodeList; |
38 |
import org.w3c.dom.Text; |
58 |
import org.w3c.dom.Text; |
39 |
|
59 |
|
40 |
/** |
60 |
/** |
41 |
* Represents a SpreadsheetML Chart |
61 |
* Represents a SpreadsheetML Chart |
|
|
62 |
* @author Nick Burch |
63 |
* @author Roman Kashitsyn |
42 |
*/ |
64 |
*/ |
43 |
public final class XSSFChart extends POIXMLDocumentPart { |
65 |
public final class XSSFChart extends POIXMLDocumentPart implements Chart, ChartAxisFactory { |
44 |
/** |
66 |
|
45 |
* Root element of the SpreadsheetML Chart part |
67 |
/** |
46 |
*/ |
68 |
* Parent graphic frame. |
47 |
private CTChartSpace chartSpace; |
69 |
*/ |
48 |
/** |
70 |
private XSSFGraphicFrame frame; |
49 |
* The Chart within that |
71 |
|
50 |
*/ |
72 |
/** |
51 |
private CTChart chart; |
73 |
* Root element of the SpreadsheetML Chart part |
52 |
|
74 |
*/ |
53 |
/** |
75 |
private CTChartSpace chartSpace; |
54 |
* Create a new SpreadsheetML chart |
76 |
/** |
55 |
*/ |
77 |
* The Chart within that |
56 |
protected XSSFChart() { |
78 |
*/ |
57 |
super(); |
79 |
private CTChart chart; |
58 |
createChart(); |
80 |
|
59 |
} |
81 |
List<XSSFChartAxis> axis; |
60 |
|
82 |
|
61 |
/** |
83 |
/** |
62 |
* Construct a SpreadsheetML chart from a package part |
84 |
* Create a new SpreadsheetML chart |
63 |
* |
85 |
*/ |
64 |
* @param part the package part holding the chart data, |
86 |
protected XSSFChart() { |
65 |
* the content type must be <code>application/vnd.openxmlformats-officedocument.drawingml.chart+xml</code> |
87 |
super(); |
66 |
* @param rel the package relationship holding this chart, |
88 |
axis = new ArrayList<XSSFChartAxis>(); |
67 |
* the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart |
89 |
createChart(); |
68 |
*/ |
90 |
} |
69 |
protected XSSFChart(PackagePart part, PackageRelationship rel) throws IOException, XmlException { |
91 |
|
70 |
super(part, rel); |
92 |
/** |
71 |
|
93 |
* Construct a SpreadsheetML chart from a package part |
72 |
chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream()).getChartSpace(); |
94 |
* |
73 |
chart = chartSpace.getChart(); |
95 |
* @param part the package part holding the chart data, |
74 |
} |
96 |
* the content type must be <code>application/vnd.openxmlformats-officedocument.drawingml.chart+xml</code> |
75 |
|
97 |
* @param rel the package relationship holding this chart, |
76 |
/** |
98 |
* the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart |
77 |
* Construct a new CTChartSpace bean. By default, it's just an empty placeholder for chart objects |
99 |
*/ |
78 |
* |
100 |
protected XSSFChart(PackagePart part, PackageRelationship rel) throws IOException, XmlException { |
79 |
* @return a new CTChartSpace bean |
101 |
super(part, rel); |
80 |
*/ |
102 |
|
81 |
private void createChart() { |
103 |
chartSpace = ChartSpaceDocument.Factory.parse(part.getInputStream()).getChartSpace(); |
82 |
chartSpace = CTChartSpace.Factory.newInstance(); |
104 |
chart = chartSpace.getChart(); |
83 |
chart = chartSpace.addNewChart(); |
105 |
} |
84 |
} |
106 |
|
85 |
|
107 |
/** |
86 |
/** |
108 |
* Construct a new CTChartSpace bean. By default, it's just an empty placeholder for chart objects |
87 |
* Return the underlying CTChartSpace bean, the root element of the SpreadsheetML Chart part. |
109 |
* |
88 |
* |
110 |
* @return a new CTChartSpace bean |
89 |
* @return the underlying CTChartSpace bean |
111 |
*/ |
90 |
*/ |
112 |
private void createChart() { |
91 |
@Internal |
113 |
chartSpace = CTChartSpace.Factory.newInstance(); |
92 |
public CTChartSpace getCTChartSpace(){ |
114 |
chart = chartSpace.addNewChart(); |
93 |
return chartSpace; |
115 |
CTPlotArea plotArea = chart.addNewPlotArea(); |
94 |
} |
116 |
CTLayout layout = plotArea.addNewLayout(); |
95 |
|
117 |
CTManualLayout manualLayout = layout.addNewManualLayout(); |
96 |
/** |
118 |
manualLayout.addNewLayoutTarget().setVal(STLayoutTarget.INNER); |
97 |
* Return the underlying CTChart bean, within the Chart Space |
119 |
manualLayout.addNewXMode().setVal(STLayoutMode.EDGE); |
98 |
* |
120 |
manualLayout.addNewYMode().setVal(STLayoutMode.EDGE); |
99 |
* @return the underlying CTChart bean |
121 |
manualLayout.addNewX().setVal(0); |
100 |
*/ |
122 |
manualLayout.addNewY().setVal(0); |
101 |
@Internal |
123 |
manualLayout.addNewW().setVal(0.65); |
102 |
public CTChart getCTChart(){ |
124 |
manualLayout.addNewH().setVal(0.8); |
103 |
return chart; |
125 |
chart.addNewPlotVisOnly().setVal(true); |
104 |
} |
126 |
CTPrintSettings printSettings = chartSpace.addNewPrintSettings(); |
105 |
|
127 |
printSettings.addNewHeaderFooter(); |
106 |
@Override |
128 |
|
107 |
protected void commit() throws IOException { |
129 |
CTPageMargins pageMargins = printSettings.addNewPageMargins(); |
108 |
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); |
130 |
pageMargins.setB(0.75); |
109 |
|
131 |
pageMargins.setL(0.70); |
110 |
Map<String, String> map = new HashMap<String, String>(); |
132 |
pageMargins.setR(0.70); |
111 |
map.put(XSSFDrawing.NAMESPACE_A, "a"); |
133 |
pageMargins.setT(0.75); |
112 |
map.put(STRelationshipId.type.getName().getNamespaceURI(), "r"); |
134 |
pageMargins.setHeader(0.30); |
113 |
xmlOptions.setSaveSuggestedPrefixes(map); |
135 |
pageMargins.setFooter(0.30); |
114 |
|
136 |
printSettings.addNewPageSetup(); |
115 |
PackagePart part = getPackagePart(); |
137 |
} |
116 |
OutputStream out = part.getOutputStream(); |
138 |
|
117 |
chartSpace.save(out, xmlOptions); |
139 |
/** |
118 |
out.close(); |
140 |
* Return the underlying CTChartSpace bean, the root element of the SpreadsheetML Chart part. |
119 |
} |
141 |
* |
120 |
|
142 |
* @return the underlying CTChartSpace bean |
121 |
/** |
143 |
*/ |
122 |
* Returns the title, or null if none is set |
144 |
@Internal |
123 |
*/ |
145 |
public CTChartSpace getCTChartSpace(){ |
124 |
public XSSFRichTextString getTitle() { |
146 |
return chartSpace; |
125 |
if(! chart.isSetTitle()) { |
147 |
} |
126 |
return null; |
148 |
|
127 |
} |
149 |
/** |
128 |
|
150 |
* Return the underlying CTChart bean, within the Chart Space |
129 |
// TODO Do properly |
151 |
* |
130 |
CTTitle title = chart.getTitle(); |
152 |
* @return the underlying CTChart bean |
131 |
|
153 |
*/ |
132 |
StringBuffer text = new StringBuffer(); |
154 |
@Internal |
133 |
XmlObject[] t = title |
155 |
public CTChart getCTChart(){ |
134 |
.selectPath("declare namespace a='"+XSSFDrawing.NAMESPACE_A+"' .//a:t"); |
156 |
return chart; |
135 |
for (int m = 0; m < t.length; m++) { |
157 |
} |
136 |
NodeList kids = t[m].getDomNode().getChildNodes(); |
158 |
|
137 |
for (int n = 0; n < kids.getLength(); n++) { |
159 |
@Override |
138 |
if (kids.item(n) instanceof Text) { |
160 |
protected void commit() throws IOException { |
139 |
text.append(kids.item(n).getNodeValue()); |
161 |
XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); |
140 |
} |
162 |
|
141 |
} |
163 |
/* |
142 |
} |
164 |
Saved chart space must have the following namespaces set: |
143 |
|
165 |
<c:chartSpace |
144 |
return new XSSFRichTextString(text.toString()); |
166 |
xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" |
145 |
} |
167 |
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" |
|
|
168 |
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"> |
169 |
*/ |
170 |
xmlOptions.setSaveSyntheticDocumentElement(new QName(CTChartSpace.type.getName().getNamespaceURI(), "chartSpace", "c")); |
171 |
Map<String, String> map = new HashMap<String, String>(); |
172 |
map.put(XSSFDrawing.NAMESPACE_A, "a"); |
173 |
map.put(XSSFDrawing.NAMESPACE_C, "c"); |
174 |
map.put(STRelationshipId.type.getName().getNamespaceURI(), "r"); |
175 |
xmlOptions.setSaveSuggestedPrefixes(map); |
176 |
|
177 |
PackagePart part = getPackagePart(); |
178 |
OutputStream out = part.getOutputStream(); |
179 |
chartSpace.save(out, xmlOptions); |
180 |
out.close(); |
181 |
} |
182 |
|
183 |
/** |
184 |
* Returns the parent graphic frame. |
185 |
* @return the graphic frame this chart belongs to |
186 |
*/ |
187 |
public XSSFGraphicFrame getGraphicFrame() { |
188 |
return frame; |
189 |
} |
190 |
|
191 |
/** |
192 |
* Sets the parent graphic frame. |
193 |
*/ |
194 |
protected void setGraphicFrame(XSSFGraphicFrame frame) { |
195 |
this.frame = frame; |
196 |
} |
197 |
|
198 |
public XSSFChartDataFactory getChartDataFactory() { |
199 |
return XSSFChartDataFactory.getInstance(); |
200 |
} |
201 |
|
202 |
public XSSFChart getChartAxisFactory() { |
203 |
return this; |
204 |
} |
205 |
|
206 |
public void plot(ChartData data, ChartAxis... axis) { |
207 |
data.fillChart(this, axis); |
208 |
} |
209 |
|
210 |
public XSSFValueAxis createValueAxis(AxisPosition pos) { |
211 |
long id = axis.size() + 1; |
212 |
XSSFValueAxis valueAxis = new XSSFValueAxis(this, id, pos); |
213 |
if (axis.size() == 1) { |
214 |
ChartAxis ax = axis.get(0); |
215 |
ax.crossAxis(valueAxis); |
216 |
valueAxis.crossAxis(ax); |
217 |
} |
218 |
axis.add(valueAxis); |
219 |
return valueAxis; |
220 |
} |
221 |
|
222 |
public List<? extends XSSFChartAxis> getAxis() { |
223 |
return axis; |
224 |
} |
225 |
|
226 |
/** |
227 |
* Sets the width ratio of the chart. |
228 |
* Chart width is ratio multiplied by parent frame width. |
229 |
* @param ratio a number between 0 and 1. |
230 |
*/ |
231 |
public void setWidthRatio(double ratio) { |
232 |
chart.getPlotArea().getLayout().getManualLayout().getW().setVal(ratio); |
233 |
} |
234 |
|
235 |
/** |
236 |
* @return relative chart width |
237 |
*/ |
238 |
public double getWidthRatio() { |
239 |
return chart.getPlotArea().getLayout().getManualLayout().getW().getVal(); |
240 |
} |
241 |
|
242 |
/** |
243 |
* Sets the height ratio of the chart. |
244 |
* Chart height is ratio multiplied by parent frame height. |
245 |
* @param ratio a number between 0 and 1. |
246 |
*/ |
247 |
public void setHeightRatio(double ratio) { |
248 |
chart.getPlotArea().getLayout().getManualLayout().getH().setVal(ratio); |
249 |
} |
250 |
|
251 |
/** |
252 |
* @return relative chart height |
253 |
*/ |
254 |
public double getHeightRatio() { |
255 |
return chart.getPlotArea().getLayout().getManualLayout().getH().getVal(); |
256 |
} |
257 |
|
258 |
/** |
259 |
* @return true if only visible cells will be present on the chart, |
260 |
* false otherwise |
261 |
*/ |
262 |
public boolean isPlotOnlyVisibleCells() { |
263 |
return chart.getPlotVisOnly().getVal(); |
264 |
} |
265 |
|
266 |
/** |
267 |
* @param plotVisOnly a flag specifying if only visible cells should be |
268 |
* present on the chart |
269 |
*/ |
270 |
public void setPlotOnlyVisibleCells(boolean plotVisOnly) { |
271 |
chart.getPlotVisOnly().setVal(plotVisOnly); |
272 |
} |
273 |
|
274 |
/** |
275 |
* Returns the title, or null if none is set |
276 |
*/ |
277 |
public XSSFRichTextString getTitle() { |
278 |
if(! chart.isSetTitle()) { |
279 |
return null; |
280 |
} |
281 |
|
282 |
// TODO Do properly |
283 |
CTTitle title = chart.getTitle(); |
284 |
|
285 |
StringBuffer text = new StringBuffer(); |
286 |
XmlObject[] t = title |
287 |
.selectPath("declare namespace a='"+XSSFDrawing.NAMESPACE_A+"' .//a:t"); |
288 |
for (int m = 0; m < t.length; m++) { |
289 |
NodeList kids = t[m].getDomNode().getChildNodes(); |
290 |
for (int n = 0; n < kids.getLength(); n++) { |
291 |
if (kids.item(n) instanceof Text) { |
292 |
text.append(kids.item(n).getNodeValue()); |
293 |
} |
294 |
} |
295 |
} |
296 |
|
297 |
return new XSSFRichTextString(text.toString()); |
298 |
} |
299 |
|
300 |
public XSSFChartLegend getOrCreateLegend() { |
301 |
return new XSSFChartLegend(this); |
302 |
} |
303 |
|
304 |
public void deleteLegend() { |
305 |
if (chart.isSetLegend()) { |
306 |
chart.unsetLegend(); |
307 |
} |
308 |
} |
146 |
|
309 |
|
147 |
} |
310 |
} |