OOo/LibreOffice UNO / Java:如何调用计算函数的电子表格单元格?

在用Java编写的OpenOffice/LibreOffice Calc(电子表格)的UNO扩展中,如何确定UDF(电子表格函数)实现中的调用单元?

言论

  • 在Excel / VBA中,这是可能的Application.Caller
  • 获取调用方的主要动机是日志记录/跟踪/调试,即,将调用单元作为堆栈跟踪的一部分进行查看。
  • 应该可以获得此信息,因为像“ROW()”和“COLUMN()”这样的内置函数确实对调用单元有一些了解。
  • 使用这种可能性(对于Excel)的应用程序是Obba,它是电子表格的对象处理程序。这里的“控制面板”提供了(Java)异常的列表,包括调用单元,,该单元是堆栈跟踪的一部分。请参阅以下屏幕截图:

Obba Control Panel showing exceptions by spreadsheet cell of calling function

这也是Apache OpenOffice Bugzilla上的一个功能请求。


答案 1

看起来您想要将侦听器注册到电子表格组件。为了满足您的目标,您可以将侦听器添加到电子表格对象本身,或者添加到另一个实现支持 add.+EventListener() 方法的接口的嵌套对象。

下面是一对(广播员/听众),我认为你可以在你的项目中使用:XDocumentEventBroadcaster/XDocumentEventListener

UNO 事件模型解释如下:https://wiki.openoffice.org/wiki/Documentation/DevGuide/ProUNO/Event_Model

以下是如何使用这些侦听器的示例。

    //////////////////////////////////////////////////////////////////// 
    // Add document window listeners. 
    //////////////////////////////////////////////////////////////////// 

    System.out.println("WriterDoc: Add window listeners."); 

    // Example of adding a document displose listener so the application 
    // can know if the user manually exits the Writer window. 

    document.addEventListener(new XEventListener() { 
        public void disposing(EventObject e) { 
            System.out.println( 
                    "WriterDoc (Event Listener): The document window is closing."); 
        } 
    }); 

    // Example of adding a window listener so the application can know 
    // when the document becomes initially visible (in the case of this 
    // implementation, we will manually set it visible below after we 
    // finish building it). 

    window.addWindowListener(new XWindowListener() { 
        public void windowShown(com.sun.star.lang.EventObject e) { 
            System.out.println( 
                    "WriterDoc (Window listener): The document window has become visible."); 
        } 
        public void windowHidden(com.sun.star.lang.EventObject e) { } 
        public void disposing(com.sun.star.lang.EventObject e) { } 
        public void windowResized(com.sun.star.awt.WindowEvent e) { } 
        public void windowMoved(com.sun.star.awt.WindowEvent e) { } 
    }); 

此外,服务SheetCellRange支持接口XModifyBroadcaster。也许你可以得到所需的行为,如果你注册了一个XModifyListener对象。该对象将实现'modified'方法,该方法在调用时接收事件对象。我相信你可以从 EventObject 的源属性中获取调用方是谁。如果源被证明是整个SheetCellRange,您可以尝试遍历您希望监视的所有单元格,并向每个单元格添加XModifyListener。SheetCell 服务还支持 XModifyBroadcaster 接口 。

从 CellRange 使用 XModifyBroadcaster 的示例:http://openoffice.2283327.n4.nabble.com/Re-How-to-get-the-XModifyBroadcaster-from-Cell-CellRange-Table-td2771959.html

干杯!


答案 2

推荐