如何在Python + Windows上使用LibreOffice API(UNO)? [英] How to use LibreOffice API (UNO) with Python + Windows?
问题描述
这个问题主要针对Windows + LibreOffice + Python 3.
This question is focused on Windows + LibreOffice + Python 3.
我还安装了LibreOffice(6.3.4.2)
pip install unoconv
和pip install unotools
(pip install uno
是另一个不相关的库),但是在import uno
之后仍然出现此错误:
I've installed LibreOffice (6.3.4.2), also
pip install unoconv
and pip install unotools
(pip install uno
is another unrelated library), but still I get this error after import uno
:
ModuleNotFoundError:没有名为"uno"的模块
ModuleNotFoundError: No module named 'uno'
更一般地说,作为使用UNO的示例,如何使用LibreOffice UNO打开.docx文档并将其导出为PDF?
几天以来,我对此进行了广泛的搜索,但是我没有找到可重现的示例代码在Windows上运行:
I've searched extensively on this since a few days, but I haven't found a reproducible sample code working on Windows:
-
soffice.exe
的无头使用,请参阅我的问题+ answer soffice.exe --headless ...,但更接近COM交互(组件对象模型)的东西对许多应用程序将很有用,因此,这里的问题
headless use of
soffice.exe
, see my question+answer Headless LibreOffice very slow to export to PDF on Windows (6 times slow than on Linux) and the notes on the answer: it "works" withsoffice.exe --headless ...
but something closer to a COM interaction (Component Object Model) would be useful for many applications, thus this question here
相关的论坛帖子和 LibreOffice:使用Python脚本编程,但是未详细说明应如何在Windows上使用Python安装uno;也
Related forum post, and LibreOffice: Programming with Python Scripts, but the way uno should be installed on Windows, with Python, is not detailed; also Detailed tutorial regarding LibreOffice to Python macro writing, especially for Calc
我也尝试了此操作(失败):获取python导入uno/pyuno :
I've also tried this (unsuccessfully): Getting python to import uno / pyuno:
import os
os.environ["URE_BOOTSTRAP"] = r"vnd.sun.star.pathname:C:\Program Files\LibreOffice\program\fundamental.ini"
os.environ["PATH"] += r";C:\Program Files\LibreOffice\program"
import uno
推荐答案
为了与LibreOffice进行交互,请启动在套接字上侦听的实例.我使用的COM并不多,但是我认为这相当于您所要求的COM交互.可以在命令行或使用Shell脚本最轻松地完成此操作,但是它也可以使用带有时间延迟和子进程的系统调用来工作.
In order to interact with LibreOffice, start an instance listening on a socket. I don't use COM much, but I think this is the equivalent of the COM interaction you asked about. This can be done most easily on the command line or using a shell script, but it can also work with a system call using a time delay and subprocess.
chdir "%ProgramFiles%\LibreOffice\program\"
start soffice -accept=socket,host=localhost,port=2002;urp;
接下来,运行LibreOffice随附的python安装,默认情况下已安装uno
.
Next, run the installation of python that comes with LibreOffice, which has uno
installed by default.
"C:\Program Files\LibreOffice\program\python.exe"
>> import uno
如果相反,而您正在Windows上使用LibreOffice附带的Python安装,那么将其与UNO配合使用会更加困难,除非您喜欢黑客,否则我不建议您使用它
If instead you are using an installation of Python on Windows that was not shipped with LibreOffice, then getting it to work with UNO is much more difficult, and I would not recommend it unless you enjoy hacking.
现在,这是所有代码.在真实的项目中,最好将其组织成类,但这是一个简化的版本.
Now, here is all the code. In a real project, it's probably best to organize into classes, but this is a simplified version.
import os
import uno
from com.sun.star.beans import PropertyValue
def createProp(name, value):
prop = PropertyValue()
prop.Name = name
prop.Value = value
return prop
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", localContext)
ctx = resolver.resolve(
"uno:socket,host=localhost,port=2002;urp;"
"StarOffice.ComponentContext")
smgr = ctx.ServiceManager
desktop = smgr.createInstanceWithContext(
"com.sun.star.frame.Desktop", ctx)
dispatcher = smgr.createInstanceWithContext(
"com.sun.star.frame.DispatchHelper", ctx)
filepath = r"C:\Users\JimStandard\Desktop\Untitled 1.docx"
fileUrl = uno.systemPathToFileUrl(os.path.realpath(filepath))
uno_args = (
createProp("Minimized", True),
)
document = desktop.loadComponentFromURL(
fileUrl, "_default", 0, uno_args)
uno_args = (
createProp("FilterName", "writer_pdf_Export"),
createProp("Overwrite", False),
)
newpath = filepath[:-len("docx")] + "pdf"
fileUrl = uno.systemPathToFileUrl(os.path.realpath(newpath))
try:
document.storeToURL(fileUrl, uno_args) # Export
except ErrorCodeIOException:
raise
try:
document.close(True)
except CloseVetoException:
raise
最后,由于速度是一个问题,因此使用LibreOffice的侦听实例可能会很慢.若要更快地执行此操作,请将代码移到宏中. APSO 提供了用于组织Python宏的菜单.然后像这样调用宏:
Finally, since speed is a concern, using a listening instance of LibreOffice can be slow. To do this faster, move the code into a macro. APSO provides a menu to organize Python macros. Then call the macro like this:
soffice "vnd.sun.star.script:myscript.py$name_of_maindef?language=Python&location=user"
在宏中,从XSCRIPTCONTEXT
而非解析器获取文档对象.
In macros, obtain the document objects from XSCRIPTCONTEXT
rather than the resolver.
这篇关于如何在Python + Windows上使用LibreOffice API(UNO)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!