1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 import com.sun.star.awt.Rectangle;
24 
25 import com.sun.star.beans.PropertyValue;
26 import com.sun.star.beans.XPropertySet;
27 
28 import com.sun.star.chart.XDiagram;
29 import com.sun.star.chart.XChartDocument;
30 
31 import com.sun.star.container.XNameAccess;
32 import com.sun.star.container.XIndexAccess;
33 
34 import com.sun.star.document.XEmbeddedObjectSupplier;
35 
36 import com.sun.star.frame.XComponentLoader;
37 
38 import com.sun.star.lang.XComponent;
39 import com.sun.star.lang.XMultiServiceFactory;
40 import com.sun.star.lang.XMultiComponentFactory;
41 
42 import com.sun.star.sheet.XSpreadsheets;
43 import com.sun.star.sheet.XSpreadsheet;
44 import com.sun.star.sheet.XSpreadsheetDocument;
45 import com.sun.star.sheet.XCellRangeAddressable;
46 
47 import com.sun.star.table.XTableChart;
48 import com.sun.star.table.XTableCharts;
49 import com.sun.star.table.XCell;
50 import com.sun.star.table.XCellRange;
51 import com.sun.star.table.XTableChartsSupplier;
52 import com.sun.star.table.CellRangeAddress;
53 
54 import com.sun.star.uno.UnoRuntime;
55 import com.sun.star.uno.XInterface;
56 import com.sun.star.uno.XComponentContext;
57 
58 
59 
60 /** This class loads an OpenOffice.org Calc document and changes the type of the
61  * embedded chart.
62  * @author Bertram Nolte
63  */
64 public class ChartTypeChange {
65 
66     /** Table chart, which type will be changed.
67      */
68     private XTableChart xtablechart = null;
69 
70     /** Service factory
71      */
72     private XMultiComponentFactory xMCF = null;
73 
74     /** Component context
75      */
76     private XComponentContext xCompContext = null;
77 
78     /** Beginning of the program.
79      * @param args No arguments will be passed to the class.
80      */
main(String args[])81     public static void main(String args[]) {
82         try {
83             ChartTypeChange charttypechange = new ChartTypeChange();
84 
85             // Double array holding all values the chart should be based on.
86             String[][] stringValues = {
87                 { "", "Jan", "Feb", "Mar", "Apr", "Mai" },
88                 { "Profit", "12.3", "43.2", "5.1", "76", "56.8" },
89                 { "Rival in business", "12.2", "12.6", "17.7", "20.4", "100" },
90             };
91 
92             // Create the chart with
93             charttypechange.getChart( stringValues );
94 
95             String[] stringChartType = {
96                 "com.sun.star.chart.LineDiagram",
97                 "com.sun.star.chart.BarDiagram",
98                 "com.sun.star.chart.PieDiagram",
99                 "com.sun.star.chart.NetDiagram",
100                 "com.sun.star.chart.XYDiagram",
101                 "com.sun.star.chart.StockDiagram",
102                 "com.sun.star.chart.AreaDiagram"
103             };
104 
105             for ( int intCounter = 0; intCounter < stringChartType.length;
106                   intCounter++ ) {
107                 charttypechange.changeChartType( stringChartType[ intCounter ],
108                                                  false );
109                 Thread.sleep( 3000 );
110             }
111 
112             System.exit(0);
113         }
114         catch( Exception exception ) {
115             System.err.println( exception );
116         }
117     }
118 
119     /** The constructor connects to the OpenOffice.org.
120      * @param args Parameters for this constructor (connection string).
121      * @throws Exception All exceptions are thrown from this method.
122      */
ChartTypeChange()123     public ChartTypeChange()
124         throws Exception {
125 
126         /* Bootstraps a component context. Component context to be granted
127            to a component for running. Arbitrary values can be retrieved
128            from the context. */
129         xCompContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
130 
131         /* Gets the service manager instance to be used (or null). This method has
132            been added for convenience, because the service manager is a often used
133            object. */
134         xMCF = xCompContext.getServiceManager();
135     }
136 
137     /** This method will change the type of a specified chart.
138      * @param stringType The chart will be converted to this type.
139      * @param booleanIs3D If the chart should be displayed in 3D this parameter should be set to true.
140      * @throws Exception All exceptions are thrown from this method.
141      */
changeChartType( String stringType, boolean booleanIs3D )142     public void changeChartType( String stringType, boolean booleanIs3D )
143     throws Exception {
144         XEmbeddedObjectSupplier xEmbeddedObjSupplier = (XEmbeddedObjectSupplier)
145             UnoRuntime.queryInterface(XEmbeddedObjectSupplier.class, xtablechart);
146         XInterface xInterface = xEmbeddedObjSupplier.getEmbeddedObject();
147 
148         XChartDocument xChartDoc = (XChartDocument)UnoRuntime.queryInterface(
149             XChartDocument.class, xInterface);
150         XDiagram xDiagram = (XDiagram) xChartDoc.getDiagram();
151         XMultiServiceFactory xMSF = (XMultiServiceFactory)
152             UnoRuntime.queryInterface( XMultiServiceFactory.class, xChartDoc );
153         Object object = xMSF.createInstance( stringType );
154         xDiagram = (XDiagram) UnoRuntime.queryInterface(XDiagram.class, object);
155 
156         XPropertySet xPropSet = (XPropertySet) UnoRuntime.queryInterface(
157             XPropertySet.class, xDiagram );
158         xPropSet.setPropertyValue( "Dim3D", new Boolean( booleanIs3D ) );
159 
160         xChartDoc.setDiagram(xDiagram);
161     }
162 
163     /** Loading an OpenOffice.org Calc document and getting a chart by name.
164      * @param stringFileName Name of the OpenOffice.org Calc document which should
165      *                       be loaded.
166      * @param stringChartName Name of the chart which should get a new chart type.
167      */
getChart( String stringFileName, String stringChartName )168     public void getChart( String stringFileName, String stringChartName ) {
169         try {
170             /* A desktop environment contains tasks with one or more
171                frames in which components can be loaded. Desktop is the
172                environment for components which can instanciate within
173                frames. */
174             XComponentLoader xComponentloader = (XComponentLoader)
175                 UnoRuntime.queryInterface( XComponentLoader.class,
176                     xMCF.createInstanceWithContext("com.sun.star.frame.Desktop",
177                                                    xCompContext ) );
178 
179             // Load a Writer document, which will be automatically displayed
180             XComponent xComponent = xComponentloader.loadComponentFromURL(
181             "file:///" + stringFileName, "_blank", 0,
182             new PropertyValue[0] );
183 
184             // Query for the interface XSpreadsheetDocument
185             XSpreadsheetDocument xSpreadSheetDocument = ( XSpreadsheetDocument )
186                 UnoRuntime.queryInterface( XSpreadsheetDocument.class, xComponent );
187 
188             XSpreadsheets xSpreadsheets = xSpreadSheetDocument.getSheets() ;
189 
190             XIndexAccess xIndexAccess = (XIndexAccess)
191                 UnoRuntime.queryInterface(XIndexAccess.class, xSpreadsheets );
192 
193             XSpreadsheet xSpreadsheet = (XSpreadsheet) UnoRuntime.queryInterface(
194                 XSpreadsheet.class, xIndexAccess.getByIndex(0));
195 
196             XTableChartsSupplier xTableChartsSupplier = ( XTableChartsSupplier )
197                 UnoRuntime.queryInterface( XTableChartsSupplier.class, xSpreadsheet );
198 
199             xIndexAccess = (XIndexAccess) UnoRuntime.queryInterface(
200                 XIndexAccess.class, xTableChartsSupplier.getCharts() );
201 
202             this.xtablechart = (XTableChart) UnoRuntime.queryInterface(
203                 XTableChart.class,  xIndexAccess.getByIndex( 0 ) );
204         }
205         catch( Exception exception ) {
206             System.err.println( exception );
207         }
208     }
209 
210     /** Creating an empty OpenOffice.org Calc document, inserting data, and getting a
211      * chart by name.
212      * @param stringValues Double array with the values for the chart.
213      */
getChart( String[][] stringValues )214     public void getChart( String[][] stringValues ) {
215         try {
216             /* A desktop environment contains tasks with one or more
217                frames in which components can be loaded. Desktop is the
218                environment for components which can instanciate within
219                frames. */
220             XComponentLoader xcomponentloader = ( XComponentLoader )
221                 UnoRuntime.queryInterface( XComponentLoader.class,
222                                            xMCF.createInstanceWithContext(
223                                                "com.sun.star.frame.Desktop",
224                                                xCompContext ) );
225 
226             // Create an empty calc document, which will be automatically displayed
227             XComponent xComponent = xcomponentloader.loadComponentFromURL(
228             "private:factory/scalc", "_blank", 0,
229             new PropertyValue[0] );
230 
231             // Query for the interface XSpreadsheetDocument
232             XSpreadsheetDocument xspreadsheetdocument = ( XSpreadsheetDocument )
233                 UnoRuntime.queryInterface( XSpreadsheetDocument.class, xComponent );
234 
235             // Get all sheets of the spreadsheet document.
236             XSpreadsheets xspreadsheets = xspreadsheetdocument.getSheets() ;
237 
238             // Get the index of the spreadsheet document.
239             XIndexAccess xindexaccess = (XIndexAccess) UnoRuntime.queryInterface(
240                 XIndexAccess.class, xspreadsheets );
241 
242             // Get the first spreadsheet.
243             XSpreadsheet xspreadsheet = (XSpreadsheet) UnoRuntime.queryInterface(
244                 XSpreadsheet.class, xindexaccess.getByIndex(0));
245 
246             // The double array will written to the spreadsheet
247             for ( int intY = 0; intY < stringValues.length; intY++ ) {
248                 for ( int intX = 0; intX < stringValues[ intY ].length;
249                 intX++ ) {
250                     // Insert the value to the cell, specified by intY and intX.
251                     this.insertIntoCell( intY, intX,
252                     stringValues[ intY ][ intX ], xspreadsheet, "" );
253                 }
254             }
255 
256             // Create a rectangle, which holds the size of the chart.
257             Rectangle rectangle = new Rectangle();
258             rectangle.X = 500;
259             rectangle.Y = 3000;
260             rectangle.Width = 25000;
261             rectangle.Height = 11000;
262 
263             // Get the cell range of the spreadsheet.
264             XCellRange xcellrange = ( XCellRange ) UnoRuntime.queryInterface(
265                 XCellRange.class, xspreadsheet );
266 
267             // Create the Unicode of the character for the column name.
268             char charRectangle = ( char ) ( 65 + stringValues.length - 1 );
269 
270             // Get maximum length all rows in the double array.
271             int intMaximumWidthRow = 0;
272             for ( int intRow = 0; intRow < stringValues.length; intRow++ ) {
273                 if ( stringValues[ intRow ].length > intMaximumWidthRow ) {
274                     intMaximumWidthRow = stringValues[ intRow ].length;
275                 }
276             }
277 
278             // Get the cell range of the written values.
279             XCellRange xcellrangeChart = xcellrange.getCellRangeByName( "A1:" +
280             charRectangle + intMaximumWidthRow );
281 
282             // Get the addressable cell range.
283             XCellRangeAddressable xcellrangeaddressable =
284             ( XCellRangeAddressable ) UnoRuntime.queryInterface(
285                 XCellRangeAddressable.class, xcellrangeChart );
286 
287             // Get the cell range address.
288             CellRangeAddress cellrangeaddress = xcellrangeaddressable.getRangeAddress();
289 
290             // Create the cell range address for the chart.
291             CellRangeAddress[] cellrangeaddressChart =
292             new CellRangeAddress[ 1 ];
293             cellrangeaddressChart[ 0 ] = cellrangeaddress;
294 
295             // Get the table charts supplier of the spreadsheet.
296             XTableChartsSupplier xtablechartssupplier = ( XTableChartsSupplier )
297                 UnoRuntime.queryInterface( XTableChartsSupplier.class, xspreadsheet );
298 
299             // Get all table charts of the spreadsheet.
300             XTableCharts xtablecharts = xtablechartssupplier.getCharts();
301 
302             // Create a table chart with all written values.
303             xtablecharts.addNewByName( "Example", rectangle,
304             cellrangeaddressChart, true, true );
305 
306             // Get the created table chart.
307             this.xtablechart = ( XTableChart ) UnoRuntime.queryInterface(
308                 XTableChart.class, (( XNameAccess ) UnoRuntime.queryInterface(
309                     XNameAccess.class, xtablecharts ) ).getByName( "Example" ));
310         }
311         catch( Exception exception ) {
312             System.err.println( exception );
313         }
314     }
315 
316     /** Inserting a given value to a cell, that is specified by the parameters intX
317      * and intY.
318      * @param intX Column on the spreadsheet.
319      * @param intY Row on the spreadsheet.
320      * @param stringValue Value to be inserted to a cell.
321      * @param xspreadsheet Spreadsheet of the cell, which will be changed.
322      * @param stringFlag If the value of stringFlag is "V", the stringValue
323      *                   will be converted to the
324      * float type. Otherwise the stringValue will be written as a formula.
325      */
insertIntoCell( int intX, int intY, String stringValue, XSpreadsheet xspreadsheet, String stringFlag )326     public static void insertIntoCell( int intX, int intY, String stringValue,
327                                        XSpreadsheet xspreadsheet, String stringFlag )
328     {
329         XCell xcell = null;
330 
331         try {
332             xcell = xspreadsheet.getCellByPosition( intX, intY );
333         }
334         catch ( com.sun.star.lang.IndexOutOfBoundsException exception ) {
335             System.out.println( "Could not get cell." );
336         }
337         if ( stringFlag.equals( "V" ) ) {
338             xcell.setValue( ( new Float( stringValue ) ).floatValue() );
339         }
340         else {
341             xcell.setFormula( stringValue );
342         }
343     }
344 }
345