scalpel@labs: ~/glossary/xlsx-excel-spreadsheet.mdx5 sections

XLSX Files: What an Excel Workbook Actually Is

XLSX is the modern Excel workbook format. Despite the single icon, an `.xlsx` file is a zip archive of XML parts (the OOXML standard, ECMA-376): a workbook, one sheet per worksheet, styles and relationships. That structure is why it can hold multiple sheets and cell types a CSV cannot.

extension: Scalpel Tablesupdated: 2026-08-14read_time: 3 min
less xlsx-excel-spreadsheet.mdx

Why it matters

XLSX is not just "a spreadsheet format." It's a structured container. That matters because a CSV can only be a flat grid of text, one sheet, no formatting. XLSX holds numbers that stay numeric, dates that stay dates, formulas that work, multiple sheets, and styles. When you export to XLSX, your data doesn't get mangled on import like it does in CSV.

A CSV import in Excel will turn 007 into 7 and 2025-01-15 into a number if the column width is wrong. XLSX avoids that: you export once and open it correctly every time.

How it works

An XLSX file is a zip archive. Rename any .xlsx to .zip and you can extract it. Inside you'll find:

[Content_Types].xml: Registry of file types inside the archive. Tells the reader which files are sheets, styles, themes, or relationships.

_rels/ directory: Relationship definitions. How the workbook relates to its sheets, styles, theme, and external links.

xl/workbook.xml: The workbook definition. Lists every sheet, their names, and their IDs. The entry point.

xl/worksheets/sheet1.xml, sheet2.xml, etc.: One XML file per sheet. Contains every cell, its value, its data type, and its style ID.

xl/styles.xml: Cell formatting: fonts, colours, number formats, alignment, fills.

xl/theme/theme1.xml: Colour scheme and theme definitions.

When you open an XLSX in Excel, the reader:

  1. Unzips the archive.
  2. Reads workbook.xml to find the sheets.
  3. Reads each sheetN.xml to load cell values.
  4. Applies styles from styles.xml.
  5. Renders the grid.

What does not matter

Macros. XLSX doesn't store macros; that's XLSM. An XLSX is safe. A cell starting with = is a formula, but it's marked as inline text (not executable). No risk of injection.

Multiple sheets being hard. Stacking tables into one XLSX as separate sheets is trivial. The writer creates a new sheetN.xml for each table, updates the relationship files, and zips it back up.

Exact formatting fidelity. A web table often has no font, no colours, no borders. The exported XLSX will be plain grey-and-white cells. That's fine; you're exporting data, not a design.

Code example

Here's what a minimal XLSX workbook looks like when you unzip it:

[Content_Types].xml
_rels/.rels
xl/
  workbook.xml
  worksheets/sheet1.xml
  styles.xml
  theme/theme1.xml

Inside xl/workbook.xml:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  <sheets>
    <sheet name="Data" sheetId="1" r:id="rId1"/>
  </sheets>
</workbook>

A cell in xl/worksheets/sheet1.xml:

<row r="1">
  <c r="A1" t="n"><v>42</v></c>
  <c r="B1" t="inlineStr"><is><t>Widget A</t></is></c>
  <c r="C1" t="d"><v>2025-01-15T00:00:00</v></c>
</row>

The t attribute tells the reader the type:

  • n = number. 42 stays 42.
  • inlineStr = inline string. Text is literal, never a formula.
  • d = date. The value is an ISO 8601 timestamp.

This is why XLSX is safer than CSV. A cell beginning with = in XLSX is declared as inline text and will never execute as a formula, even if someone opens it in Excel and tries to trigger it.

When exporting multiple tables, the writer creates a new sheet for each:

<workbook>
  <sheets>
    <sheet name="Table 1" sheetId="1" r:id="rId1"/>
    <sheet name="Table 2" sheetId="2" r:id="rId2"/>
    <sheet name="Table 3" sheetId="3" r:id="rId3"/>
  </sheets>
</workbook>

How Scalpel Tables shows it

When you click XLSX on a detected table, the extension builds the workbook in memory and triggers a download. If you're exporting multiple tables, the merge bar's XLSX button builds one workbook with a sheet per table. Each sheet is named after the page (if there's only one table) or a sanitised version of the table's position on the page.

Open the file in Excel, Google Sheets, or LibreOffice and every cell's type is respected. Numbers stay numbers. Dates are readable. No import wizard, no data mangling.

Sources