如何通过 Python + Windows 使用 LibreOffice API (UNO)?

How to use LibreOffice API (UNO) with Python + Windows?

本题关注Windows + LibreOffice + Python 3.

我也安装了 LibreOffice (6.3.4.2) pip install unoconvpip install unotoolspip install uno 是另一个不相关的库),但在 import uno:

之后我仍然收到此错误

ModuleNotFoundError: No module named 'uno'

更一般地说,作为使用 UNO 的示例,如何使用 LibreOffice UNO 打开 .docx 文档并将其导出为 PDF?

几天以来,我对此进行了广泛的搜索,但我还没有找到适用于 Windows:

的可重现示例代码

为了与 LibreOffice 交互,启动一个监听套接字的实例。我不怎么使用 COM,但我认为这相当于您询问的 COM 交互。这可以在命令行上或使用 shell 脚本最轻松地完成,但它也可以与使用时间延迟和子进程的系统调用一起工作。

chdir "%ProgramFiles%\LibreOffice\program\"
start soffice -accept=socket,host=localhost,port=2002;urp;

接下来运行安装LibreOffice自带的python,默认安装了uno

"C:\Program Files\LibreOffice\program\python.exe"
>> import uno

如果您在 Windows 上使用 LibreOffice 未附带的 Python 安装,那么要使其与 UNO 一起使用 much更难,除非你喜欢黑客,否则我不会推荐它。

现在,这里是所有代码。在实际项目中,最好组织成 类,但这是一个简化版本。

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 宏。然后像这样调用宏:

soffice "vnd.sun.star.script:myscript.py$name_of_maindef?language=Python&location=user"

在宏中,从 XSCRIPTCONTEXT 而不是解析器获取文档对象。