Difference between revisions of "Groovy UNO Extension"

From Apache OpenOffice Wiki
Jump to: navigation, search
(updated overview section (checkpoint save))
(added source tags (checkpoint save))
Line 18: Line 18:
 
The example leaves out the try/catch for brevity and assumes we have a reference to XSpreadsheetDocument myDoc..<br />
 
The example leaves out the try/catch for brevity and assumes we have a reference to XSpreadsheetDocument myDoc..<br />
 
Java way
 
Java way
    XSpreadsheets xSheets = myDoc.getSheets() ;
+
<source lang="java">
    XIndexAccess oIndexSheets = (XIndexAccess) UnoRuntime.queryInterface(
+
XSpreadsheets xSheets = myDoc.getSheets() ;
        XIndexAccess.class, xSheets);
+
XIndexAccess oIndexSheets = (XIndexAccess) UnoRuntime.queryInterface(
    xSheet = (XSpreadsheet) UnoRuntime.queryInterface(
+
    XIndexAccess.class, xSheets);
      XSpreadsheet.class, oIndexSheets.getByIndex(0));
+
xSheet = (XSpreadsheet) UnoRuntime.queryInterface(
    xCell = xSheet.getCellByPosition(1,0);
+
  XSpreadsheet.class, oIndexSheets.getByIndex(0));
    xCell.setFormula("Sample");
+
xCell = xSheet.getCellByPosition(1,0);
 
+
xCell.setFormula("Sample");
 +
</source>
  
 
Groovy Extension way
 
Groovy Extension way
    XSpreadsheet xSheet = myDoc.getSheetByIndex(0)
+
<source lang="java">
    xSheet.setTextToCell(1,0,"Sample")
+
XSpreadsheet xSheet = myDoc.getSheetByIndex(0)
 +
xSheet.setTextToCell(1,0,"Sample")
 +
</source>
  
 
Using Groovy without the extension allows removing the Interface cast on the right side and not using semi-colons.<br />
 
Using Groovy without the extension allows removing the Interface cast on the right side and not using semi-colons.<br />
Line 37: Line 40:
 
The extension adds a setter method for CellStyle allowing what looks like property access to cellStyle. (ToDo add getter method)<br />
 
The extension adds a setter method for CellStyle allowing what looks like property access to cellStyle. (ToDo add getter method)<br />
 
Without Extension
 
Without Extension
  XPropertySet xCellProps = UnoRuntime.queryInterface(XPropertySet.class, xCell)
+
<source lang="java">
  xCellProps.setPropertyValue("CellStyle", "Result")
+
XPropertySet xCellProps = UnoRuntime.queryInterface(XPropertySet.class, xCell)
 
+
xCellProps.setPropertyValue("CellStyle", "Result")
 +
</source>
 
With extension
 
With extension
 +
<source lang="java">
 
   xCell.cellStyle = "Result"
 
   xCell.cellStyle = "Result"
 
+
</source>
  
 
'''Using Enum Types'''<br />
 
'''Using Enum Types'''<br />
 
The extension adds getter and setter methods for CellVertJustify allowing what looks like property access to vertJustify.<br />
 
The extension adds getter and setter methods for CellVertJustify allowing what looks like property access to vertJustify.<br />
 
Without extension
 
Without extension
    xCellProps.setPropertyValue("VertJustify", com.sun.star.table.CellVertJustify.TOP)
+
<source lang="java">
 +
xCellProps.setPropertyValue("VertJustify", com.sun.star.table.CellVertJustify.TOP)
 +
</source>
 
With extension
 
With extension
    xCell.vertJustify = com.sun.star.table.CellVertJustify.TOP
+
<source lang="java">
 
+
xCell.vertJustify = com.sun.star.table.CellVertJustify.TOP
 +
</source>
  
 
'''Setting the active sheet'''<br />
 
'''Setting the active sheet'''<br />
 
Without Extension but using SpreadsheetDocHelper.groovy included with the [[OpenOffice_Gradle_Integration]] aoo-client template.
 
Without Extension but using SpreadsheetDocHelper.groovy included with the [[OpenOffice_Gradle_Integration]] aoo-client template.
    XModel xSpreadsheetModel = sdHelper.getModel()
+
<source lang="java">
    XController xSpreadsheetController = xSpreadsheetModel.getCurrentController()
+
XModel xSpreadsheetModel = sdHelper.getModel()
    XSpreadsheetView xSpreadsheetView = UnoRuntime.queryInterface(XSpreadsheetView.class, xSpreadsheetController)
+
XController xSpreadsheetController = xSpreadsheetModel.getCurrentController()
    xSpreadsheetView.setActiveSheet(xSpreadsheet)
+
XSpreadsheetView xSpreadsheetView = UnoRuntime.queryInterface(XSpreadsheetView.class, xSpreadsheetController)
 
