如何在Windows系统下使用Python与LibreOffice API(UNO)?

8
这个问题关注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上广泛搜索了几天,但是我没有找到一个可重现的示例代码:
1个回答

8
为了与LibreOffice交互,请启动一个监听socket的实例。我不经常使用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

如果您使用的是未随LibreOffice一起提供的Windows版Python安装,则使其与UNO配合工作要困难得多,除非您喜欢黑客攻击,否则我不建议这样做。
现在,这是所有代码。 在实际项目中,最好组织成类,但这是一个简化版本。
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获取文档对象,而不是使用解析器。

1
谢谢您详细的回答!我会尝试这个方法。如果您使用的是未随LibreOffice一起提供的Windows Python安装程序,则使其与UNO配合工作要困难得多:哦,好的,这正是我想做的!实际上,我想使用我的标准Python(而不是随LibreOffice提供的那个),因为我已经在那里拥有了所有的库等。 - Basj
1
是的,我明白你为什么想这样做,但这可能不是一个好主意。 - Jim K
@JimK 请分享“更加困难”的方法 - undefined
@deostroll:链接在问题中,提问者写道:“我也尝试过这个(不成功)。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接