Linux - Automate LibreOffice FlatPak
Overview
This guide will show you how to automate LibreOffice FlatPak on Linux.
The process is to start LibreOffice FlatPak, wait for it to be ready, and then send commands to it via a bridge connection using API.
Prerequisites
The libreoffice-script-provider-python
apt package must be installed.
This package allows scripts to connect to LibreOffice.
sudo apt install libreoffice-script-provider-python
Set up virtual environment
LibreOffice Flatpak uses a python that is included with FlatPak.
Get Python version
To start, we need to get the major and minor version of Python from LibreOffice.
The FlatPak version of LibreOffice comes with APSO extension already installed. Start FlatPak LibreOffice and open the APSO extension. In this case we are using Writer.
Tools -> Macros -> Organize python scripts
Start the Python Console
APSO python console [LibreOffice]
3.10.11 (main, Nov 10 2011, 15:00:00) [GCC 12.2.0]
Type "help", "copyright", "credits" or "license" for more information.
>>>
We can see in the console output above that the python version is 3.10.11
in this case.
Now we know we need to create a virtual environment for python 3.10
.
Most Likely your system python will match the Major and the Minor version of python.
Find matching Python version on your system
$ /usr/bin/python3 --version
Python 3.10.6
If you do not get a match for python3
then also try with major and minor prefix and suffix.
You system may have the version installed.
$ /usr/bin/python3.10 --version
Python 3.10.6
If you do not have a python version matching major and minor version, 3.10
in this case,
then it is recommended to use a tool such as pyenv to install a version of python that matches.
Create a virtual Environment
Create a virtual environment for you system.
Make a project Directory.
$ mkdir ~/my-project
cd ~/my-project
Create Virtual Environment using the matching python version found above.
/usr/bin/python3.10 -m venv .venv
Activate Virtual Environment
source .venv/bin/activate
Now that the virtual environment is activated, we can install the required packages.
Install OOOENV
The virtual environment has been created but it does not yet have access to uno.py
and unohelper.py
which are needed to use the LibreOffice API.
For this we will use the oooenv package.
Make sure you have activated the virtual environment.
oooenv is a Python package that allows you to auto configure a virtual environment to be used by LibreOffice.
Install oooenv in the virtual environment:
python -m pip install oooenv
Now that the package is installed we can use it to configure the virtual environment to use uno.py
and unohelper.py
.
oooenv cmd-link -a
Now the virtual environment is configured to use uno.py
and unohelper.py
.
Automate with ooo-dev-tools
Requires ooo-dev-tools version 0.11.8
or greater.
Install ooo-dev-tools
python -m pip install ooo-dev-tools
Run an automation script
We will create a simple script to automate LibreOffice FlatPak by the Name of hello_world.py
.
Connecting to LibreOffice FlatPak is a little different than connecting to LibreOffice installed on the system.
First of all starting FlatPak LibreOffice from a python script seems to need the --display
argument set to the current display.
If it is not set we may get an error and the script may hang.
So in the script below we are getting the current display and setting it to the --display
argument via os.getenv('DISPLAY')
.
Next we must instruct OooDev to use the FlatPak version of LibreOffice. Normally OooDev will use the system installed version of LibreOffice by default; However, we need to instruct OooDev to use the FlatPak version of LibreOffice.
This is done by setting the soffice
argument to the flatpak run org.libreoffice.LibreOffice/x86_64/stable
value.
The display setting are passed to the extended_args
argument.
It also seem ConnectPipe
does not work with FlatPak LibreOffice so we are using ConnectSocket
.
The same thing is true with Snap installed LibreOffice.
The rest is straight forward for OooDev.
from __future__ import annotations
import os
import uno
from ooodev.office.calc import Calc
from ooodev.gui.gui import GUI
from ooodev.utils.kind.zoom_kind import ZoomKind
from ooodev.loader.lo import Lo
from ooodev.dialog.msgbox import (
MsgBox, MessageBoxType, MessageBoxButtonsEnum, MessageBoxResultsEnum
)
def main():
display_str = f"--display {os.getenv('DISPLAY', ':0')}"
_ = Lo.load_office(
Lo.ConnectSocket(
soffice="flatpak run org.libreoffice.LibreOffice/x86_64/stable",
extended_args=[display_str],
)
)
try:
doc = Calc.create_doc()
GUI.set_visible(True, doc)
Lo.delay(500)
Calc.zoom(doc, ZoomKind.ZOOM_100_PERCENT)
sheet = Calc.get_sheet(doc, 0)
Calc.set_val(value="Hello World!", sheet=sheet, cell_name="A1")
msg_result = MsgBox.msgbox(
"Do you wish to close document?",
"All done",
boxtype=MessageBoxType.QUERYBOX,
buttons=MessageBoxButtonsEnum.BUTTONS_YES_NO,
)
if msg_result == MessageBoxResultsEnum.YES:
Lo.close_doc(doc=doc, deliver_ownership=True)
Lo.close_office()
else:
print("Keeping document open")
except Exception:
Lo.close_office()
raise
return
if __name__ == "__main__":
main()
Note
The Code to connection to LibreOffice FlatPak is something like this:
# is it important to use shell=True
import os
from subprocess import Popen
Popen(f'flatpak run org.libreoffice.LibreOffice/x86_64/stable --invisible --norestore --nofirststartwizard --nologo --accept="socket,host=localhost,port=2002,tcpNoDelay=1;urp;" --display {os.getenv("DISPLAY")}', shell=True)
Once the script is created and save as hello_world.py
we can run it
python hello_world.py