+
xSpreadsheetView.setActiveSheet(xSpreadsheet)
 +
</source>
 
With extension and a SpreadsheetDocHelper.groovy method to get the XSpreadsheetView directly
 
With extension and a SpreadsheetDocHelper.groovy method to get the XSpreadsheetView directly
    XSpreadsheetView xSpreadsheetView = sdHelper.getSpreadsheetView()
+
<source lang="java">
    xSpreadsheetView.setActiveSheet(xSpreadsheet)
+
XSpreadsheetView xSpreadsheetView = sdHelper.getSpreadsheetView()
 
+
xSpreadsheetView.setActiveSheet(xSpreadsheet)
 +
</source>
  
 
'''Get cell ranges'''<br />
 
'''Get cell ranges'''<br />
 
Without extension
 
Without extension
    XCellRangesQuery xCellQuery = UnoRuntime.queryInterface(XCellRangesQuery.class, xSpreadsheet)
+
<source lang="java">
    XSheetCellRanges xFormulaCells = xCellQuery.queryContentCells((short)CellFlags.FORMULA)
+
XCellRangesQuery xCellQuery = UnoRuntime.queryInterface(XCellRangesQuery.class, xSpreadsheet)
 
+
XSheetCellRanges xFormulaCells = xCellQuery.queryContentCells((short)CellFlags.FORMULA)
 +
</source>
 
With extension
 
With extension
    XSheetCellRanges xFormulaCells = xSpreadsheet.getCellRanges(CellFlags.FORMULA)
+
<source lang="java">
 
+
XSheetCellRanges xFormulaCells = xSpreadsheet.getCellRanges(CellFlags.FORMULA)
 +
</source>
 
'''Use of XEnumerationAccess'''<br />
 
'''Use of XEnumerationAccess'''<br />
 
Without extension we get an Enumeration and use it iterate through Cells
 
Without extension we get an Enumeration and use it iterate through Cells
    XEnumerationAccess xFormulas = xFormulaCells.getCells()
+
<source lang="java">
    XEnumeration xFormulaEnum = xFormulas.createEnumeration()
+
XEnumerationAccess xFormulas = xFormulaCells.getCells()
    while (xFormulaEnum.hasMoreElements()) {
+
XEnumeration xFormulaEnum = xFormulas.createEnumeration()
        Object formulaCell = xFormulaEnum.nextElement()
+
while (xFormulaEnum.hasMoreElements()) {
        xCell = UnoRuntime.queryInterface(XCell.class, formulaCell)
+
    Object formulaCell = xFormulaEnum.nextElement()
        XCellAddressable xCellAddress = UnoRuntime.queryInterface(XCellAddressable.class, xCell)
+
    xCell = UnoRuntime.queryInterface(XCell.class, formulaCell)
        println("Formula cell in column " +
+
    XCellAddressable xCellAddress = UnoRuntime.queryInterface(XCellAddressable.class, xCell)
            xCellAddress.getCellAddress().Column + ", row " + xCellAddress.getCellAddress().Row
+
    println("Formula cell in column " +
            + " contains " + xCell.getFormula())
+
        xCellAddress.getCellAddress().Column + ", row " + xCellAddress.getCellAddress().Row
        }
+
        + " contains " + xCell.getFormula())
 
+
}
 +
</source>
 
With extension we can use a List provided by a new method and a closure to iterate through each cell
 
With extension we can use a List provided by a new method and a closure to iterate through each cell
    XCell[] cellList = xFormulaCells.cellList
+
<source lang="java">
    cellList.each() {println("Formula cell in column ${it.address.Column}, " +  
+
XCell[] cellList = xFormulaCells.cellList
        "row ${it.address.Row} contains ${it.formula}")
+
cellList.each() {println("Formula cell in column ${it.address.Column}, " +  
    }
+
    "row ${it.address.Row} contains ${it.formula}")
 
+
}
 +
</source>
 
'''Create a new cell range container, add all cells that are filled, and iterate through them'''<br />
 
'''Create a new cell range container, add all cells that are filled, and iterate through them'''<br />
 
Without Extension
 
Without Extension
    com.sun.star.lang.XMultiServiceFactory xDocFactory = UnoRuntime.queryInterface(
+
<source lang="java">
        com.sun.star.lang.XMultiServiceFactory.class, xSpreadsheetDocument)
