# Document Skills XLSX

> XLSX workbench

- Skill: `minimax-ai/document-skills-xlsx` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add minimax-ai/document-skills-xlsx`
- Raw SKILL.md: https://api.skillmd.com/api/skills/minimax-ai/document-skills-xlsx/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: MiniMax AI (https://skillmd.com/u/minimax-ai)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/minimax-ai/document-skills-xlsx

---


# XLSX workbench

Spreadsheets are where agents do the most damage by being clever: pasted values where formulas
belong, dates written as text, whole-number floats displayed as `3.0000000001`. Follow the
contracts below.

## Step 0 - Check the toolchain

```bash
python -c "import defusedxml, openpyxl; print(openpyxl.__version__, defusedxml.__version__)"
```

- `.csv`/`.tsv` -> standard library `csv` module is fine and often better (streaming).
- `.xlsx`/`.xlsm`/`.xltx` -> openpyxl.
- Safe package preflight requires `defusedxml==0.7.1`; do not fall back to the standard XML
  parser for untrusted OOXML parts.
- Macro preservation: openpyxl keeps VBA in `.xlsm` only with `keep_vba=True` on load and save.
- Before **any** `openpyxl.load_workbook()` of an existing package, copy and use the bounded
  same-handle loader in [references/package.md](references/package.md). `read_only=True` does
  not bound shared strings, styles, or other package parts parsed during initialization.

## Step 1 - Classify the task

| Request | Route |
|---|---|
| Open, inspect, profile a workbook | [references/read.md](references/read.md) |
| Edit cells, add sheets, fix formatting | [references/edit.md](references/edit.md) |
| Build a new workbook (data + formulas + chart) | [references/create.md](references/create.md) |
| CSV/TSV in or out, messy data cleanup | [references/csv.md](references/csv.md) |
| Conditional formatting, structured tables, pivot-style aggregation | [references/formatting.md](references/formatting.md) |
| Safely open an existing OOXML package | [references/package.md](references/package.md) |

## Step 2 - Contracts that always apply

1. **Formulas are formulas.** If the user asks for a total/average/lookup, write `=SUM(B2:B10)`
   in the cell - never the computed number - unless the user explicitly asked to freeze values.
   openpyxl writes the formula; Excel/WPS/LibreOffice calculate on open.
2. **`data_only=True` reads cached values** (last calculated by a real app) and **loses
   formulas on save**. Use it only for reading values; never load, edit, and save with it.
3. **Types**: write `int`/`float`/`datetime`/`bool`, never formatted strings. Dates go in as
   `datetime` with `number_format='yyyy-mm-dd'`; currency as float plus
   `number_format='#,##0.00'` (or the locale-appropriate currency format string).
4. **Formulas are not recalculated by openpyxl.** After writing formulas, set
   `wb.calculation.fullCalcOnLoad = True` before saving so Excel/WPS/LibreOffice recalculate
   on open even when the workbook (typically one you loaded, which can carry
   `fullCalcOnLoad=False`) uses calculation mode `manual` - check
   `wb.calculation.calcMode`. You still cannot read results back without opening the file in
   a real spreadsheet app; verify formula strings and ranges structurally instead (see
   postcheck).
5. **Dimensions**: treat `<dimension>`, `ws.max_row`, and `ws.max_column` as untrusted hints.
   Discover logical cells with the sparse worksheet-XML scan in the read route; never expand an
   unknown rectangular range merely to find its bounds.
6. Save to a new path first; overwrite only on explicit request.

## Step 3 - Postcheck (mandatory)

Save this as `postcheck.py`, copy `load_validated_workbook()` and its dependencies from
[references/package.md](references/package.md), then pass the output path followed by every
sheet the task should produce, for example `python postcheck.py output.xlsx Sales Summary`:

```python
import openpyxl
import sys

if len(sys.argv) < 3:
    raise SystemExit("usage: python postcheck.py OUTPUT.xlsx EXPECTED_SHEET [...]")
output_path, *expected_sheets = sys.argv[1:]
# Populate this whenever the task requested specific display formats.
expected_number_formats = {
    # "Sales": {"D2": "#,##0.00", "E2": "yyyy-mm-dd"},
}
# Populate every formula the task intends to create or preserve.
expected_formulas = {
    # "Sales": {"D2": "=C2*1.08"},
}
# Populate every expected sheet with the exact used range required by the task.
expected_dimensions = {
    # "Sales": "A1:E20",
    # "Summary": "A1:C8",
}
wb = load_validated_workbook(output_path)

def require(condition, message):
    if not condition:
        raise ValueError(message)

def formula_text(value):
    if isinstance(value, str):
        return value
    if text := getattr(value, "text", None):
        return text
    fields = ("ref", "r1", "r2", "dt2D", "dtr", "ca", "del1", "del2")
    details = ", ".join(
        f"{name}={getattr(value, name)!r}" for name in fields if hasattr(value, name)
    )
    return f"{type(value).__name__}({details})"

print("sheets:", wb.sheetnames)
missing = set(expected_sheets) - set(wb.sheetnames)
require(not missing, f"missing expected sheets: {sorted(missing)}")
require(
    set(expected_dimensions) == set(expected_sheets),
    "expected_dimensions must declare the exact used range for every expected sheet",
)
calc = wb.calculation
print("calcMode:", getattr(calc, "calcMode", None),
      "fullCalcOnLoad:", getattr(calc, "fullCalcOnLoad", None))
if any(expected_formulas.values()):
    require(
        getattr(calc, "fullCalcOnLoad", False) is True
        or getattr(calc, "calcMode", None) == "auto",
        "formula output is not configured to recalculate in spreadsheet viewers",
    )
for ws in wb.worksheets:
    print(f"{ws.title} dims:", ws.dimensions)
    if ws.title in expected_dimensions:
        require(
            ws.dimensions == expected_dimensions[ws.title],
            f"{ws.title}: expected used range {expected_dimensions[ws.title]!r}, "
            f"got {ws.dimensions!r}",
        )
    # `expected_formulas` is the task contract, so verify those coordinates directly.
    # Never call unbounded iter_rows(): one styled extreme cell can make the rectangle huge.
    actual_formulas = {}
    for coordinate, expected_formula in expected_formulas.get(ws.title, {}).items():
        cell = ws[coordinate]
        actual_formula = formula_text(cell.value) if cell.data_type == "f" else None
        actual_formulas[coordinate] = actual_formula
        require(
            actual_formula == expected_formula,
            f"{ws.title}!{coordinate}: expected formula {expected_formula!r}, "
            f"got {actual_formula!r}",
        )
    print(f"{ws.title} expected formula cells:", list(actual_formulas.items())[:10])
    for coordinate, expected_format in expected_number_formats.get(ws.title, {}).items():
        actual_format = ws[coordinate].number_format
        require(actual_format == expected_format, (
            f"{ws.title}!{coordinate}: expected format {expected_format!r}, got {actual_format!r}"
        ))
wb.close()
```

Confirm: expected sheet names exist; used range matches expectations; intended formula cells
contain formula strings; when the task wrote formulas, the printout shows `fullCalcOnLoad: True`
(or `calcMode: auto`) so viewers will recalculate — otherwise set it and re-save; every
task-specific formatted cell is listed in `expected_number_formats` and matches. Report what
was verified and note that final rendered values require opening in a spreadsheet application.

