如何在Python + Windows上使用LibreOffice API(UNO)? [英] How to use LibreOffice API (UNO) with Python + Windows?

查看:693
本文介绍了如何在Python + Windows上使用LibreOffice API(UNO)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题主要针对Windows + LibreOffice + Python 3.

This question is focused on Windows + LibreOffice + Python 3.

我还安装了LibreOffice(6.3.4.2) pip install unoconvpip 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:

  • 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" with soffice.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