+
com.sun.star.lang.XMultiServiceFactory xDocFactory = UnoRuntime.queryInterface(
    com.sun.star.sheet.XSheetCellRangeContainer xRangeCont = UnoRuntime.queryInterface(
+
    com.sun.star.lang.XMultiServiceFactory.class, xSpreadsheetDocument)
        com.sun.star.sheet.XSheetCellRangeContainer.class,
+
com.sun.star.sheet.XSheetCellRangeContainer xRangeCont = UnoRuntime.queryInterface(
        xDocFactory.createInstance("com.sun.star.sheet.SheetCellRanges"));
+
    com.sun.star.sheet.XSheetCellRangeContainer.class,
    xRangeCont.addRangeAddresses(xCellRanges.rangeAddresses, false)
+
    xDocFactory.createInstance("com.sun.star.sheet.SheetCellRanges"));
    print("All filled cells: ")
+
xRangeCont.addRangeAddresses(xCellRanges.rangeAddresses, false)
    com.sun.star.container.XEnumerationAccess xCellsEA = xRangeCont.getCells()
+
print("All filled cells: ")
    com.sun.star.container.XEnumeration xEnum = xCellsEA.createEnumeration()           
+
com.sun.star.container.XEnumerationAccess xCellsEA = xRangeCont.getCells()
    while (xEnum.hasMoreElements()) {
+
com.sun.star.container.XEnumeration xEnum = xCellsEA.createEnumeration()           
        Object aCellObj = xEnum.nextElement()
+
while (xEnum.hasMoreElements()) {
        com.sun.star.sheet.XCellAddressable xAddr = UnoRuntime.queryInterface(
+
    Object aCellObj = xEnum.nextElement()
            com.sun.star.sheet.XCellAddressable.class, aCellObj)
+
    com.sun.star.sheet.XCellAddressable xAddr = UnoRuntime.queryInterface(
        com.sun.star.table.CellAddress aAddr = xAddr.getCellAddress()
+
        com.sun.star.sheet.XCellAddressable.class, aCellObj)
        println(sdHelper.getCellAddressString(aAddr.Column, aAddr.Row) + " ")
+
    com.sun.star.table.CellAddress aAddr = xAddr.getCellAddress()
    }
+
    println(sdHelper.getCellAddressString(aAddr.Column, aAddr.Row) + " ")
 
+
}
 +
</source>
 
With extension
 
With extension
    XSheetCellRangeContainer xRangeCont = xSpreadsheetDocument.rangeContainer
+
<source lang="java">
    XSheetCellRanges xCellRanges = xSpreadsheet.getCellRanges(1023)
+
XSheetCellRangeContainer xRangeCont = xSpreadsheetDocument.rangeContainer
    XCell[] cellList2 = xRangeCont.cellList
+
XSheetCellRanges xCellRanges = xSpreadsheet.getCellRanges(1023)
    print("All filled cells: ")
+
XCell[] cellList2 = xRangeCont.cellList
    cellList2.each() {println("Formula cell in column ${it.address.Column}, " +  
+
print("All filled cells: ")
        "row ${it.address.Row} contains ${it.formula}")
+
cellList2.each() {println("Formula cell in column ${it.address.Column}, " +  
    }
+
    "row ${it.address.Row} contains ${it.formula}")
 
+
}
 +
</source>
 
[[Category:API]]
 
[[Category:API]]
 
[[Category:Effort]]
 
[[Category:Effort]]

Revision as of 16:23, 28 February 2016

Overview

This is an Apache Groovy language extension of the Java UNO API's and should not be confused with GroovyForOpenOffice which is an OpenOffice extension added to OpenOffice itself. The artifact of this extension is a Java jar file that when used in a Groovy script or class adds convenience methods to the regular Java UNO API's.

The goal of the Groovy UNO Extension is to allow UNO programming that is less verbose than using the Java UNO API's alone.

These methods are implemented using Groovy Extension Modules. An extension module allows you to add new methods to existing classes, including classes which are precompiled, like classes from the JDK or in this case Java UNO classes. These new methods, unlike those defined through a metaclass or using a category, are available globally.

Aside from a few general methods, initial efforts have been on enhancing the spreadsheet API's and future work will be on enhancing the other applications.

Getting Started

The Extension is a Gradle based project and information about checking it out of Apache SVN can be found on the OpenOffice_Gradle_Integration page.

Usage

The best way to explain the differences between the Java UNO API's and using Groovy with and without the extension is with some example code. Many of the examples are from SCalc.java that is included with the AOO SDK.

Get the first sheet in the spreadsheet document and insert data into a cell
The example leaves out the try/catch for brevity and assumes we have a reference to XSpreadsheetDocument myDoc..
Java way

XSpreadsheets xSheets = myDoc.getSheets() ;
XIndexAccess oIndexSheets = (XIndexAccess) UnoRuntime.queryInterface(
    XIndexAccess.class, xSheets);
xSheet = (XSpreadsheet) UnoRuntime.queryInterface(
   XSpreadsheet.class, oIndexSheets.getByIndex(0));
xCell = xSheet.getCellByPosition(1,0);
xCell.setFormula("Sample");

Groovy Extension way

