简体   繁体   English

如何将 LibreOffice API (UNO) 与 Python + Windows 一起使用?

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

This question is focused on Windows + LibreOffice + Python 3.这个问题的重点是 Windows + LibreOffice + Python 3。

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 :我已经安装了 LibreOffice (6.3.4.2), pip install unoconvpip install unotools ( pip install uno是另一个不相关的import uno库之后)

ModuleNotFoundError: No module named 'uno' ModuleNotFoundError:没有名为“uno”的模块

More generally, and as an example of use of UNO, how to open a.docx document with LibreOffice UNO and export it to PDF?更一般地,作为使用 UNO 的示例,如何使用 LibreOffice UNO 打开一个 .docx 文档并将其导出到 PDF?

I've searched extensively on this since a few days, but I haven't found a reproducible sample code working on Windows:几天以来,我对此进行了广泛的搜索,但我还没有找到在 Windows 上工作的可重现示例代码:

In order to interact with LibreOffice, start an instance listening on a socket.为了与 LibreOffice 交互,启动一个监听套接字的实例。 I don't use COM much, but I think this is the equivalent of the COM interaction you asked about.我不经常使用 COM,但我认为这相当于您询问的 COM 交互。 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.这可以在命令行上或使用 shell 脚本最容易地完成,但它也可以与使用时间延迟和子进程的系统调用一起使用。

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

Next, run the installation of python that comes with LibreOffice, which has uno installed by default.接下来,运行 LibreOffice 自带的 python 的安装,默认安装了uno

"C:\Program Files\LibreOffice\program\python.exe"
>> import 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.相反,如果您在 Windows 上使用未随 LibreOffice 提供的 Python 安装,那么让它与 UNO 一起工作要困难得多,除非您喜欢黑客,否则我不会推荐它。

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

Finally, since speed is a concern, using a listening instance of LibreOffice can be slow.最后,由于速度是一个问题,使用 LibreOffice 的监听实例可能会很慢。 To do this faster, move the code into a macro.要更快地执行此操作,请将代码移动到宏中。 APSO provides a menu to organize Python macros. APSO提供了一个菜单来组织 Python 宏。 Then call the macro like this:然后像这样调用宏:

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

In macros, obtain the document objects from XSCRIPTCONTEXT rather than the resolver.在宏中,从XSCRIPTCONTEXT而不是解析器获取文档对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM