LibreOffice mit Python betreiben
Es gibt drei Methoden.
Die erste Methode erfordert eine GUI-Operation, sodass keine Stapelverarbeitung vom Programm aus durchgeführt werden kann. Der Bediener reagiert auf jeden Fehler.
Die zweite Methode kann für die Stapelverarbeitung verwendet werden, da LibreOffice nach Beendigung des Makros beendet wird. Wenn ein Fehler auftritt, zeigt LibreOffice einen Dialog an und wartet, und das Programm kann ihn nicht verarbeiten. In Anbetracht möglicher Fehler müssen Maßnahmen wie das Festlegen eines Zeitlimits in timeout-decorator getroffen werden. Wenn beim Start von LibreOffice bereits ein LibreOffice gestartet wurde, wird die Verarbeitung dort ausgeführt, sodass die Steuerung möglicherweise nicht wie erwartet möglich ist.
Die dritte Methode besteht darin, den Schalter --accept vorab auf LibreOffice anzugeben, damit er mit einem Socket oder einer Named Pipe verbunden und gestartet werden kann. Wenn bei dieser Methode LibreOffice zuerst gestartet wird, wird die Verarbeitung dort ausgeführt, sodass die Steuerung möglicherweise nicht wie erwartet möglich ist. Es kann unter Microsoft Windows verwendet werden, kann jedoch aufgrund eines Fehlers beim Herstellen der Verbindung nicht unter FreeBSD ausgeführt werden.
Microsoft Windows
Unter Microsoft Windows wird LibreOffice mit einem Python-Prozessor% PROGRAMFILES% \ LibreOffice \ program \ python.exe geliefert, der automatisch für Makros verwendet wird. Selbst wenn Sie eine Verbindung über die Befehlszeile herstellen, müssen Sie das mit LibreOffice gelieferte Python-Verarbeitungssystem verwenden. Die mit LibreOffice 6.3.6 gelieferte Python-Version ist 3.5.9.
Die Bibliothek wird in% PROGRAMFILES% \ LibreOffice \ program \ python-core-3.5.9 \ lib installiert. Es gibt auch einen Unterordner für Site-Pakete, der ebenfalls sys.path durchläuft, jedoch nur eine README-Datei enthält. Die Installation des Pakets ist nicht einfach, da kein Pip vorhanden ist. Aus Installation von pip site Sie können es installieren, indem Sie get-pip.py herunterladen und ausführen. Wenn Sie es jedoch mit persönlichen Kontoberechtigungen ausführen % PROGRAMFILES% \ LibreOffice \ program \ python-core-3.5.9 \ lib \ site-packages ist nicht beschreibbar Es wird in% APPDATA% \ Roaming \ Python \ Python35 \ site-packages unter dem Benutzerprofil installiert.
C:\Users\shota243>cd Downloads
C:\Users\shota243\Downloads>"c:\Program Files\LibreOffice\program"\python get-pip.py
Defaulting to user installation because normal site-packages is not writeable
Collecting pip
Downloading pip-20.1.1-py2.py3-none-any.whl (1.5 MB)
|################################| 1.5 MB 1.3 MB/s
Collecting setuptools
Downloading setuptools-47.1.1-py3-none-any.whl (583 kB)
|################################| 583 kB 6.8 MB/s
Collecting wheel
Downloading wheel-0.34.2-py2.py3-none-any.whl (26 kB)
Installing collected packages: pip, setuptools, wheel
WARNING: The scripts pip.exe, pip3.5.exe and pip3.exe are installed in 'C:\Users\shota243\AppData\Roaming\Python\Python35\Scripts' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
WARNING: The scripts easy_install-3.5.exe and easy_install.exe are installed in 'C:\Users\shota243\AppData\Roaming\Python\Python35\Scripts' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
WARNING: The script wheel.exe is installed in 'C:\Users\shota243\AppData\Roaming\Python\Python35\Scripts' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed pip-20.1.1 setuptools-47.1.1 wheel-0.34.2
pip.exe ist auch in% APPDATA% \ Roaming \ Python \ Python35 \ Scripts installiert, aber Sie müssen es selbst festlegen, um den PATH in diesen Ordner zu legen, und% PROGRAMFILES%, um pip.exe auszuführen Da \ LibreOffice \ program \ python35.dll erforderlich ist, muss auch der DLL-Suchpfad behandelt werden.
%PROGRAMFILES%\LibreOffice\program\python -m pip
Es kann einfacher sein, damit zu beginnen. Mit pip installierte Pakete werden auch in% APPDATA% \ Roaming \ Python \ Python35 \ site-packages installiert, können jedoch unverändert verwendet werden, da sys.path verfügbar ist.
C:\Users\shota243>"c:\Program Files\LibreOffice\program"\python -m pip install timeout-decorator
Defaulting to user installation because normal site-packages is not writeable
Collecting timeout-decorator
Downloading timeout-decorator-0.4.1.tar.gz (4.8 kB)
Building wheels for collected packages: timeout-decorator
Building wheel for timeout-decorator (setup.py) ... done
Created wheel for timeout-decorator: filename=timeout_decorator-0.4.1-py3-none-any.whl size=5022 sha256=5d3ecc37c619ed429c313b18ddf3b01b309d43dccc65d19ce974df
76af478609
Stored in directory: c:\users\shota243\appdata\local\pip\cache\wheels\df\f4\3c\031226c90008861114781e36ef5898934aad3196808c40e6ea
Successfully built timeout-decorator
Installing collected packages: timeout-decorator
Successfully installed timeout-decorator-0.4.1
Wenn Sie get-pip.py mit Administratorrechten ausführen, können Sie pip in einem Ordner unter% PROGRAMFILES% installieren und auf Ihrem System freigeben. Andere Pakete können auch unter% PROGRAMFILES% installiert werden. Der Ordner% PROGRAMFILES% \ LibreOffice wird jedoch möglicherweise gelöscht, wenn LibreOffice aktualisiert wird, und muss möglicherweise adressiert werden.
FreeBSD
Im Fall von FreeBSD wird LibreOffice nicht mit einem Python-Verarbeitungssystem geliefert, und selbst wenn es sich um ein Makro handelt, wird Python verwendet, das sich im PATH befindet. Mit pip installierte Pakete können auch über Makros verwendet werden. Wenn Sie LibreOffice in einer virtuellen Umgebung starten, können Sie verschiedene Python-Versionen und -Pakete verwenden.
UNO
Verwenden Sie UNO (Universal Network Objects), um LibreOffice programmgesteuert zu betreiben. UNO ist ein sprachunabhängiges Komponentenmodell, das Python-UNO-Bridge (PyUNO-Bridge) verwendet, wenn es von Python aus verwendet wird. .. Verwenden Sie auch die Python-UNO-Brücke, egal ob über ein Makro oder eine externe Verbindung.
LibreOffice kann weder Python-Makros bearbeiten noch Editoren starten. Erstellen Sie ein Python-Makro separat und legen Sie es im folgenden Verzeichnis ab.
--Benutzermakro
%APPDATA%\LibreOffice\4\user\Scripts\python
%PROGRAMFILES%\LibreOffice\share\Scripts\python
--Benutzermakro
${HOME}/.config/libreoffice/4/user/Scripts/python
/usr/local/lib/libreoffice/share/Scripts/python
Das Verzeichnis für die Platzierung von Benutzermakros ist von Anfang an nicht vorhanden. Erstellen Sie es daher bei Bedarf selbst.
APSO --Alternative Script Organizer für Python Nach der Installation der Erweiterung können Sie:
Dies ermöglicht das Bearbeiten, ohne das Makro-Layout zu kennen. Sie können auch versuchen, über den Python-Interpreter auf UNO zuzugreifen.
Globale XSCRIPTCONTEXT-Variablen können über Python-Makros referenziert werden. Über XSCRIPTCONTEXT können Sie mit der folgenden Methode auf die Umgebung zugreifen, in der das Makro gestartet wird.
XSCRIPTCONTEXT ist eine Implementierung der Schnittstelle XScriptContext. Als globale Variable von Python ist es eine Instanz der Klasse pythonscript.ScriptContext.
>>> type(XSCRIPTCONTEXT)
<class 'pythonscript.ScriptContext'>
Klassendefinitionen befinden sich in der Datei /usr/local/lib/libreoffice/program/pythonscript.py.
Die Befehlszeile zum Angeben des Makros beim Starten von LibreOffice lautet wie folgt
soffice 'vnd.sun.star.script:<Name der Skriptdatei>$<Funktionsname>?language=Python&location=user'
Dadurch wird das Makro ausgeführt und LibreOffice beendet. Wenn das Makro den Bildschirm nicht anzeigen muss, schalten Sie den Schalter --headless ein und der Bildschirm wird nicht angezeigt. Wenn während der Makroausführung ein Fehler auftritt, wird ein Fehlerdialog angezeigt und eine Benutzerbestätigung angefordert. Wenn jedoch --headless angegeben ist, wird der Dialog nicht angezeigt und es kommt zu einem Hang.
Beispiel:
mymacro.py
def macrofunc():
pass
Starten ohne Bildschirmanzeige
$ soffice --headless 'vnd.sun.star.script:mymacro.py$macrofunc?language=Python&location=user'
Um eine externe Verbindung zu erhalten, geben Sie den Schalter --accept vorab für LibreOffice an und starten Sie ihn. Für Steckdosenanschluss
$ soffice "--accept=socket,host=<Hostbezeichnung>,port=<Port-Nummer>;urp;"
Für Named Pipe-Verbindung
$ soffice "--accept=pipe,name=<Benannter Rohrname>;urp;"
In beiden Fällen behandelt die Shell eines UNIX-basierten Betriebssystems das Semikolon (;) als Befehlsbegrenzer, daher muss es in Anführungszeichen gesetzt werden.
Beispiel:
$ soffice --writer "--accept=socket,host=0,port=2002;urp;"
$ soffice --calc --headless "--accept=pipe,name=librepipe;urp;"
Python-UNO-Brücke Auf der Beispielseite
"-accept=socket,host=localhost,port=2002;urp;"
Vor "Akzeptieren" steht ein Minuszeichen. Dies ist die alte Notation, und die aktuelle Notation besteht darin, zwei zu schreiben. Im selben Beispiel fügt das Programm auch die Zeichenfolge "Hello, World" in das Writer-Dokument ein. Da das Dokument jedoch nicht neu im Programm erstellt wird, tritt beim Zugriff auf die Texteigenschaft ein Fehler auf, wenn es so ausgeführt wird, wie es ist. Wenn Sie beim Starten von LibreOffice mit dem Schalter --writer ein neues Dokument erstellen, wird dieses Dokument verwendet.
Im Python-Programm wird der Parameter des Optionsschalters --accept beim Starten von LibreOffice angegeben, wenn der Resolver (com.sun.star.bridge.UnoUrlResolver-Instanz) das Verbindungsziel auf der Seite auflöst, die dieselbe Zeichenfolge verbindet. Da Host der Name des Partnerhosts ist, werden unterschiedliche Werte angegeben.
Sobald Sie eine Verbindung zu LibreOffice hergestellt und den Kontext abgerufen haben, können Sie damit eine Desktop-Instanz und eine Instanz der ScriptContext-Klasse erstellen, um die globale Variable XSCRIPTCONTEXT in Ihrem Makro zu ersetzen. Das dritte Argument des ScriptContext-Klassenkonstruktors ist der Aufrufkontext, kann jedoch gemäß der XScriptContext-Schnittstellendokumentation (https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1script_1_1provider_1_1XScriptCon) NULL sein. Geben Sie Keine an.
import uno
from pythonscript import ScriptContext
def connect_script_context(host='localhost', port='2002', namedpipe=None):
UNO_RESOLVER = "com.sun.star.bridge.UnoUrlResolver"
UNO_DESKTOP = "com.sun.star.frame.Desktop"
localCtx = uno.getComponentContext()
localSmgr = localCtx.ServiceManager
resolver = localSmgr.createInstanceWithContext(UNO_RESOLVER, localCtx)
if namedpipe is None:
uno_string = 'uno:socket,host=%s,port=%s;urp;StarOffice.ComponentContext' % (host, port)
else:
uno_string = 'uno:pipe,name=%s;urp;StarOffice.ComponentContext' % namedpipe
ctx = resolver.resolve(uno_string)
smgr = ctx.ServiceManager
XSCRIPTCONTEXT = ScriptContext(ctx,
smgr.createInstanceWithContext(UNO_DESKTOP, ctx),
None)
return XSCRIPTCONTEXT
Durch Zuweisen des Rückgabewerts dieser Funktion connect_script_context () zur globalen Variablen XSCRIPTCONTEXT wird der Fall eines Makros simuliert.
Bei der Verbindung mit LibreOffice von FreeBSD oder einem UNIX-ähnlichen System wird das Python-Programm unter / usr / local / lib / libreoffice / program importiert und die dynamische Linkbibliothek am selben Speicherort wird ebenfalls verwendet, sodass zusätzlich zu PYTHONPATH auch LD_LIBRARY_PATH verwendet wird. Übergeben Sie auch Umgebungsvariablen.
export PYTHONPATH="${PYTHONPATH}:/usr/local/lib/libreoffice/program"
export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:/usr/local/lib/libreoffice/program"
export PATH="${PATH}:/usr/local/lib/libreoffice/program"
Wenn ich tatsächlich eine Verbindung herstelle, kann ich eine Verbindung herstellen und den ComponentContext abrufen. Beim Versuch, Desktop abzurufen, wird jedoch eine Fehlermeldung angezeigt.
>>> import uno
import uno
>>> localContext = uno.getComponentContext()
localContext = uno.getComponentContext()
>>> resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext)
<reateInstanceWithContext("com.sun.star.bridge.UnoUrlResolver", localContext)
>>> ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
ctx = resolver.resolve("uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext")
>>> smgr = ctx.ServiceManager
smgr = ctx.ServiceManager
>>> desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop",ctx)
desktop = smgr.createInstanceWithContext("com.sun.star.frame.Desktop",ctx)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
__main__.RuntimeException: Binary URP bridge disposed during call
Recommended Posts