XSpreadsheet xSheet = myDoc.getSheetByIndex(0)
xSheet.setTextToCell(1,0,"Sample")

Using Groovy without the extension allows removing the Interface cast on the right side and not using semi-colons.
The following examples are in that style and other than that, similar to the Java way.

Setting the Cell Style property
The extension adds a setter method for CellStyle allowing what looks like property access to cellStyle. (ToDo add getter method)
Without Extension

XPropertySet xCellProps = UnoRuntime.queryInterface(XPropertySet.class, xCell)
xCellProps.setPropertyValue("CellStyle", "Result")

With extension

   xCell.cellStyle = "Result"

Using Enum Types
The extension adds getter and setter methods for CellVertJustify allowing what looks like property access to vertJustify.
Without extension

xCellProps.setPropertyValue("VertJustify", com.sun.star.table.CellVertJustify.TOP)

With extension

xCell.vertJustify = com.sun.star.table.CellVertJustify.TOP

Setting the active sheet
Without Extension but using SpreadsheetDocHelper.groovy included with the OpenOffice_Gradle_Integration aoo-client template.

XModel xSpreadsheetModel = sdHelper.getModel()
XController xSpreadsheetController = xSpreadsheetModel.getCurrentController()
XSpreadsheetView xSpreadsheetView = UnoRuntime.queryInterface(XSpreadsheetView.class, xSpreadsheetController)
xSpreadsheetView.setActiveSheet(xSpreadsheet)

With extension and a SpreadsheetDocHelper.groovy method to get the XSpreadsheetView directly

XSpreadsheetView xSpreadsheetView = sdHelper.getSpreadsheetView()
xSpreadsheetView.setActiveSheet(xSpreadsheet)

Get cell ranges
Without extension

XCellRangesQuery xCellQuery = UnoRuntime.queryInterface(XCellRangesQuery.class, xSpreadsheet)
XSheetCellRanges xFormulaCells = xCellQuery.queryContentCells((short)CellFlags.FORMULA)

With extension

XSheetCellRanges xFormulaCells = xSpreadsheet.getCellRanges(CellFlags.FORMULA)

Use of XEnumerationAccess
Without extension we get an Enumeration and use it iterate through Cells

XEnumerationAccess xFormulas = xFormulaCells.getCells()
XEnumeration xFormulaEnum = xFormulas.createEnumeration()
while (xFormulaEnum.hasMoreElements()) {
    Object formulaCell = xFormulaEnum.nextElement()
    xCell = UnoRuntime.queryInterface(XCell.class, formulaCell)
    XCellAddressable xCellAddress = UnoRuntime.queryInterface(XCellAddressable.class, xCell)
    println("Formula cell in column " +
        xCellAddress.getCellAddress().Column + ", row " + xCellAddress.getCellAddress().Row
        + " contains " + xCell.getFormula())
}

With extension we can use a List provided by a new method and a closure to iterate through each cell

XCell[] cellList = xFormulaCells.cellList
cellList.each() {println("Formula cell in column ${it.address.Column}, " + 
    "row ${it.address.Row} contains ${it.formula}")
}

Create a new cell range container, add all cells that are filled, and iterate through them
Without Extension

com.sun.star.lang.XMultiServiceFactory xDocFactory = UnoRuntime.queryInterface(
    com.sun.star.lang.XMultiServiceFactory.class, xSpreadsheetDocument)
com.sun.star.sheet.XSheetCellRangeContainer xRangeCont = UnoRuntime.queryInterface(
    com.sun.star.sheet.XSheetCellRangeContainer.class,
    xDocFactory.createInstance("com.sun.star.sheet.SheetCellRanges"));
xRangeCont.addRangeAddresses(xCellRanges.rangeAddresses, false)
print("All filled cells: ")
com.sun.star.container.XEnumerationAccess xCellsEA = xRangeCont.getCells()
com.sun.star.container.XEnumeration xEnum = xCellsEA.createEnumeration()          
while (xEnum.hasMoreElements()) {
    Object aCellObj = xEnum.nextElement()
    com.sun.star.sheet.XCellAddressable xAddr = UnoRuntime.queryInterface(
        com.sun.star.sheet.XCellAddressable.class, aCellObj)
    com.sun.star.table.CellAddress aAddr = xAddr.getCellAddress()
    println(sdHelper.getCellAddressString(aAddr.Column, aAddr.Row) + " ")
}

With extension

XSheetCellRangeContainer xRangeCont = xSpreadsheetDocument.rangeContainer
XSheetCellRanges xCellRanges = xSpreadsheet.getCellRanges(1023)
XCell[] cellList2 = xRangeCont.cellList
print("All filled cells: ")
cellList2.each() {println("Formula cell in column ${it.address.Column}, " + 
    "row ${it.address.Row} contains ${it.formula}")
}
Personal tools