Transform XLSX files into LLM-friendly semantic XML
Project description
xlsx2semantic
Transform XLSX into LLM-friendly semantic XML.
Raw Excel XML is unreadable — cell references like <c r="B7" t="s"><v>74</v></c> mean nothing to an LLM.
xlsx2semantic converts that into structured, self-describing XML that any language model can instantly understand.
Before (raw OOXML) After (semantic XML)
───────────────────── ────────────────────
<c r="B7" s="59" t="s"> <record row="7" state="Alabama">
<v>74</v> <total_number>745938</total_number>
</c> <total_percent>100</total_percent>
<c r="C7" s="60"> </record>
<v>745938</v>
</c>
Why?
| Problem | xlsx2semantic |
|---|---|
| LLMs can't parse raw OOXML cell references | Headers become tag names, data becomes readable records |
| Shared strings are just index numbers | Automatically resolved to actual text |
| Merged cells break structure | Propagated correctly across the grid |
| Multi-level headers are ambiguous | Combined into hierarchical tag names |
| Style indices are opaque | Resolved to human-readable font, color, format info |
Quick Start
Install
pip install xlsx2semantic
Python
from xlsx2semantic import parse_file
result = parse_file("enrollment.xlsx")
# Semantic XML — headers as tags, rows as records
for sheet, xml in result.semantic_xml.items():
print(xml)
Output:
<semantic-table>
<title>Public school enrollment by race/ethnicity</title>
<schema>
<row-key index="2" attribute="state"/>
<column index="3" tag="total_number"/>
<column index="4" tag="total_percent"/>
</schema>
<records count="52">
<record row="8" state="Alabama">
<total_number>745938</total_number>
<total_percent>100</total_percent>
</record>
<record row="9" state="Alaska">
<total_number>132731</total_number>
<total_percent>100</total_percent>
</record>
</records>
</semantic-table>
CLI
# Semantic XML (default)
xlsx2semantic data.xlsx
# With layout hints
xlsx2semantic data.xlsx --title-range "B2:*2" --header-range "B4:*6" --row-meta-col B
# Save to file
xlsx2semantic data.xlsx -o output.xml
# Different output modes
xlsx2semantic data.xlsx --mode cell # enriched <cell> tags
xlsx2semantic data.xlsx --mode raw-xml # original OOXML
xlsx2semantic data.xlsx --mode all # everything
Install CLI extras: pip install xlsx2semantic[cli]
Layout Hints
For complex spreadsheets, guide the parser with explicit layout hints:
from xlsx2semantic import parse_file
result = parse_file(
"report.xlsx",
title_range="B2:*2", # title rows (B2, cols to end of sheet)
header_range="B4:*6", # header area (rows 4-6, cols to end)
row_meta_col="B", # row label column → becomes record attribute
)
Range Syntax
| Pattern | Meaning |
|---|---|
B4:Z6 |
Exact range: col B–Z, row 4–6 |
B4:*6 |
Col B to end of sheet, row 4–6 |
B4:Z* |
Col B–Z, row 4 to end of sheet |
B4:** |
Col B to end, row 4 to end |
* = automatically expands to the last row or column in the sheet.
Without hints, xlsx2semantic auto-detects headers using a text/numeric ratio heuristic.
Three Output Layers
xlsx2semantic gives you three views of the same spreadsheet:
| Layer | Description | Access |
|---|---|---|
| Raw XML | Original OOXML extracted from ZIP | result.xml_entries |
| Cell XML | <c> → <cell> with resolved styles, types, values |
result.cell_xml |
| Semantic XML | Headers as tags, data as records | result.semantic_xml |
Cell XML Example
<cell ref="B7" row="7" col="2" styleIndex="59"
font="Arial 11pt Bold" numberFormat="#,##0" fill="solid FF333399"
type="sharedString" rawValue="74" value="Alabama"/>
Every opaque attribute is resolved:
t="s"→type="sharedString",value="Alabama"s="59"→font="Arial 11pt Bold",numberFormat="#,##0"
How It Works
┌──────────┐ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ .xlsx │────▶│ ZIP Extract │────▶│ Shared Str │────▶│ Semantic │
│ (OOXML) │ │ Raw XML │ │ Style Resolve│ │ Transform │
└──────────┘ └─────────────┘ └──────────────┘ └──────────────┘
│ │ │
xml_entries cell_xml semantic_xml
- ZIP Extract — XLSX is a ZIP archive. Extract all XML entries.
- Shared Strings — Resolve
<v>74</v>→"Alabama"viasharedStrings.xml. - Style Resolve — Map
s="59"→ font, number format, fill, alignment viastyles.xml. - Semantic Transform — Detect (or use hints for) title/header/data regions → generate semantic XML.
Use Cases
- RAG pipelines — Feed structured spreadsheet data into retrieval systems
- LLM tool use — Let agents query spreadsheet data via semantic XML
- Data extraction — Convert messy government/financial Excel reports into clean structure
- Spreadsheet QA — Ask natural language questions about tabular data
Development
git clone https://github.com/kangminjugit/xlsx2semantic.git
cd xlsx2semantic
pip install -e ".[dev,cli]"
pytest -v
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file xlsx2semantic-0.1.1.tar.gz.
File metadata
- Download URL: xlsx2semantic-0.1.1.tar.gz
- Upload date:
- Size: 15.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0dc9f85433b959f4a478bd2a0a8ab5a06d81d88ad1960022421b1642a1c3adcd
|
|
| MD5 |
1b1dcf14daa33c7c06416d2403e3e770
|
|
| BLAKE2b-256 |
aa30a0bc6ebb366e5f6984a658cfeb2a59fc5f6b4f24c91d0cea1c40e2f96bd5
|
File details
Details for the file xlsx2semantic-0.1.1-py3-none-any.whl.
File metadata
- Download URL: xlsx2semantic-0.1.1-py3-none-any.whl
- Upload date:
- Size: 17.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9f519437ed0ca0ea11bc18d4ff09ebce4c91e88871a16e0265bd6267b432e3fe
|
|
| MD5 |
6e0f43b29303b8eaa49660ca954828b4
|
|
| BLAKE2b-256 |
8f4e9a2bd8d35b3023c13c95649229a04044659b76569e7602f3ed7d8f19feca
|