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 
24 import com.sun.star.comp.servicemanager.ServiceManager;
25 import com.sun.star.bridge.XUnoUrlResolver;
26 import com.sun.star.uno.XNamingService;
27 import com.sun.star.frame.XDesktop;
28 import com.sun.star.frame.XComponentLoader;
29 import com.sun.star.lang.XMultiServiceFactory;
30 import com.sun.star.lang.XComponent;
31 
32 import com.sun.star.uno.UnoRuntime;
33 import com.sun.star.uno.RuntimeException;
34 
35 // __________  implementation  ____________________________________
36 
37 /** This is a helper class for the spreadsheet and table samples.
38     It connects to a running office and creates a spreadsheet document.
39     Additionally it contains various helper functions.
40  */
41 public class SpreadsheetDocHelper
42 {
43 
44 // __  private members  ___________________________________________
45 
46     private final String  msDataSheetName  = "Data";
47 
48     private com.sun.star.uno.XComponentContext  mxRemoteContext;
49     private com.sun.star.lang.XMultiComponentFactory  mxRemoteServiceManager;
50 //    private com.sun.star.lang.XMultiServiceFactory  mxMSFactory;
51     private com.sun.star.sheet.XSpreadsheetDocument mxDocument;
52 
53 // ________________________________________________________________
54 
SpreadsheetDocHelper( String[] args )55     public SpreadsheetDocHelper( String[] args )
56     {
57         // Connect to a running office and get the service manager
58         connect();
59 
60         // Create a new spreadsheet document
61         try
62         {
63             mxDocument = initDocument();
64         }
65         catch (Exception ex)
66         {
67             System.err.println( "Couldn't create document: " + ex );
68             System.err.println( "Error: Couldn't create Document\nException Message = "
69                                 + ex.getMessage());
70             ex.printStackTrace();
71             System.exit( 1 );
72         }
73     }
74 
75 // __  helper methods  ____________________________________________
76 
77     /** Returns the service manager of the connected office.
78         @return  XMultiComponentFactory interface of the service manager. */
getServiceManager()79     public com.sun.star.lang.XMultiComponentFactory getServiceManager()
80     {
81         return mxRemoteServiceManager;
82     }
83 
84     /** Returns the component context of the connected office
85         @return  XComponentContext interface of the context. */
getContext()86     public com.sun.star.uno.XComponentContext getContext()
87     {
88         return mxRemoteContext;
89     }
90 
91     /** Returns the whole spreadsheet document.
92         @return  XSpreadsheetDocument interface of the document. */
getDocument()93     public com.sun.star.sheet.XSpreadsheetDocument getDocument()
94     {
95         return mxDocument;
96     }
97 
98     /** Returns the spreadsheet with the specified index (0-based).
99         @param nIndex  The index of the sheet.
100         @return  XSpreadsheet interface of the sheet. */
getSpreadsheet( int nIndex )101     public com.sun.star.sheet.XSpreadsheet getSpreadsheet( int nIndex )
102     {
103         // Collection of sheets
104         com.sun.star.sheet.XSpreadsheets xSheets = mxDocument.getSheets();
105         com.sun.star.sheet.XSpreadsheet xSheet = null;
106         try
107         {
108             com.sun.star.container.XIndexAccess xSheetsIA =
109                 (com.sun.star.container.XIndexAccess)UnoRuntime.queryInterface(
110                     com.sun.star.container.XIndexAccess.class, xSheets );
111             xSheet = (com.sun.star.sheet.XSpreadsheet) UnoRuntime.queryInterface(
112                com.sun.star.sheet.XSpreadsheet.class, xSheetsIA.getByIndex(nIndex));
113         }
114         catch (Exception ex)
115         {
116             System.err.println( "Error: caught exception in getSpreadsheet()!\nException Message = "
117                                 + ex.getMessage());
118             ex.printStackTrace();
119         }
120         return xSheet;
121     }
122 
123     /** Inserts a new empty spreadsheet with the specified name.
124         @param aName  The name of the new sheet.
125         @param nIndex  The insertion index.
126         @return  The XSpreadsheet interface of the new sheet. */
insertSpreadsheet( String aName, short nIndex )127     public com.sun.star.sheet.XSpreadsheet insertSpreadsheet(
128         String aName, short nIndex )
129     {
130         // Collection of sheets
131         com.sun.star.sheet.XSpreadsheets xSheets = mxDocument.getSheets();
132         com.sun.star.sheet.XSpreadsheet xSheet = null;
133         try
134         {
135             xSheets.insertNewByName( aName, nIndex );
136             xSheet = (com.sun.star.sheet.XSpreadsheet)
137                 UnoRuntime.queryInterface(com.sun.star.sheet.XSpreadsheet.class,
138                                           xSheets.getByName( aName ));
139         }
140         catch (Exception ex)
141         {
142             System.err.println( "Error: caught exception in insertSpreadsheet()!\nException Message = "
143                                 + ex.getMessage());
144             ex.printStackTrace();
145         }
146         return xSheet;
147     }
148 
149 // ________________________________________________________________
150 // Methods to fill values into cells.
151 
152     /** Writes a double value into a spreadsheet.
153         @param xSheet  The XSpreadsheet interface of the spreadsheet.
154         @param aCellName  The address of the cell (or a named range).
155         @param fValue  The value to write into the cell. */
setValue( com.sun.star.sheet.XSpreadsheet xSheet, String aCellName, double fValue )156     public void setValue(
157             com.sun.star.sheet.XSpreadsheet xSheet,
158             String aCellName,
159             double fValue ) throws RuntimeException, Exception
160     {
161         xSheet.getCellRangeByName( aCellName ).getCellByPosition( 0, 0 ).setValue( fValue );
162     }
163 
164     /** Writes a formula into a spreadsheet.
165         @param xSheet  The XSpreadsheet interface of the spreadsheet.
166         @param aCellName  The address of the cell (or a named range).
167         @param aFormula  The formula to write into the cell. */
setFormula( com.sun.star.sheet.XSpreadsheet xSheet, String aCellName, String aFormula )168     public void setFormula(
169             com.sun.star.sheet.XSpreadsheet xSheet,
170             String aCellName,
171             String aFormula ) throws RuntimeException, Exception
172     {
173         xSheet.getCellRangeByName( aCellName ).getCellByPosition( 0, 0 ).setFormula( aFormula );
174     }
175 
176     /** Writes a date with standard date format into a spreadsheet.
177         @param xSheet  The XSpreadsheet interface of the spreadsheet.
178         @param aCellName  The address of the cell (or a named range).
179         @param nDay  The day of the date.
180         @param nMonth  The month of the date.
181         @param nYear  The year of the date. */
setDate( com.sun.star.sheet.XSpreadsheet xSheet, String aCellName, int nDay, int nMonth, int nYear )182     public void setDate(
183             com.sun.star.sheet.XSpreadsheet xSheet,
184             String aCellName,
185             int nDay, int nMonth, int nYear ) throws RuntimeException, Exception
186     {
187         // Set the date value.
188         com.sun.star.table.XCell xCell = xSheet.getCellRangeByName( aCellName ).getCellByPosition( 0, 0 );
189         String aDateStr = nMonth + "/" + nDay + "/" + nYear;
190         xCell.setFormula( aDateStr );
191 
192         // Set standard date format.
193         com.sun.star.util.XNumberFormatsSupplier xFormatsSupplier =
194             (com.sun.star.util.XNumberFormatsSupplier) UnoRuntime.queryInterface(
195                 com.sun.star.util.XNumberFormatsSupplier.class, getDocument() );
196         com.sun.star.util.XNumberFormatTypes xFormatTypes =
197             (com.sun.star.util.XNumberFormatTypes) UnoRuntime.queryInterface(
198                 com.sun.star.util.XNumberFormatTypes.class, xFormatsSupplier.getNumberFormats() );
199         int nFormat = xFormatTypes.getStandardFormat(
200             com.sun.star.util.NumberFormat.DATE, new com.sun.star.lang.Locale() );
201 
202         com.sun.star.beans.XPropertySet xPropSet = (com.sun.star.beans.XPropertySet)
203             UnoRuntime.queryInterface( com.sun.star.beans.XPropertySet.class, xCell );
204         xPropSet.setPropertyValue( "NumberFormat", new Integer( nFormat ) );
205     }
206 
207     /** Draws a colored border around the range and writes the headline in the
208         first cell.
209         @param xSheet  The XSpreadsheet interface of the spreadsheet.
210         @param aRange  The address of the cell range (or a named range).
211         @param aHeadline  The headline text. */
prepareRange( com.sun.star.sheet.XSpreadsheet xSheet, String aRange, String aHeadline )212     public void prepareRange(
213             com.sun.star.sheet.XSpreadsheet xSheet,
214             String aRange, String aHeadline ) throws RuntimeException, Exception
215     {
216         com.sun.star.beans.XPropertySet xPropSet = null;
217         com.sun.star.table.XCellRange xCellRange = null;
218 
219         // draw border
220         xCellRange = xSheet.getCellRangeByName( aRange );
221         xPropSet = (com.sun.star.beans.XPropertySet)
222             UnoRuntime.queryInterface( com.sun.star.beans.XPropertySet.class, xCellRange );
223         com.sun.star.table.BorderLine aLine = new com.sun.star.table.BorderLine();
224         aLine.Color = 0x99CCFF;
225         aLine.InnerLineWidth = aLine.LineDistance = 0;
226         aLine.OuterLineWidth = 100;
227         com.sun.star.table.TableBorder aBorder = new com.sun.star.table.TableBorder();
228         aBorder.TopLine = aBorder.BottomLine = aBorder.LeftLine = aBorder.RightLine = aLine;
229         aBorder.IsTopLineValid = aBorder.IsBottomLineValid = true;
230         aBorder.IsLeftLineValid = aBorder.IsRightLineValid = true;
231         xPropSet.setPropertyValue( "TableBorder", aBorder );
232 
233         // draw headline
234         com.sun.star.sheet.XCellRangeAddressable xAddr = (com.sun.star.sheet.XCellRangeAddressable)
235             UnoRuntime.queryInterface( com.sun.star.sheet.XCellRangeAddressable.class, xCellRange );
236         com.sun.star.table.CellRangeAddress aAddr = xAddr.getRangeAddress();
237 
238         xCellRange = xSheet.getCellRangeByPosition(
239             aAddr.StartColumn, aAddr.StartRow, aAddr.EndColumn, aAddr.StartRow );
240         xPropSet = (com.sun.star.beans.XPropertySet)
241             UnoRuntime.queryInterface( com.sun.star.beans.XPropertySet.class, xCellRange );
242         xPropSet.setPropertyValue( "CellBackColor", new Integer( 0x99CCFF ) );
243         // write headline
244         com.sun.star.table.XCell xCell = xCellRange.getCellByPosition( 0, 0 );
245         xCell.setFormula( aHeadline );
246         xPropSet = (com.sun.star.beans.XPropertySet)
247             UnoRuntime.queryInterface( com.sun.star.beans.XPropertySet.class, xCell );
248         xPropSet.setPropertyValue( "CharColor", new Integer( 0x003399 ) );
249         xPropSet.setPropertyValue( "CharWeight", new Float( com.sun.star.awt.FontWeight.BOLD ) );
250     }
251 
252 // ________________________________________________________________
253 // Methods to create cell addresses and range addresses.
254 
255     /** Creates a com.sun.star.table.CellAddress and initializes it
256         with the given range.
257         @param xSheet  The XSpreadsheet interface of the spreadsheet.
258         @param aCell  The address of the cell (or a named cell). */
createCellAddress( com.sun.star.sheet.XSpreadsheet xSheet, String aCell )259     public com.sun.star.table.CellAddress createCellAddress(
260             com.sun.star.sheet.XSpreadsheet xSheet,
261             String aCell ) throws RuntimeException, Exception
262     {
263         com.sun.star.sheet.XCellAddressable xAddr = (com.sun.star.sheet.XCellAddressable)
264             UnoRuntime.queryInterface( com.sun.star.sheet.XCellAddressable.class,
265                 xSheet.getCellRangeByName( aCell ).getCellByPosition( 0, 0 ) );
266         return xAddr.getCellAddress();
267     }
268 
269     /** Creates a com.sun.star.table.CellRangeAddress and initializes
270         it with the given range.
271         @param xSheet  The XSpreadsheet interface of the spreadsheet.
272         @param aRange  The address of the cell range (or a named range). */
createCellRangeAddress( com.sun.star.sheet.XSpreadsheet xSheet, String aRange )273     public com.sun.star.table.CellRangeAddress createCellRangeAddress(
274             com.sun.star.sheet.XSpreadsheet xSheet, String aRange )
275     {
276         com.sun.star.sheet.XCellRangeAddressable xAddr = (com.sun.star.sheet.XCellRangeAddressable)
277             UnoRuntime.queryInterface( com.sun.star.sheet.XCellRangeAddressable.class,
278                 xSheet.getCellRangeByName( aRange ) );
279         return xAddr.getRangeAddress();
280     }
281 
282 // ________________________________________________________________
283 // Methods to convert cell addresses and range addresses to strings.
284 
285     /** Returns the text address of the cell.
286         @param nColumn  The column index.
287         @param nRow  The row index.
288         @return  A string containing the cell address. */
getCellAddressString( int nColumn, int nRow )289     public String getCellAddressString( int nColumn, int nRow )
290     {
291         String aStr = "";
292         if (nColumn > 25)
293             aStr += (char) ('A' + nColumn / 26 - 1);
294         aStr += (char) ('A' + nColumn % 26);
295         aStr += (nRow + 1);
296         return aStr;
297     }
298 
299     /** Returns the text address of the cell range.
300         @param aCellRange  The cell range address.
301         @return  A string containing the cell range address. */
getCellRangeAddressString( com.sun.star.table.CellRangeAddress aCellRange )302     public String getCellRangeAddressString(
303             com.sun.star.table.CellRangeAddress aCellRange )
304     {
305         return
306             getCellAddressString( aCellRange.StartColumn, aCellRange.StartRow )
307             + ":"
308             + getCellAddressString( aCellRange.EndColumn, aCellRange.EndRow );
309     }
310 
311     /** Returns the text address of the cell range.
312         @param xCellRange  The XSheetCellRange interface of the cell range.
313         @param bWithSheet  true = Include sheet name.
314         @return  A string containing the cell range address. */
getCellRangeAddressString( com.sun.star.sheet.XSheetCellRange xCellRange, boolean bWithSheet )315     public String getCellRangeAddressString(
316             com.sun.star.sheet.XSheetCellRange xCellRange,
317             boolean bWithSheet )
318     {
319         String aStr = "";
320         if (bWithSheet)
321         {
322             com.sun.star.sheet.XSpreadsheet xSheet = xCellRange.getSpreadsheet();
323             com.sun.star.container.XNamed xNamed = (com.sun.star.container.XNamed)
324                 UnoRuntime.queryInterface( com.sun.star.container.XNamed.class, xSheet );
325             aStr += xNamed.getName() + ".";
326         }
327         com.sun.star.sheet.XCellRangeAddressable xAddr = (com.sun.star.sheet.XCellRangeAddressable)
328             UnoRuntime.queryInterface( com.sun.star.sheet.XCellRangeAddressable.class, xCellRange );
329         aStr += getCellRangeAddressString( xAddr.getRangeAddress() );
330         return aStr;
331     }
332 
333     /** Returns a list of addresses of all cell ranges contained in the collection.
334         @param xRangesIA  The XIndexAccess interface of the collection.
335         @return  A string containing the cell range address list. */
getCellRangeListString( com.sun.star.container.XIndexAccess xRangesIA )336     public String getCellRangeListString(
337             com.sun.star.container.XIndexAccess xRangesIA ) throws RuntimeException, Exception
338     {
339         String aStr = "";
340         int nCount = xRangesIA.getCount();
341         for (int nIndex = 0; nIndex < nCount; ++nIndex)
342         {
343             if (nIndex > 0)
344                 aStr += " ";
345             Object aRangeObj = xRangesIA.getByIndex( nIndex );
346             com.sun.star.sheet.XSheetCellRange xCellRange = (com.sun.star.sheet.XSheetCellRange)
347                 UnoRuntime.queryInterface( com.sun.star.sheet.XSheetCellRange.class, aRangeObj );
348             aStr += getCellRangeAddressString( xCellRange, false );
349         }
350         return aStr;
351     }
352 
353 // ________________________________________________________________
354 
355     // Connect to a running office that is accepting connections.
connect()356     private void connect()
357     {
358         if (mxRemoteContext == null && mxRemoteServiceManager == null) {
359             try {
360                 // First step: get the remote office component context
361                 mxRemoteContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
362                 System.out.println("Connected to a running office ...");
363 
364                 mxRemoteServiceManager = mxRemoteContext.getServiceManager();
365             }
366             catch( Exception e) {
367                 System.err.println("ERROR: can't get a component context from a running office ...");
368                 e.printStackTrace();
369                 System.exit(1);
370             }
371         }
372     }
373 
374     /** Creates an empty spreadsheet document.
375         @return  The XSpreadsheetDocument interface of the document. */
initDocument()376     private com.sun.star.sheet.XSpreadsheetDocument initDocument()
377             throws RuntimeException, Exception
378     {
379         XComponentLoader aLoader = (XComponentLoader)
380             UnoRuntime.queryInterface(
381                 XComponentLoader.class,
382                 mxRemoteServiceManager.createInstanceWithContext(
383                     "com.sun.star.frame.Desktop", mxRemoteContext));
384 
385         XComponent xComponent = aLoader.loadComponentFromURL(
386             "private:factory/scalc", "_blank", 0,
387             new com.sun.star.beans.PropertyValue[0] );
388 
389         return (com.sun.star.sheet.XSpreadsheetDocument)UnoRuntime.queryInterface(
390             com.sun.star.sheet.XSpreadsheetDocument.class, xComponent );
391     }
392 
393 // ________________________________________________________________
394 }
395