问题
There are a few related threads about this topic here ad here but they seem a bit dated.
I just downloaded LibreOffice 4 which has a Python 3.3.0 built in. Using that Python I can import and use UNO just fine, and control Office from my Python script. However, many of my other modules are missing from that Python—and UNO is the only one missing from my Python.
Is there any way that I can install pyuno for my local Python? The LibreOffice source tree includes a pyuno/ source tree, but I'm not sure how to go about building/integrating this into another Python tree.
Any experiences here? Help? Hints? Dos, Don'ts, Dohs?
EDIT The answer below works just fine for Linux, and I have no problem there extending the PYTHONPATH
to import uno. Matters are different on the Mac, so take a look at the other answer.
EDIT Absolutely take this anwer into consideration when tinkering with Python paths!
回答1:
Once you try to run PyUNO off any other python executable than the one provided with LO, things do get rough.
The SEGV on Mac is because LO's libpyuno.dylib (loaded via libuno.dylib, which in turn is loaded via "import uno") references @loader_path/LibreOfficePython.framework/Versions/3.3/LibreOfficePython (run "otool -L" on that file; path as on current LO master; paths are a little different on various LO versions). When run from a different python process than LO's, that means there'll be two python runtimes in the process (and the LO one not even properly initialized, probably), and that leads to a SEGV somewhere in that LibreOfficePython. (This happens to work better on Linux, where libpyuno.so references libpython3.3m.so, and normally finds the LO python one's next to itself via its RPATH, but if any libpython3.3m.so happens to already be loaded into the process (from the other python), the Linux loader happily re-uses that one.)
One gross hack on Mac is to use install_name_tool to "rewire" libpyuno.dylib to reference the other python's Python.framework/Versions/3.3/Python (by absolute path) instead of @loader_path/LibreOfficePython.framework/Versions/3.3/LibreOfficePython.
Another gotcha is that LO's python (on Linux and Mac) is actually a shell script around the true python executable. It needs to set up a number of env vars (whose purpose is even documented in the script). To make PyUNO work from a different python you'll want to set up these env vars too, esp. UNO_PATH, URE_BOOTSTRAP, and the parts of PYTHONPATH that find the LO-specific libs (rather than those that come with python itself). Note that the details of those env vars' values differ among LO versions.
回答2:
It is a late answer and I don't have the exact same setup as you have, but for me, I could simply adjust PYTHONPATH
so that the directory where uno.py
lives is known to python.
bash> export PYTHONPATH=${PYTHONPATH}:/usr/lib/libreoffice/program
bash> python
>>> import uno
A requirement is that your LibreOffice/OO python has the same version as your regular one: Python will compile the .py to .pyc, and that format is not transferable between versions (at least, that is not guaranteed).
Do a locate uno.py
if you are not sure where your file is. Inspecting where /usr/bin/libreoffice
links to may also help.
回答3:
Linux
dirkjot's answer to this thread works great on Linux.
Mac (Yosemite)
Things are a little bit more tricky here, and as of LibreOffice 4.3 I still can't extend my PYTHONPATH
to LibreOffice and import uno
without crashing on Mac:
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
But here is what works for me. First, I have to make sure that both Python and my LibreOffice are built for 32b or 64b; they can't be mixed. I'm working with 64b MacPorts Python 3.3 and 64b LibreOffice for Mac (download link) which comes with Python 3.3. Second, I have to make sure to run the right Python and extend the PYTHONPATH
correctly. Because I can't run my MacPorts Python and extend it with LibreOffice's path, I have to do it the other way around: run the LibreOffice Python and extend it with my MacPorts Python path:
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
>>>
Note how uno
is imported from the LibreOffice's Python path, and lxml
lives in MacPort's Python path.
回答4:
I recently wanted to use pyuno with django (i.e. I had a pricing engine in a spreadsheet and the django app opened it up, filled in user input, and retrieved the price after recalculating). The only reasonable solution to this is either use docker containers or a linux vm on whatever platform you're working on (I'm on mac and use parallels for ubuntu machine). Any other solution is a colossal waste of time.
When you're in the linux environment, all you have to do is run apt-get install python3-uno
and set your python path to $PYTHONPATH:/usr/lib/python3/dist-packages/
(i.e. where apt-get installs python3-uno and everything will be ok (only in linux environment).
来源:https://stackoverflow.com/questions/15223209/installing-pyuno-libreoffice-for-private-python-build