如何使用 UNO 获取打开的文档?

Posted

技术标签:

【中文标题】如何使用 UNO 获取打开的文档?【英文标题】:How to get the opened document using UNO? 【发布时间】:2015-09-22 13:55:20 【问题描述】:

我正在编写一个打开对话框的插件,我需要访问当前打开的文本文档,但我不知道如何获取它。

我在 NetBeans 中使用 OpenOffice 插件,并且从一个附加项目开始。它创建了一个类,它为我提供了一个 XComponentContext 实例,但我不知道如何使用它来获取当前文档的 OfficeDocument 实例。

我已经在谷歌上搜索了一段时间,但找不到任何使用现有打开文档的示例。它们都从一个新文档或首先加载的文档开始,因此它们有一个 URL。

我根据 OpenOffice wiki (https://wiki.openoffice.org/wiki/API/Samples/Java/Office/DocumentHandling) 试了一下,结果如下:

private OfficeDocument getDocument() 
  if (this.officeDocument == null) 
    try 
        // this causes the error
        XMultiComponentFactory xMultiComponentFactory = this.xComponentContext.getServiceManager();

        Object oDesktop = xMultiComponentFactory.createInstanceWithContext("com.sun.star.frame.Desktop", this.xComponentContext);
        XComponentLoader xComponentLoader = UnoRuntime.queryInterface(XComponentLoader.class, oDesktop);

        String url = "private:factory/swriter";
        String targetFrameName = "_self";
        int searchFlags = FrameSearchFlag.SELF;
        PropertyValue[] propertyValues = new PropertyValue[1];
        propertyValues[0] = new PropertyValue();
        propertyValues[0].Name = "Hidden";
        propertyValues[0].Value = Boolean.TRUE;

        XComponent xComponent = xComponentLoader.loadComponentFromURL(url, targetFrameName, searchFlags, propertyValues);

        XModel xModel = UnoRuntime.queryInterface(XModel.class, xComponent);
        this.officeDocument = new OfficeDocument(xModel);
     catch (com.sun.star.uno.Exception ex) 
        throw new RuntimeException(ex);
    
  
  return this.officeDocument;

但是发生了一些奇怪的事情。仅在我的类中使用此方法,即使它从未在任何地方调用过,在添加插件时也会导致错误。

(com.sun.star.depoyment.DeploymentDescription) Message = "Error during activation of: VaphAddOn.jar", Context = (com.sun.star.uno.XInterface) @6ce03e0 , Cause = (any) (com.sun.star.registry.CannotRegisterImplementationException) Message = "", Context = (com.sun.star.uno.XInterface) @0 

这行似乎会导致错误:

XMultiComponentFactory xMultiComponentFactory = this.xComponentContext.getServiceManager();

我不知道如何继续。

我在OpenOffice forum 上发布了这个问题,但那里没有得到回复。我现在在这里试试运气。

【问题讨论】:

【参考方案1】:

在您的代码中使用它来获取当前文档:

import com.sun.star.frame.XDesktop;
...
XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, oDesktop);
XComponent xComponent = xDesktop.getCurrentComponent();

我在 NetBeans 中打开 the BookmarkInsertion sample 并添加此代码以使用当前文档而不是加载新文档。

就错误而言,它的构建方式可能存在问题。有几件事要检查:

Office SDK 版本是否与 Office 版本匹配?检查版本号以及它是 32 位还是 64 位。 确保 4 个 .jar 文件(juh.jar、jurt.jar、unoil.jar、ridl.jar)显示在 NetBeans 的库下,因为它们需要与插件一起包含。

如果您对尝试正确设置构建感到沮丧,那么您可能会发现使用 python 更容易,因为它不需要编译。 python也不需要queryInterface()。

【讨论】:

以上是关于如何使用 UNO 获取打开的文档?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 UNO 遍历 OpenOffice/LibreOffice 中的整个文档

如何通过 UNO 更改文档名称?

使用 UNO 在同一窗口中打开多个文档

Python libreoffice 使用 uno 设置边距值、最佳高度和打印文档

如何获取 Uno CheckBox 控件的名称和标签?

Libreoffice API (UNO):来自 xTextField 的文本和数据