How to get the opened document using UNO?

2020-04-21 06:38发布

问题:

I'm writing an add-on that opens a dialog and I need to access the currently opened text document but I don't know how get it.

I'm using the OpenOffice plug-in in NetBeans and I started from an Add-on project. It created a class that gives me a XComponentContext instance but I don't know how to use it to get a OfficeDocument instance of the current document.

I've been googling for some time and I can't find any example that uses an existing, opened, document. They all start from a new document or a document that is loaded first so they have an URL for it.

I gave it a try based on the OpenOffice wiki (https://wiki.openoffice.org/wiki/API/Samples/Java/Office/DocumentHandling) and this is what I came up with:

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;
}

But there is something strange going on. Just having this method in my class, even if it's never been called anywhere, causes an error when adding the add-on.

(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 }}}}

It seems this line causes the error:

XMultiComponentFactory xMultiComponentFactory = this.xComponentContext.getServiceManager();

I have no idea how to preceed.

I posted this question on the OpenOffice forum but I haven't got a response there. I'm trying my luck here now.

回答1:

Use this in your code to get the current document:

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

I opened the BookmarkInsertion sample in NetBeans and added this code to use the current document instead of loading a new document.

As far as the error, there may be a problem with how it is getting built. A couple of things to check:

  • Does the Office SDK version match the Office version? Check version number and whether it's 32- or 64-bit.
  • Make sure that 4 .jar files (juh.jar, jurt.jar, unoil.jar, ridl.jar) are shown under Libraries in NetBeans, because they need to be included along with the add-on.

If you get frustrated with trying to get the build set up correctly, then you might find it easier to use python, since it doesn't need to be compiled. Also python does not require queryInterface().