Starting LibreOffice with Python — Macro Programming in OpenOffice/LibreOffice with using Python[EN]-2

Rebah Özkoç
Analytics Vidhya
Published in
4 min readDec 18, 2019

Hi guys, I haven’t been able to write the second article of the series for a while because I was a little busy because of the exams. Now it’s time to continue :)

In this article, I will explain how to open LibreOffice with Python and connect to the office we opened. We will write a function for this.

From this point on, I will use PyCharm as an integrated development environment (IDE) in my articles. I suggest you use it. To set up our IDE, first of all, let’s create a project in PyCharm where we will write macros.

When creating the project, let’s create a new virtual environment as in the screenshot. As a Python base interpreter, let’s choose LibreOffice’s own Python interpreter. I explained in my previous article where we can find this interpreter.

Error: standard python 'venv' module not found

Note: If you encounter an error like this after the project was created, create the project with the default base interpreter again. Then edit the interpreter in the project settings and replace the default interpreter with LibreOffice’s Python interpreter.

Now let’s create a new file with .py extension. If your operating system is Windows, you should add the following code block to the beginning of the function. If you do not use Windows, you may not add it.

import sys
import os

if sys.platform == 'win32':
#This is required in order to make pyuno usable with the default python interpreter under windows
#Some environment variables must be modified

#get the install path from registry
import _winreg
# try with OpenOffice, LibreOffice on W7
for _key in [# OpenOffice 3.3
"SOFTWARE\\OpenOffice.org\\UNO\\InstallPath",
# LibreOffice 3.4.5 on W7
"SOFTWARE\\Wow6432Node\\LibreOffice\\UNO\\InstallPath"]:
try:
value = _winreg.QueryValue(_winreg.HKEY_LOCAL_MACHINE, _key)
except Exception as detail:
_errMess = "%s" % detail
else:
break # first existing key will do
install_folder = '\\'.join(value.split('\\')[:-1]) # 'C:\\Program Files\\OpenOffice.org 3'

#modify the environment variables
os.environ['URE_BOOTSTRAP'] = 'vnd.sun.star.pathname:{0}\\program\\fundamental.ini'.format(install_folder)
os.environ['UNO_PATH'] = install_folder+'\\program\\'

sys.path.append(install_folder+'\\Basis\\program')
sys.path.append(install_folder+'\\program')

paths = ''
for path in ("\\URE\\bin;", "\\Basis\\program;", "'\\program;"):
paths += install_folder + path
os.environ['PATH'] = paths+ os.environ['PATH']

On Windows, Python is having trouble running UNO. This code solves this problem.

Now let’s define our main function.

import os
import shutil
import subprocess
import tempfile
import time
import uno
import uuid
from com.sun.star.connection import NoConnectException

def
start_libreoffice():
# This depends on your LibreOffice installation location.
sofficePath = '/opt/libreoffice6.3/program/soffice'
tempDir = tempfile.mkdtemp()

# Restore cached profile if available
userProfile = tempDir + '/profile'
cacheDir = os.getenv('XDG_CACHE_DIR', os.environ['HOME'] + '/.cache') + '/lo_profile_cache'
if os.path.isdir(cacheDir):
shutil.copytree(cacheDir, userProfile)
profileCached = True
else
:
os.mkdir(userProfile)
profileCached = False
# Launch the LibreOffice server
pipeName = uuid.uuid4().hex
args = [
sofficePath,
'-env:UserInstallation=file://' + userProfile,
'--pidfile=' + tempDir + '/soffice.pid',
'--accept=pipe,name=' + pipeName + ';urp;',
'--norestore',
'--invisible']
sofficeEnvironment = os.environ
sofficeEnvironment['TMPDIR'] = tempDir
subprocess.Popen(args, env=sofficeEnvironment, preexec_fn=os.setsid)
# Open connection to server
for i in range(100):
try:
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext("com.sun.star.bridge.UnoUrlResolver",localContext)
context = resolver.resolve("uno:pipe,name=%s;urp;StarOffice.ComponentContext" % pipeName)
break
except
NoConnectException:
time.sleep(0.1)
if i == 99:
raise
# Cache profile if required
if not profileCached:
shutil.copytree(userProfile, cacheDir)
return_list = [context.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop",context), context]
return return_list

In this function you have to change the sofficePath variable to the location where LibreOffice is installed. I explained it in my first article.

If we didn’t have a problem to this point, soffice should be opened in the background when we call the function. After you call the function, you can see the application called Soffice.bin in the running processes in the task manager.

The function we defined returns a list as a result. If you want, you can simply return the variable named context and define the first variable of return_list with this object. But I find it more useful to define it as above.

To see more advanced examples you can check this repository that I created for this blog series.

In my next post, I will explain how to open a new document or an existing document with the objects that we returned. Goodbye :)

Important resources I refer to when creating this article series:

--

--

Rebah Özkoç
Analytics Vidhya

I’m a computer science student. I am sharing at here interesting and useful stuff which I encounter while studying :)