
Xlsx
Recalculate Excel formulas in agent pipelines using openpyxl and headless LibreOffice when exports must match desktop Excel results.
Overview
xlsx is an agent skill most often used in Build (also Operate reporting) that recalculates Excel formulas via openpyxl and headless LibreOffice macros.
Install
npx skills add https://github.com/appautomaton/document-skills --skill xlsxWhat is this skill?
- Python ≥3.12 script with openpyxl dependency for workbook load/save
- Headless LibreOffice macro bootstrap (`RecalculateAndSave`) when macro missing
- Cross-platform macro path handling (macOS Library vs Linux config dir)
- `calculateAll()` + store workflow for faithful formula evaluation
- requires-python >=3.12
- openpyxl dependency declared in script header
Adoption & trust: 1.1k installs on skills.sh; 107 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your agent writes .xlsx files with formulas but recipients see blank or wrong values because nothing executed the formula engine after generation.
Who is it for?
Indie builders automating invoices, models, or ops spreadsheets in Python who already use or can install LibreOffice.
Skip if: Pure Google Sheets workflows or environments where installing LibreOffice/soffice is blocked.
When should I use this skill?
Generated or modified .xlsx files contain formulas that must be evaluated before handoff.
What do I get? / Deliverables
You get workbooks with evaluated formulas saved back to disk, ready for email, BI import, or customer download.
- Recalculated .xlsx file on disk
- Optional LibreOffice Module1 macro for repeat runs
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Spreadsheet automation lands in Build when wiring document pipelines into product or internal ops tooling. Canonical shelf is tool integration (Python + LibreOffice macro), not writing marketing copy in Grow.
Where it fits
Post-process agent-generated pricing model .xlsx before attaching it to a SaaS export endpoint.
Nightly cron recalculates ops dashboards stored as Excel templates on a VPS.
Refresh lead-magnet spreadsheet downloads so formula cells show current metrics.
How it compares
Local formula execution bridge—not a hosted Excel API or Microsoft Graph integration.
Common Questions / FAQ
Who is xlsx for?
Solo developers building document automation with Python who need reliable formula recalc without manual Excel clicks.
When should I use xlsx?
In Build (integrations) when piping generated workbooks into CI or apps; in Operate (iterate) for scheduled report regeneration; in Grow (content) when shipping downloadable spreadsheet templates with live formulas.
Is xlsx safe to install?
It runs shell and LibreOffice against files you specify—review the Security Audits panel on this page and sandbox paths you do not trust.
SKILL.md
READMESKILL.md - Xlsx
# /// script # requires-python = ">=3.12" # dependencies = ["openpyxl"] # /// """ Excel Formula Recalculation Script Recalculates all formulas in an Excel file using LibreOffice """ import json import sys import subprocess import os import platform from pathlib import Path from openpyxl import load_workbook def setup_libreoffice_macro(): """Setup LibreOffice macro for recalculation if not already configured""" if platform.system() == 'Darwin': macro_dir = os.path.expanduser('~/Library/Application Support/LibreOffice/4/user/basic/Standard') else: macro_dir = os.path.expanduser('~/.config/libreoffice/4/user/basic/Standard') macro_file = os.path.join(macro_dir, 'Module1.xba') if os.path.exists(macro_file): with open(macro_file, 'r') as f: if 'RecalculateAndSave' in f.read(): return True if not os.path.exists(macro_dir): subprocess.run(['soffice', '--headless', '--terminate_after_init'], capture_output=True, timeout=10) os.makedirs(macro_dir, exist_ok=True) macro_content = '''<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd"> <script:module xmlns:script="http://openoffice.org/2000/script" script:name="Module1" script:language="StarBasic"> Sub RecalculateAndSave() ThisComponent.calculateAll() ThisComponent.store() ThisComponent.close(True) End Sub </script:module>''' try: with open(macro_file, 'w') as f: f.write(macro_content) return True except Exception: return False def recalc(filename, timeout=30): """ Recalculate formulas in Excel file and report any errors Args: filename: Path to Excel file timeout: Maximum time to wait for recalculation (seconds) Returns: dict with error locations and counts """ if not Path(filename).exists(): return {'error': f'File {filename} does not exist'} abs_path = str(Path(filename).absolute()) if not setup_libreoffice_macro(): return {'error': 'Failed to setup LibreOffice macro'} cmd = [ 'soffice', '--headless', '--norestore', 'vnd.sun.star.script:Standard.Module1.RecalculateAndSave?language=Basic&location=application', abs_path ] # Handle timeout command differences between Linux and macOS if platform.system() != 'Windows': timeout_cmd = 'timeout' if platform.system() == 'Linux' else None if platform.system() == 'Darwin': # Check if gtimeout is available on macOS try: subprocess.run(['gtimeout', '--version'], capture_output=True, timeout=1, check=False) timeout_cmd = 'gtimeout' except (FileNotFoundError, subprocess.TimeoutExpired): pass if timeout_cmd: cmd = [timeout_cmd, str(timeout)] + cmd result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0 and result.returncode != 124: # 124 is timeout exit code error_msg = result.stderr or 'Unknown error during recalculation' if 'Module1' in error_msg or 'RecalculateAndSave' not in error_msg: return {'error': 'LibreOffice macro not configured properly'} else: return {'error': error_msg} # Check for Excel errors in the recalculated file - scan ALL cells try: wb = load_workbook(filename, data_only=True) excel_errors = ['#VALUE!', '#DIV/0!', '#REF!', '#NAME?', '#NULL!', '#NUM!', '#N/A'] error_details = {err: [] for err in excel_errors} total_errors = 0 for sheet_name in wb.sheetnames: ws = wb[sheet_name] # Check ALL rows and columns - no limits for row in ws.iter_rows(): for cell in