Metadata-Version: 2.4
Name: excel-form-extractor
Version: 0.1.0
Summary: Extract checkboxes and dropdowns from .xlsx and .xls Excel files
Project-URL: Homepage, https://github.com/asadani/excel-form-extractor
Project-URL: Repository, https://github.com/asadani/excel-form-extractor
Project-URL: Bug Tracker, https://github.com/asadani/excel-form-extractor/issues
Project-URL: Changelog, https://github.com/asadani/excel-form-extractor/releases
License: MIT
Keywords: checkbox,dropdown,excel,extraction,form,xls,xlsx
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Office Suites
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Provides-Extra: dev
Requires-Dist: black>=24.0; extra == 'dev'
Requires-Dist: flake8>=7.0; extra == 'dev'
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: xlrd>=2.0.1; extra == 'dev'
Requires-Dist: xlsxwriter>=3.1.0; extra == 'dev'
Provides-Extra: xls
Requires-Dist: xlrd>=2.0.1; extra == 'xls'
Description-Content-Type: text/markdown

# excel-form-extractor

Extract checkboxes and dropdowns from Excel files (`.xlsx` / `.xls`) — no Excel installation required.

## Installation

```bash
pip install excel-form-extractor
```

`.xls` support requires the optional `xlrd` extra:

```bash
pip install excel-form-extractor[xls]
```

## Python API

```python
from excel_form_extractor import extract

result = extract("survey.xlsx")

# Checkboxes — grouped by row proximity
for group in result.checkboxes:
    print(group.group_name, group.sheet)
    for cb in group.checkboxes:
        print("  ", cb.cell, "✓" if cb.checked else "☐")

# Dropdowns
for dd in result.dropdowns:
    print(dd.sheet, dd.cells, dd.source)

# JSON serialisation
import json
print(json.dumps(result.to_dict(), indent=2))
```

### `extract()` signature

```python
extract(
    file_path: str | Path,
    *,
    sheet: str | None = None,       # restrict to one sheet (case-sensitive)
    controls: str | None = None,    # "checkbox", "dropdown", or None (both)
) -> ExtractionResult
```

### Return types

| Class | Fields |
|---|---|
| `ExtractionResult` | `checkboxes: list[CheckboxGroup]`, `dropdowns: list[Dropdown]`, `.to_dict()` |
| `CheckboxGroup` | `group_name`, `sheet`, `row`, `checkboxes: list[Checkbox]` |
| `Checkbox` | `cell`, `checked`, `label` |
| `Dropdown` | `sheet`, `cells`, `source` |

## CLI

```bash
xfe file.xlsx
xfe file.xlsx --sheet Sheet1
xfe file.xlsx --controls checkbox
xfe file.xlsx --json                   # JSON to stdout
xfe file.xlsx --output                 # save to results/<stem>-<timestamp>.json
xfe file.xlsx --output out.json        # save to a custom path
xfe --version
```

### Sample output

```
============================================================
CHECKBOXES  (2 groups, 3 total)
============================================================

  Group: "Preferences"  [Sheet: Survey, Row 3]
    ✓  B3
    ☐  D3
    ✓  F3

  Group: "Row5"  [Sheet: Survey, Row 5]
    ☐  B5
    ✓  G5

============================================================
DROPDOWNS  (1 total)
============================================================

  1. Cells: B2   Sheet: Form
     Source: "Yes,No,Maybe"
```

## Checkbox detection

Three strategies are applied automatically:

1. **Boolean cells** (`t="b"`) — checkboxes created in Google Sheets and exported to `.xlsx`
2. **VML form controls** — legacy Excel checkboxes (`.xlsx` only)
3. **xlrd boolean cells** — `.xls` files via the optional `xls` extra

> `.xls` files: VML form controls and dropdowns are not available (xlrd limitation).

## Grouping

Checkboxes in the same row with a column gap ≤ 2 (at most one empty column between them) are placed in the same group. The group name is inferred from the text cell immediately to the left of the first checkbox; falls back to `Row{n}`.

## Project layout

```
excel_form_extractor/
    __init__.py     public API: extract(), models
    models.py       dataclasses: Checkbox, CheckboxGroup, Dropdown, ExtractionResult
    _checkbox.py    checkbox extraction and proximity grouping
    _dropdown.py    dropdown extraction
    _utils.py       shared helpers (cell refs, xlsx internals, text cells)
    cli.py          CLI entry point (xfe command)
    py.typed        PEP 561 type marker
sample.py           dev utility — regenerates samples/  (python sample.py)
samples/            sample .xlsx files for testing
results/            default output dir for --output
```

## Development

```bash
git clone https://github.com/asadani/excel-form-extractor
cd excel-form-extractor
pip install -e ".[dev]"

# Regenerate sample files
python sample.py

# Run tests
pytest

# Lint
flake8 excel_form_extractor
black excel_form_extractor
```

## License

MIT
