问题描述
我的工作流程通常遵循以下链条:
-
在libreoffice中使用soffice命令打开示例数据文件,这样就可以连接示例数据文件了,这是一个控制台命令:
$ soffice --calc --accept="socket,host=localhost,port=2002;urp;STaroffice.ServiceManager" /path/to/sample/data.ods
-
运行 python 控制台并输入以下连接命令:
>>> sys.path.append("/path/to/uno_lib/.local/lib/python3") >>> import uno >>> local_context = uno.getComponentContext() >>> resolver = local_context.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver",local_context) >>> ctx = resolver.resolve("uno:socket,port=2002;urp;STaroffice.ComponentContext") >>> smgr = ctx.ServiceManager >>> desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop",ctx) >>> document = desktop.getCurrentComponent()
-
使用 uno 命令提取数据
pseudo-code >>> document.getSheet("data").getCellRange("B5","H15")
显然,我想将所有这些放入文件“connect”和函数“connection”中,例如:
connect.py
import os
import uno
def connection():
os.system(soffice --calc --accept="socket,port=2002;urp;STaroffice.ServiceManager" /path/to/sample/data.ods)
context ...
resolver
ctx ...
smgr ....
desktop ...
document ...
return document
所以我可以简单地去:
$ python
>>> import connect
>>> document = connection()
>>> document.getSheet("DataSheet").getCellRange("B5","H15")
哦,我多么喜欢这个 :)
有一个问题:当我调用函数“connection()”时,控制台在打开 calc 文件的系统命令处停止,只有当我关闭 calc 文件时,脚本才会继续,但它不再连接,因为文件已关闭 :( 我该如何规避?
解决方法
首选方法是使用 shell 脚本而不是系统调用来启动 LibreOffice。
./start_soffice_listening.sh
python
>>> import connect
>>> document = connection()
这是我使用的shell脚本:
if [ "$1" == "-headless" ]; then
echo "Opening headless (use 'pkill loffice' and 'pkill soffice.bin' to end"
loffice "--accept=socket,host=localhost,port=2002;urp;" --writer --headless --nologo --nofirststartwizard --nolockcheck --norestore &
else
loffice "--accept=socket,port=2002;urp;" --writer &
fi
否则,您将需要线程和睡眠命令才能从 Python 中与操作系统交互。这比直接启动 LO 更困难,更不可靠。