API LibreOffice UNO Java: ¿cómo abrir un documento, ejecutar una macro y cerrarla?
macros openoffice.org (1)
Estoy trabajando en el lado del servidor de LibreOffice: en el servidor que ejecuto
soffice --accept=...
Luego utilizo las API del cliente Java LibreOffice para aplicar una macro en un documento (calc o writer). La ejecución de Java no da ningún error, pero no hago el trabajo (se ejecuta el código de macro, pero sus efectos no están en el archivo de salida). Más, después de invocar el script de macro, aparece la ventana del depurador básico, aparentemente detenida en la primera línea de mi macro; F5 no lo reinicia ...
Este es el código relevante que estoy usando:
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();
}
Después de largas horas de prueba y error, solo encontré el problema (cuya causa sigue siendo bastante oscura, para mí ...). El componente no se debe ejecutar en el modo " Oculto ", entonces, solo con:
loadProps[1].Name = "Hidden";
loadProps[1].Value = Boolean.FALSE;
todo está bien. Supongo que no es un problema, ya que el archivo jar se ejecuta en el servidor ...
Espero que pueda ayudar ... :-)