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

怎甘沉沦 提交于 2020-05-15 22:55:09

问题


This question is focused on 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:

ModuleNotFoundError: No module named '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?

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

  • 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

  • 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
    

回答1:


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;

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

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

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"

In macros, obtain the document objects from XSCRIPTCONTEXT rather than the resolver.



来源:https://stackoverflow.com/questions/61457120/how-to-use-libreoffice-api-uno-with-python-windows

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!