Yes. LibreOffice Calc can run Python code as a macro inside the LibreOffice process, and a LibreOffice Basic macro can also call a Python function through LibreOffice's scripting framework. If your goal is to read or change cells in the open spreadsheet, an in-process Python macro is usually the simplest starting point. Use a Basic-to-Python call when an existing Basic macro should hand one task to a reusable Python function.
These approaches are different from launching an ordinary system Python script with a shell command. A normal external Python process does not automatically receive Calc's document object. For workbook access, run a Python macro through LibreOffice or deliberately connect an external process to a LibreOffice instance through UNO.
What does “run Python inside a Calc macro” mean?
LibreOffice supports multiple scripting languages through its scripting framework. In a Python macro, LibreOffice supplies a UNO context object that lets the script reach the current document and its sheets. A Python macro is a function in a .py module; the module's g_exportedScripts tuple identifies functions that LibreOffice should show as runnable macros.
A Python macro can run on its own from Calc's macro menu. It does not have to be called by Basic. If you already have a Basic macro and want it to call Python, LibreOffice's script provider or the newer ScriptForge Session.ExecutePythonScript service can bridge the two languages.
Which approach should you choose?
- Use a Python macro directly when the task is mostly Python and needs the current Calc document. It avoids a language handoff and is easiest to debug as one script.
- Call Python from Basic when you already have Basic code, buttons, or document events that should remain in place, and you want a Python helper to perform a focused calculation or data operation.
- Use an external Python process when you need a separate development environment or Python packages not included with LibreOffice. Set up an explicit UNO connection; do not assume a script started from a terminal can see the open spreadsheet.
For example, a small spreadsheet cleanup tool can be written entirely as a Python macro. If an existing Basic button already runs a report, keep the button's macro and let it call a Python function that computes the report total.
How do you create a Python macro that edits Calc cells?
LibreOffice stores personal Python scripts in the user profile, application-wide scripts in the installation directory, and document scripts with a document. For a first test, a personal script is convenient because it is available from any open LibreOffice document for the same user. It does not travel with an ODS file, however, so another person will not automatically receive it with the spreadsheet.
Find the personal Python scripts folder for your system in LibreOffice Help under “Python Scripts Organization and Location.” Common locations include %APPDATA%\LibreOffice\4\user\Scripts\python on Windows and ~/.config/libreoffice/4/user/Scripts/python on Linux. The actual profile can vary; use the location documented for your installation rather than creating a second profile directory by guesswork.
Create a file named calc_tools.py in the personal Python scripts folder, then add this simple example:
def double_a1(args=None):
doc = XSCRIPTCONTEXT.getDocument()
sheet = doc.getCurrentController().getActiveSheet()
source = sheet.getCellRangeByName("A1")
target = sheet.getCellRangeByName("B1")
target.setValue(source.getValue() * 2)
g_exportedScripts = (double_a1,)
This reads the numeric value in cell A1 of the active sheet and writes twice that value to B1. XSCRIPTCONTEXT is supplied to a LibreOffice Python macro at run time; it is not a regular Python global when the same file is launched outside LibreOffice. The public function is listed in g_exportedScripts so it appears in the macro selector.
Save the file, then open or return to Calc and choose Tools > Macros > Run Macros. Depending on the LibreOffice version or platform translation, the menu label may be singular. Select My Macros > calc_tools > double_a1 and run it. Enter a number in A1 first, then check that B1 contains the doubled value. If the module does not appear, confirm the file extension is .py, the file is in the correct profile's Python folder, and Python scripting support is installed. Restarting LibreOffice after adding a new module can help refresh the script list.
How can a Basic macro call a Python function?
For a Basic-to-Python call, put a Python module in the personal scripts folder and call its function through ScriptForge's Session service. This example adds two values in Python and writes the result to B1 in the current Calc sheet.
In calc_tools.py, define the function:
def add_values(first, second):
return float(first) + float(second)
g_exportedScripts = (add_values,)
Then create a Basic macro in Calc and use:
Sub RunPythonHelper()
Dim session As Object
Dim result As Variant
Dim sheet As Object
session = CreateScriptService("Session")
result = session.ExecutePythonScript( _
session.SCRIPTISPERSONAL, _
"calc_tools.py$add_values", _
12, 30)
sheet = ThisComponent.CurrentController.getActiveSheet()
sheet.getCellRangeByName("B1").setValue(result)
End Sub
Run RunPythonHelper from the Basic macro selector. If the call succeeds, B1 should display 42. The script reference follows the form module.py$function_name; for a module in a subfolder or another storage location, use the syntax and location constant documented for that ScriptForge version. Keep arguments and return values to data types both languages can represent cleanly, such as numbers, strings, and simple sequences.
CreateScriptService and the documented ScriptForge session helpers are available in modern LibreOffice versions, but menu names and bundled components can differ in older or distribution-packaged builds. If this service is unavailable, use LibreOffice's documented UNO script-provider method, which obtains an XScript from a script URI and invokes it. Avoid copying a code fragment for a different macro location without changing its location setting.
Should the Python code be personal, shared, or embedded?
| Storage | Best fit | Trade-off |
| My Macros / user profile | Your own reusable tools across documents | Not automatically included when you send the spreadsheet |
| Application Macros | Scripts managed for multiple users on one installation | Typically requires administrator access to install or maintain |
| Document macros | Code intended to be associated with one document | Recipients may need to allow macros; test portability and security behavior on the target LibreOffice version |
For a team workflow, decide how recipients will get and trust the code before building a workbook around a personal macro. If the Python logic must accompany the spreadsheet, test the document's macro storage and security prompts on the same LibreOffice versions your recipients use. For managed deployment, an administrator can package scripts for users or distribute an extension under the organization's normal software controls.
Why might the macro be missing or fail?
- The Python option or module is absent. On some GNU/Linux distributions, LibreOffice's Python scripting framework is an optional package. Check the distribution's LibreOffice packaging instructions if Python macros do not appear in the macro dialog.
- The script is saved in the wrong profile. LibreOffice can use multiple user profiles. Confirm the profile path for the running installation and save the module under its
Scripts/python directory.
- The function is not exported. Add it to
g_exportedScripts for a function you intend to run from the macro selector. Make sure the tuple syntax includes the trailing comma for a one-item tuple.
- The script runs outside LibreOffice.
XSCRIPTCONTEXT exists for a macro launched by LibreOffice, not when the same file is started with the system's python command. Use the macro runner or set up a documented UNO connection.
- Macro security blocks embedded code. Review LibreOffice's macro security settings and only enable code from a source you trust. Lowering the global security level is not a good troubleshooting shortcut.
- An imported module cannot see the document context. LibreOffice documents that
XSCRIPTCONTEXT is not passed to imported modules. Pass the needed document or sheet object into helper functions instead of expecting imported modules to read that global.
- There is no visible console output. Python's standard output is not available when a macro is run from the Tools > Macros menu. For feedback, write a result into a cell, use a LibreOffice dialog service, or log to a deliberate file path.
How do you verify the result safely?
Test with a copy of the spreadsheet and a known input. Confirm the Python macro appears in the runner, run it once, and compare the output cell with a hand-calculated result. For a Basic-to-Python call, test one simple input and confirm the returned value is written to the intended sheet. Avoid starting with scripts that delete sheets, overwrite large ranges, or execute operating-system commands.
When the test works, decide how the script will be installed on other computers and document any required Python libraries or LibreOffice version assumptions. LibreOffice's bundled Python environment is the one used for in-process macros; packages installed for a separate system Python interpreter may not be available to it. If you need packages from another interpreter, use the external-process/UNO approach and configure that connection deliberately.
Official references