Skip to main content

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
  1. ZIP Extract — XLSX is a ZIP archive. Extract all XML entries.
  2. Shared Strings — Resolve <v>74</v>"Alabama" via sharedStrings.xml.
  3. Style Resolve — Map s="59" → font, number format, fill, alignment via styles.xml.
  4. 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

xlsx2semantic-0.1.1.tar.gz (15.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xlsx2semantic-0.1.1-py3-none-any.whl (17.5 kB view details)

Uploaded Python 3

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

Hashes for xlsx2semantic-0.1.1.tar.gz
Algorithm Hash digest
SHA256 0dc9f85433b959f4a478bd2a0a8ab5a06d81d88ad1960022421b1642a1c3adcd
MD5 1b1dcf14daa33c7c06416d2403e3e770
BLAKE2b-256 aa30a0bc6ebb366e5f6984a658cfeb2a59fc5f6b4f24c91d0cea1c40e2f96bd5

See more details on using hashes here.

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

Hashes for xlsx2semantic-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9f519437ed0ca0ea11bc18d4ff09ebce4c91e88871a16e0265bd6267b432e3fe
MD5 6e0f43b29303b8eaa49660ca954828b4
BLAKE2b-256 8f4e9a2bd8d35b3023c13c95649229a04044659b76569e7602f3ed7d8f19feca

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page