[英]Run Macro from LibreOffice extension JAVA
我試圖從擴展中的Java按鈕運行宏(宏在Writer Standard.Voto.Main中)。
這是按鈕:
<dlg:button dlg:id="Bt_voto" dlg:tab-index="2" dlg:left="78" dlg:top="15" dlg:width="52" dlg:height="12" dlg:tag="B" dlg:value="Voto"><script:eventscript:event-name="on-performaction" script:macro-name="vnd.sun.star.UNO:ConfigChange" script:language="UNO"/>
我從此類中調用該方法:
public boolean callHandlerMethod(XDialog dialog, Object eventObject, String methodName)
throws WrappedTargetException {
if (methodName.equals(ConfigChange)) {
try {
String param = "";
// String cmd =
// "Standard.Conversion.ConvertHTMLToWord?langauge=Basic&location=application";
String cmd = "Standard.Voto.Main?langauge=Basic&location=Document";
System.out.println("Running macro on " + param);
Macro macObj = new Macro();
macObj.executeMacro(cmd, new Object[] { param });
System.out.println("Completed?");
onOkButtonPressed();
} catch (Exception e) {
System.out.println(e.toString());
// e.printStackTrace();
}
而Macro.class是:
class Macro {
public Object executeMacro(String strMacroName, Object[] aParams) throws BootstrapException
{
String oooExecFolder = "C:/Program Files (x86)/LibreOffice 5/program";
try {
System.out.println("Completed1");
XComponentContext xContext = BootstrapSocketConnector.bootstrap(oooExecFolder);
XMultiComponentFactory xMultiComponentFactory = xContext.getServiceManager();
XComponentLoader xcomponentloader = (XComponentLoader) UnoRuntime.queryInterface(XComponentLoader.class,xMultiComponentFactory.createInstanceWithContext("com.sun.star.frame.Desktop", xContext));
System.out.println("Completed2");
com.sun.star.text.XTextDocument mxDoc = openWriter(xContext);
XScriptProviderSupplier xScriptPS = (XScriptProviderSupplier) UnoRuntime.queryInterface(XScriptProviderSupplier.class, xcomponentloader);
XScriptProvider xScriptProvider = xScriptPS.getScriptProvider();
XScript xScript = xScriptProvider.getScript("vnd.sun.star.script:"+strMacroName);
short[][] aOutParamIndex = new short[1][1];
Object[][] aOutParam = new Object[1][1];
aParams = new String[2];
@SuppressWarnings("unused")
Object result = xScript.invoke(aParams, aOutParamIndex, aOutParam);
System.out.println("xScript invoke macro " + strMacroName);
} catch (Exception e) {
throw new RuntimeException(e);
}
return oooExecFolder;
}
public static com.sun.star.text.XTextDocument openWriter(com.sun.star.uno.XComponentContext xContext)
{
com.sun.star.frame.XComponentLoader xCLoader;
com.sun.star.text.XTextDocument xDoc = null;
com.sun.star.lang.XComponent xComp = null;
try {
// get the remote office service manager
com.sun.star.lang.XMultiComponentFactory xMCF =
xContext.getServiceManager();
Object oDesktop = xMCF.createInstanceWithContext(
"com.sun.star.frame.Desktop", xContext);
xCLoader = (com.sun.star.frame.XComponentLoader)
UnoRuntime.queryInterface(com.sun.star.frame.XComponentLoader.class,
oDesktop);
com.sun.star.beans.PropertyValue [] szEmptyArgs =
new com.sun.star.beans.PropertyValue [0];
/*
ArrayList<PropertyValue> props = new ArrayList<PropertyValue>();
PropertyValue p = new PropertyValue();
p.Name = "Hidden";
p.Value = new Boolean(true);
props.add(p);
PropertyValue[] properties = new PropertyValue[props.size()];
props.toArray(properties);
String strDoc = "private:factory/swriter";
xComp = xCLoader.loadComponentFromURL(strDoc, "_blank", 0, properties);
*/
String strDoc = "private:factory/swriter";
xComp = xCLoader.loadComponentFromURL(strDoc, "_blank", 0, szEmptyArgs);
xDoc = (com.sun.star.text.XTextDocument)
UnoRuntime.queryInterface(com.sun.star.text.XTextDocument.class,
xComp);
} catch(Exception e){
System.err.println(" Exception " + e);
e.printStackTrace(System.err);
}
return xDoc;
}
}
如果我運行此類,則引導程序可以運行,但在以下行終止:
XComponentContext xContext = BootstrapSocketConnector.bootstrap(oooExecFolder);
沒有錯誤。 你能幫助我嗎?
直接從對話框中調用Basic宏要容易得多。 即使擴展的其余部分使用Java,此方法也有效。 確保使用正確的腳本URI 。
<dlg:button dlg:id="Bt_voto" dlg:tab-index="3" dlg:left="173" dlg:top="88" dlg:width="51" dlg:height="13" dlg:value="Voto">
<script:event script:event-name="on-performaction" script:macro-name="vnd.sun.star.script:Standard.Voto.Main?language=Basic&location=application" script:language="Script"/>
</dlg:button>
但是,如果由於某些其他原因確實需要使用Java,請繼續閱讀。 看來您嘗試合並來自兩個不同項目的代碼:
問題在於某些命令只能執行一次,而每個項目都要執行一次,從而導致重復。 不要第二次引導。 而是將上下文存儲在某個位置,以便可以在需要時將其傳遞給Macro類。
以下是對我有用的代碼的相關部分。 為了進行測試,我向StarterProjectImpl.java添加了main方法。 這樣就可以查看錯誤消息。
public static void main (String [] args) {
com.sun.star.uno.XComponentContext xContext = null;
try {
xContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
ActionOneDialog actionOneDialog = new ActionOneDialog(xContext);
actionOneDialog.show();
} catch (Exception exc) {
exc.printStackTrace();
}
}
public ActionOneDialog(XComponentContext xContext) {
m_xContext = xContext;
this.dialog = DialogHelper.createDialog("ActionOneDialog.xdl", xContext, this);
}
public boolean callHandlerMethod(XDialog dialog, Object eventObject, String methodName) throws WrappedTargetException {
if (methodName.equals(ConfigChange)) {
try {
String cmd = "Standard.Voto.Main?language=Basic&location=application";
Macro macObj = new Macro(m_xContext);
}
}
public Object executeMacro(String strMacroName, Object[] aParams)
{
String oooExecFolder = "C:/Program Files (x86)/LibreOffice 5/program";
try {
XMultiComponentFactory xMultiComponentFactory = m_xContext.getServiceManager();
Object oDesktop = xMultiComponentFactory.createInstanceWithContext(
"com.sun.star.frame.Desktop", m_xContext);
XComponentLoader xcomponentloader = (com.sun.star.frame.XComponentLoader)
UnoRuntime.queryInterface(com.sun.star.frame.XComponentLoader.class,
oDesktop);
com.sun.star.text.XTextDocument mxDoc = openWriter(m_xContext);
XScriptProviderSupplier xScriptPS = (XScriptProviderSupplier) UnoRuntime.queryInterface(
XScriptProviderSupplier.class, mxDoc);
XScriptProvider xScriptProvider = xScriptPS.getScriptProvider();
XScript xScript = xScriptProvider.getScript("vnd.sun.star.script:"+strMacroName);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
編輯 :
以下是分步說明。 在LibreOffice中,轉到Tools -> Macros -> Organize Macros -> LibreOffice Basic
。 在“ My Macros & Dialogs -> Standard -> Voto
,粘貼以下代碼:
Sub Main
MsgBox("Hello, Voto!")
End Sub
接下來,按照“ 入門”說明進行操作 。 展開dialog -> ActionOneDialog.xdl
並轉到“ Source
選項卡。 將以下代碼粘貼到</dlg:button>
。
<dlg:button dlg:id="Bt_voto" dlg:tab-index="4" dlg:left="100" dlg:top="88" dlg:width="51" dlg:height="13" dlg:value="Voto">
<script:event script:event-name="on-performaction" script:macro-name="vnd.sun.star.script:Standard.Voto.Main?language=Basic&location=application" script:language="Script"/>
</dlg:button>
現在運行它以添加擴展名。 最后,在LibreOffice中,轉到Starter Project -> Action One
,然后單擊Voto
。 結果應該是這樣的:
編輯2 :
根據我的經驗,不可能從對話框事件處理程序中插入字段。 而是要等到對話框完成執行后再插入該字段。
對於此項目,應該可以在ActionOneDialog.java中修改show()
。 在命令dialog.execute()
,編寫Java代碼以使用分派器插入字段。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.