# XLSX Parsing

Read Microsoft Excel (.xlsx) files robustly with `openpyxl` (or `pandas`).

- Repository: https://github.com/benchflow-ai/skillsbench (1888 stars)
- Category: Documents
- License: Apache-2.0
- Last updated: 2026-10-24
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add benchflow-ai/skillsbench --skill xlsx-parsing -g -a claude-code -y`
Codex: `npx skills add benchflow-ai/skillsbench --skill xlsx-parsing -g -a codex -y`
Cursor: `npx skills add benchflow-ai/skillsbench --skill xlsx-parsing -g -a cursor -y`
Gemini CLI: `npx skills add benchflow-ai/skillsbench --skill xlsx-parsing -g -a gemini-cli -y`

## Description

Read Microsoft Excel (.xlsx) files robustly with `openpyxl` (or `pandas`). Covers multi-sheet workbooks, header rows, empty cells, merged cells, comma-separated list cells, and converting a sheet to a list-of-dicts the rest of your code can consume. Use when a task input or reference document is an `.xlsx` file rather than JSON/CSV.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# xlsx-parsing

Excel workbooks are the lingua franca of operational documents that nobody bothered to put in a database, playbooks, rate cards, deviation policies, finance models, SLAs. They show up in tasks with three properties that trip up naive readers:

1. **Multiple sheets**, only one of which is the data you actually want.
2. **Sparse cells**, a row that uses a column may sit next to a row that doesn't, leaving `None` cells. Empty is meaningful (the rule does not apply), not an error.
3. **Composite cells**, a single cell that contains a comma-separated list, a JSON blob, or a sentence rather than an atomic value.

Treat the workbook as a *typed table* with declared columns, not a free-form spreadsheet. Read every sheet you need, normalise it to `list[dict[str, Any]]`, then operate on that.

## Reading with `openpyxl` (pure Python, no compiled dependencies)

```python
import openpyxl

wb = openpyxl.load_workbook("workbook.xlsx", data_only=True, read_only=True)
print(wb.sheetnames)            # e.g., ['Metadata', 'Definitions', 'Rules']

ws = wb["Rules"]
rows = ws.iter_rows(values_only=True)
header = [str(c).strip() if c else "" for c in next(rows)]
records = [dict(zip(header, row)) for row in rows if any(cell is not None for cell in row)]
```

Notes:
- `data_only=True` returns the cached value of formula cells instead of the formula expression. Without this you may get strings like `"=A1+B2"`.
- `read_only=True` is faster on big workbooks and avoids loading styles you don't need.
- The `any(cell is not None ...)` filter drops entirely-blank rows that Excel preserves at the bottom of a sheet.
- `dict(zip(header, row))` handles trailing empty columns gracefully when a row is shorter than the header.

## Reading with `pandas` (if it's installed)

```python
import pandas as pd

# Multi-sheet read returns a dict of DataFrames
sheets = pd.read_excel("workbook.xlsx", sheet_name=None, dtype=object)
rules_df = sheets["Rules"]

The rest: https://github.com/benchflow-ai/skillsbench/blob/HEAD/tasks-extra/nda-playbook-review/environment/skills/xlsx-parsing/SKILL.md
