2015-04-02 81 views
0

目前我打电话现有现有的LibreOffice宏与此:如何从一个python脚本中调用现有的LibreOffice蟒蛇宏观

def OnLOtimestamp(self): 
     try: 
      pid= Popen(['lowriter '"'"'vnd.sun.star.script:fs2TimeStamp.py$fs2_TimeStamp?language=Python&location=user'"'"],shell=True).pid 
     except OSError, e: 
      self.notify_show("Timestamp Error",str(e)) 
     self.ma2.SetLabel("Macro timestamp") 
     self.database['Time_stamp'] = self.database['Time_stamp'] + 1 

的键位作为POPEN通话,这样宏的名称是fs2TimeStamp.py和该函数是fs2_TimeStamp,但这感觉就像一个警察,我宁愿通过Uno执行直接调用。 我的研究表明,我可能需要使用MasterScriptProvider,XscriptProvider和XscriptInvocation,但试图破译Uno API就像游过糖浆。 有没有人有使用Uno调用LibreOffice中现有宏的代码示例?

编辑:
到目前为止答案似乎是否定的! 这是目前的比赛状态。当为LibreOffice的和scriptx打印在宏调用

#!/usr/bin/python3 
# -*- coding: utf-8 -*- 
## 
# a python script to run a libreoffice python macro externally 
# 
import uno 
from com.sun.star.connection import NoConnectException 
from com.sun.star.uno import RuntimeException 
from com.sun.star.uno import Exception 
from com.sun.star.lang import IllegalArgumentException 
def test2(*args): 
    localContext = uno.getComponentContext() 
    localsmgr = localContext.ServiceManager 
    resolver = localsmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext) 
    try: 
     ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext") 
    except NoConnectException as e: 
     print ("LibreOffice is not running or not listening on the port given - ("+e.Message+")") 
     return 
    except IllegalArgumentException as e: 
     print ("Invalid argument given - ("+ e.Message+ ")") 
     return 
    except RuntimeException as e: 
     print ("An unknown error occurred: " + e.Message) 
     return 

    servmgr = ctx.ServiceManager 
    desktop = servmgr.createInstanceWithContext("com.sun.star.frame.Desktop",ctx) 
    model = desktop.getCurrentComponent() 
# scriptP = model.getScriptProvider() 
# print("scriptP", scriptP) 
    scriptx = model.getScriptProvider().getScript('vnd.sun.star.script:fs2TimeStamp.py$fs2_TimeStamp?language=Python&location=user') 
    print("scriptx", scriptx) 
    try: 
     scriptx.invoke("",0,0) 
    except IllegalArgumentException as e: 
     print ("The command given is invalid ("+ e.Message+ ")") 
     return 
    except RuntimeException as e: 
     print("An unknown error occurred: " + e.Message) 
     return 
    except Exception as e: 
     print ("Script error ("+ e.Message+ ")") 
     print(e) 
     return 
    except: 
     print("Error") 
    return(None) 

test2() 

此代码的工作高高兴兴地出来为:

scriptx <pythonscript.PythonScript object at 0x7fa2879c42e8> 

但是在命令行脚本不执行任何操作,并scriptx打印出来作为运行时:

scriptx pyuno object (com.sun.star.script.provider.XScript)0x1e749d8{, supportedInterfaces={com.sun.star.lang.XTypeProvider,com.sun.star.script.provider.XScript}} 

所以getScriptProvider或getScript都没有提供他们需要的东西。我目前对遗失的东西感到不知所措,但我觉得在我的骨头里,我接近了解决方案。

任何人都可以看到我犯了一个错误吗?

回答

1

最后,我有一个工作解决方案。丁!东东!

#!/usr/bin/python3 
# -*- coding: utf-8 -*- 
## 
# a python script to run a libreoffice python macro externally 
# 
import uno 
from com.sun.star.connection import NoConnectException 
from com.sun.star.uno import RuntimeException 
from com.sun.star.uno import Exception 
from com.sun.star.lang import IllegalArgumentException 
def test2(*args): 
    localContext = uno.getComponentContext() 
    localsmgr = localContext.ServiceManager 
    resolver = localsmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext) 
    try: 
     ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext") 
    except NoConnectException as e: 
     print ("LibreOffice is not running or not listening on the port given - ("+e.Message+")") 
     return 
    msp = ctx.getValueByName("/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") 
    sp = msp.createScriptProvider("") 
    scriptx = sp.getScript('vnd.sun.star.script:fs2TimeStamp.py$fs2_TimeStamp?language=Python&location=user') 
    try: 
     scriptx.invoke((),(),()) 
    except IllegalArgumentException as e: 
     print ("The command given is invalid ("+ e.Message+ ")") 
     return 
    except RuntimeException as e: 
     print("An unknown error occurred: " + e.Message) 
     return 
    except Exception as e: 
     print ("Script error ("+ e.Message+ ")") 

return(None) 

test2() 

注意:为了清楚起见,现有Python脚本被称为fs2TimeStamp.py,它包含定义1(一)的功能def fs2_TimeStamp(*args):
见线:

scriptx = sp.getScript('vnd.sun.star.script:fs2TimeStamp.py$fs2_TimeStamp?language=Python&location=user') 

并且它被存储在$HOME/.config/libreoffice/4/user/Scripts/python

对于此解决方案的工作,libreoffice 必须在监听模式运行的,所以开始的LibreOffice用以下命令:

soffice "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp;" --writer --norestore 

OR

nohup soffice "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp;" --writer --norestore & 

或者你可以(在本例中为笔者)用更直接的方法:

lowriter "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp" 

nohup lowriter "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp" & 

还要注意,你必须用python3

1

这是第一次的答案,这是非常倾斜,以我的具体问题,称为宏,然后更简单和更宽泛的版本运行脚本在插入通过TCP连接发送的文本之前,通过TCP与另一个程序通话。
该版本将独立运行,应该立即可复制。
像以前一样必须在监听模式启动LibreOffice的作家(见选项前面的答案):

lowriter "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp" 

这是外部Python程序,必须以python3运行:

#!/usr/bin/python3 
# -*- coding: utf-8 -*- 
## 
# a python script to run a libreoffice python macro externally 
# NOTE: for this to run start libreoffice in the following manner 
# soffice "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp;" --writer --norestore 
# OR 
# nohup soffice "--accept=socket,host=127.0.0.1,port=2002,tcpNoDelay=1;urp;" --writer --norestore & 
# 
import uno 
from com.sun.star.connection import NoConnectException 
from com.sun.star.uno import RuntimeException 
from com.sun.star.uno import Exception 
from com.sun.star.lang import IllegalArgumentException 
def uno_directmacro(*args): 
    localContext = uno.getComponentContext() 
    localsmgr = localContext.ServiceManager 
    resolver = localsmgr.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext) 
    try: 
     ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext") 
    except NoConnectException as e: 
     print ("LibreOffice is not running or not listening on the port given - ("+e.Message+")") 
     return 
    msp = ctx.getValueByName("/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") 
    sp = msp.createScriptProvider("") 
    scriptx = sp.getScript('vnd.sun.star.script:directmacro.py$directmacro?language=Python&location=user') 
    try: 
     scriptx.invoke((),(),()) 
    except IllegalArgumentException as e: 
     print ("The command given is invalid ("+ e.Message+ ")") 
     return 
    except RuntimeException as e: 
     print("An unknown error occurred: " + e.Message) 
     return 
    except Exception as e: 
     print ("Script error ("+ e.Message+ ")") 
     print(e) 
     return 
    return(None) 

uno_directmacro() 

这是LibreOffice python宏directmacro.py它应该位于:

$HOME/.config/libreoffice/4/user/Scripts/python 

(假设我们

#!/usr/bin/python 
class FontSlant(): 
    from com.sun.star.awt.FontSlant import (NONE, ITALIC,) 

def directmacro(*args): 
#get the doc from the scripting context which is made available to all scripts 
    desktop = XSCRIPTCONTEXT.getDesktop() 
    model = desktop.getCurrentComponent() 
    text = model.Text 
    tRange = text.End 
    cursor = desktop.getCurrentComponent().getCurrentController().getViewCursor() 
    doc = XSCRIPTCONTEXT.getDocument() 
    parentwindow = doc.CurrentController.Frame.ContainerWindow 

# your cannot insert simple text and text into a table with the same method 
# so we have to know if we are in a table or not. 
# oTable and oCurCell will be null if we are not in a table 
    oTable = cursor.TextTable 
    oCurCell = cursor.Cell 
    insert_text = "This is text inserted into a LibreOffice Document\ndirectly from a macro called externally" 
    Text_Italic = FontSlant.ITALIC 
    Text_None = FontSlant.NONE 
    cursor.CharPosture=Text_Italic 
    if oCurCell == None: # Are we inserting into a table or not? 
     text.insertString(cursor, insert_text, 0) 
    else: 
     cell = oTable.getCellByName(oCurCell.CellName) 
     cell.insertString(cursor, insert_text, False) 
    cursor.CharPosture=Text_None 
    return None 
:LibreOffice的的版本4在这里)

directmacro.py宏Ë