Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LibreOffice UNO Java API: how to open a document, execute a macro and close it?

I'm working on LibreOffice server-side: on the server I run

soffice --accept=...

Then I use Java LibreOffice client API's to apply a macro on a document (calc or writer). The java execution does not give any error, but I do not get the job done (macro code is executed, but it's effects are not in the output file). More, after macro script is invoked, the Basic debugger window appears, apparently stopped on the first line of my macro; F5 does not restart it...

This is the relevant code I'm using:

    try {
        XComponentContext xLocalContext = Bootstrap.createInitialComponentContext(null);
        System.out.println("xLocalContext");

        XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager();
        System.out.println("xLocalServiceManager");

        Object urlResolver = xLocalServiceManager.createInstanceWithContext(
                "com.sun.star.bridge.UnoUrlResolver", xLocalContext);
        System.out.println("urlResolver");

        XUnoUrlResolver xUrlResolver =
            (XUnoUrlResolver) UnoRuntime.queryInterface(XUnoUrlResolver.class, urlResolver);            
        System.out.println("xUrlResolve");

        try {
            String uno = "uno:" + unoMode + ",host=" + unoHost + ",port=" + unoPort + ";" + unoProtocol + ";" + unoObjectName;
            Object rInitialObject = xUrlResolver.resolve(uno);
            System.out.println("rInitialObject");

            if (null != rInitialObject) {
                XMultiComponentFactory xOfficeFactory = (XMultiComponentFactory) UnoRuntime.queryInterface(
                    XMultiComponentFactory.class, rInitialObject);
                System.out.println("xOfficeFactory");

                Object desktop = xOfficeFactory.createInstanceWithContext("com.sun.star.frame.Desktop", xLocalContext);
                System.out.println("desktop");

                XComponentLoader xComponentLoader = (XComponentLoader)UnoRuntime.queryInterface(
                    XComponentLoader.class, desktop);
                System.out.println("xComponentLoader");

                PropertyValue[] loadProps = new PropertyValue[3];

                loadProps[0] = new PropertyValue();
                loadProps[0].Name = "Hidden";
                loadProps[0].Value = Boolean.TRUE;

                loadProps[1] = new PropertyValue();
                loadProps[1].Name = "ReadOnly";
                loadProps[1].Value = Boolean.FALSE;

                loadProps[2] = new PropertyValue();
                loadProps[2].Name = "MacroExecutionMode";
                loadProps[2].Value = new Short(com.sun.star.document.MacroExecMode.ALWAYS_EXECUTE_NO_WARN);

                try {
                    XComponent xComponent = xComponentLoader.loadComponentFromURL("file:///" + inputFile, "_blank", 0, loadProps);              
                    System.out.println("xComponent from " + inputFile);

                    String macroName = "Standard.Module1.MYMACRONAME?language=Basic&location=application";
                    Object[] aParams = null;

                    XScriptProviderSupplier xScriptPS = (XScriptProviderSupplier) UnoRuntime.queryInterface(XScriptProviderSupplier.class, xComponent);
                    XScriptProvider xScriptProvider = xScriptPS.getScriptProvider(); 
                    XScript xScript = xScriptProvider.getScript("vnd.sun.star.script:"+macroName); 

                    short[][] aOutParamIndex = new short[1][1]; 
                    Object[][] aOutParam = new Object[1][1];

                    @SuppressWarnings("unused")
                    Object result = xScript.invoke(aParams, aOutParamIndex, aOutParam);
                    System.out.println("xScript invoke macro" + macroName);

                    XStorable xStore = (XStorable)UnoRuntime.queryInterface(XStorable.class, xComponent);
                    System.out.println("xStore");

                    if (outputFileType.equalsIgnoreCase("pdf")) {
                        System.out.println("writer_pdf_Export");
                        loadProps[0].Name = "FilterName";
                        loadProps[0].Value = "writer_pdf_Export";
                    }
                    xStore.storeToURL("file:///" + outputFile, loadProps);
                    System.out.println("storeToURL to file " + outputFile);

                    xComponent.dispose();

                    xComponentLoader = null;
                    rInitialObject = null;

                    System.out.println("done.");

                    System.exit(0);

                } catch(IllegalArgumentException e) {
                    System.err.println("Error: Can't load component from url " + inputFile);
                }
            } else {
                System.err.println("Error: Unknown initial object name at server side");
            }           
        } catch(NoConnectException e) {
            System.err.println("Error: Server Connection refused: check server is listening...");           }
    } catch(java.lang.Exception e) {
        System.err.println("Error: Java exception:");
        e.printStackTrace();
    }
like image 653
MarcoS Avatar asked Jun 01 '12 10:06

MarcoS


1 Answers

After long hours of trial and error, I did just find the problem (whose cause keeps to be quite obscure, to me...). The component shouldn't be executed in "Hidden" mode, so, just with:

loadProps[1].Name = "Hidden";
loadProps[1].Value = Boolean.FALSE;

everything is ok. I suppose it's not an issue, since the jar file is executed server-side...

Hope it can help... :-)

like image 61
MarcoS Avatar answered Oct 12 '22 13:10

MarcoS