LibreOffice UNO Java API: как открыть документ, выполнить макрос и закрыть его?
Я работаю на стороне сервера LibreOffice: на сервере я запускаю
soffice --accept=...
затем я использую JAVA LibreOffice client API для применения макроса к документу (calc или writer). Выполнение java не дает никакой ошибки, но я не выполняю работу (выполняется макрос-код, но его эффекты не находятся в выходном файле). Более того, после вызова макрос-скрипта появляется окно основного отладчика, по-видимому, остановленное в первой строке моего макроса; F5 не перезапускается он...
это код, который я использую:
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();
}
1 ответов
после долгих часов проб и ошибок я просто нашел проблему (причина которой для меня остается совершенно неясной...). Компонент не должен выполняться в "скрытый" режим, так просто с:
loadProps[1].Name = "Hidden";
loadProps[1].Value = Boolean.FALSE;
все ок. Я полагаю, что это не проблема, так как файл jar выполняется на стороне сервера...
надеюсь, что это может помочь... :-)