为私有Python构建安装pyuno(LibreOffice)

5 投票
4 回答
6192 浏览
提问于 2025-04-17 17:59

关于这个话题,有几个相关的讨论线程,可以在这里这里找到,不过这些讨论看起来有点过时了。

我刚下载了LibreOffice 4,它里面自带了Python 3.3.0。用这个Python,我可以顺利导入和使用UNO,并且可以通过我的Python脚本来控制Office。但是,我发现这个Python里缺少很多其他模块,而UNO是我唯一缺少的模块。

有没有办法让我在本地的Python上安装pyuno?LibreOffice的源代码里有一个pyuno/的源代码树,但我不太确定怎么把它构建或整合到其他的Python环境里。

有没有人有相关的经验?能帮忙吗?有什么提示?该做和不该做的事情?

编辑 下面的回答在Linux上运行得很好,我在那边扩展PYTHONPATH来导入uno没有问题。但在Mac上情况就不一样了,所以可以看看另一个回答

编辑 在调整Python路径时,一定要考虑这个回答

4 个回答

2

这是个迟来的回答,我的环境和你的不完全一样,但对我来说,我只需要调整一下 PYTHONPATH,让 Python 知道 uno.py 文件所在的目录就可以了。

bash> export PYTHONPATH=${PYTHONPATH}:/usr/lib/libreoffice/program
bash> python
>>> import uno

有一个要求是,你的 LibreOffice/OO 的 Python 版本要和你常用的 Python 版本一致:因为 Python 会把 .py 文件编译成 .pyc 文件,而这种格式在不同版本之间是不能互通的(至少,这个是不保证的)。

如果你不确定你的文件在哪里,可以用 locate uno.py 来查找一下。查看一下 /usr/bin/libreoffice 链接到哪里也可能会有帮助。

4

如果你尝试用其他的 Python 运行 PyUNO,而不是 LibreOffice 自带的那个,事情就会变得很麻烦。

在 Mac 上出现的 SEGV 错误是因为 LibreOffice 的 libpyuno.dylib(通过 libuno.dylib 加载,而 libuno.dylib 又是通过 "import uno" 加载的)引用了 @loader_path/LibreOfficePython.framework/Versions/3.3/LibreOfficePython(你可以运行 "otool -L" 来查看这个文件的路径;这个路径在当前的 LibreOffice 主版本中是这样的,不同版本的 LibreOffice 路径会有些不同)。当你从一个不同的 Python 进程运行时,这就意味着会在进程中出现两个 Python 运行环境(而 LibreOffice 的那个可能还没有正确初始化),这就会导致在 LibreOfficePython 中出现 SEGV 错误。(在 Linux 上情况稍微好一些,因为 libpyuno.so 引用了 libpython3.3m.so,通常可以通过它的 RPATH 找到旁边的 LibreOffice Python 版本,但如果其他 Python 进程已经加载了 libpython3.3m.so,Linux 的加载器会很高兴地重用那个。)

在 Mac 上有一个比较粗糙的解决办法,就是使用 install_name_tool 来“重连” libpyuno.dylib,使其引用其他 Python 的 Python.framework/Versions/3.3/Python(用绝对路径),而不是 @loader_path/LibreOfficePython.framework/Versions/3.3/LibreOfficePython。

另一个需要注意的地方是,LibreOffice 的 Python(在 Linux 和 Mac 上)实际上是一个围绕真正的 Python 可执行文件的脚本。它需要设置一些环境变量(这些变量的作用在脚本中都有说明)。如果你想让 PyUNO 在不同的 Python 中工作,你需要设置这些环境变量,特别是 UNO_PATH、URE_BOOTSTRAP,以及 PYTHONPATH 中找到 LibreOffice 特定库的部分(而不是那些自带的 Python 库)。注意,这些环境变量的具体值在不同版本的 LibreOffice 中是不同的。

0

Linux

dirkjot的回答在Linux上效果很好。

Mac(Yosemite)

在这里事情有点复杂。到目前为止,在LibreOffice 4.3版本中,我仍然无法在Mac上扩展我的 PYTHONPATH 到LibreOffice,并且 import uno 会崩溃:

localhost ~ > PYTHONPATH=$PYTHONPATH:/Applications/LibreOffice64.app/Contents/MacOS python3.3
Python 3.3.6 (default, Nov 12 2014, 18:18:46) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.54)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import uno
Segmentation fault: 11

不过,这里有我能用的方法。首先, 我必须确保我的Python和LibreOffice都是32位或64位的;它们不能混用。我使用的是64位的MacPorts Python 3.3和64位的LibreOffice for Mac(下载链接),这个版本自带Python 3.3。其次, 我必须确保运行正确的Python,并正确扩展 PYTHONPATH。因为我不能用LibreOffice的路径来扩展我的MacPorts Python,所以我必须反过来做:运行LibreOffice的Python,并用我的MacPorts Python路径来扩展:

localhost ~ > PYTHONPATH=$PYTHONPATH:/opt/local/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/site-packages /Applications/LibreOffice64.app/Contents/MacOS/python
Python 3.3.5 (default, Dec 12 2014, 10:33:58) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.51)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import uno
>>> import lxml
>>> 

注意 uno 是从LibreOffice的Python路径中导入的,而 lxml 则在MacPorts的Python路径中。

撰写回答