Skip to main content

Pure-Python reader for Excel Binary Workbook (.xlsb) files

Project description

Claude ChatGPT GitHub Actions

xlsb_reader

A pure-Python module for reading Excel Binary Workbook (.xlsb) files.

The XLSB format published from Microsoft was used to code this up.

[!WARNING]
This has been coded using a mixture of claude (sonnet 4.5) and codex (gpt-5.3 codex).

Supports reading:

  • Formulas
  • Values
  • Pivot tables

TODO

  • Support for reading:
    • filters

Installation

pip install xlsb_reader

CLI Usage

The xlsb_reader command extracts formulas, values, and pivot table metadata from an .xlsb file.

xlsb_reader <path> [sheet_name] [--format dict|json|markdown] [--include formulas,values,pivots]

Output all data (default dict format)

xlsb_reader workbook.xlsb

Filter to a single sheet

xlsb_reader workbook.xlsb "Sheet1"

JSON output

xlsb_reader workbook.xlsb --format json

Markdown output

xlsb_reader workbook.xlsb --format markdown

Only formulas, as JSON

xlsb_reader workbook.xlsb --include formulas --format json

Only values from a specific sheet

xlsb_reader workbook.xlsb "Sheet1" --include values --format json

Only pivot table metadata

xlsb_reader workbook.xlsb --include pivots --format json

Python Module Usage

from xlsb_reader import XlsbWorkbook, col_to_letter

List sheet names

with XlsbWorkbook("workbook.xlsb") as wb:
    print(wb.sheet_names)
# ['Sheet1', 'Sheet2', 'Summary']

Read all formulas

iter_formulas() yields (sheet_name: str, formulas: dict[tuple[int, int], str]).

Formula strings always start with =. If a formula cannot be decoded, the value will be =<parse_error:...> rather than raising an exception — filter these out if needed:

with XlsbWorkbook("workbook.xlsb") as wb:
    for sheet_name, formulas in wb.iter_formulas():
        for (row, col), formula in sorted(formulas.items()):
            if formula.startswith("=<parse_error:"):
                continue  # skip cells that failed to decode
            cell = f"{col_to_letter(col)}{row + 1}"
            print(f"{sheet_name}!{cell}: {formula}")
# Sheet1!A1: =SUM(B1:B10)
# Sheet1!C3: =IF(A3>0,A3*1.2,0)

Read all cell values

iter_values() yields (sheet_name: str, values: dict[tuple[int, int], str | int | float | bool | str]).

Possible value types per cell:

Type Example Notes
int 42 Integer-valued numbers
float 3.14 Decimal numbers
str "Hello" Text cells
bool True Boolean cells
str (error) "#DIV/0!" Excel error; possible values: #DIV/0!, #N/A, #NAME?, #NULL!, #NUM!, #REF!, #VALUE!
with XlsbWorkbook("workbook.xlsb") as wb:
    for sheet_name, values in wb.iter_values():
        for (row, col), value in sorted(values.items()):
            cell = f"{col_to_letter(col)}{row + 1}"
            print(f"{sheet_name}!{cell}: {value!r}")
# Sheet1!A1: 42
# Sheet1!B2: 'Hello World'
# Sheet1!C5: True
# Sheet1!D9: '#DIV/0!'

Read pivot table metadata

iter_pivot_tables() yields one dict per pivot table. Full schema:

{
    "name": "PivotTable1",          # str | None
    "cache_id": 1,                  # int | None — links to the pivot cache
    "data_caption": "Values",       # str | None
    "sheet": "Sheet1",              # str — sheet the pivot table lives on
    "pivot_fields": 5,              # int — number of fields (columns) in the cache
    "pivot_items": 42,              # int — total number of items across all fields
    "location": {
        "rfx_geom": {
            "top_left": "A3",       # str — first cell of the pivot table body
            "bottom_right": "D20",  # str — last cell of the pivot table body
        },
        "rw_first_head":  3,        # int — 1-based row of the header row
        "rw_first_data":  5,        # int — 1-based row where data rows start
        "col_first_data": "B",      # str — column letter where data columns start
        "page_rows":      1,        # int — number of page-filter rows
        "page_cols":      0,        # int — number of page-filter columns
    },
    "part": "xl/pivotTables/pivotTable1.bin",                        # str — internal zip path
    "pivot_cache_definition": "xl/pivotCache/pivotCacheDefinition1.bin",  # str | None
}
with XlsbWorkbook("workbook.xlsb") as wb:
    for pt in wb.iter_pivot_tables():
        print(pt["name"], "on sheet:", pt["sheet"])
        print("  cache_id:", pt.get("cache_id"))
        print("  fields:", pt.get("pivot_fields"))
        loc = pt.get("location") or {}
        geom = loc.get("rfx_geom") or {}
        print(f"  range: {geom.get('top_left')}:{geom.get('bottom_right')}")

Filter to a specific sheet

with XlsbWorkbook("workbook.xlsb") as wb:
    for sheet_name, formulas in wb.iter_formulas():
        if sheet_name != "Sheet1":
            continue
        for (row, col), formula in sorted(formulas.items()):
            print(f"{col_to_letter(col)}{row + 1}: {formula}")

Convert (row, col) to a cell address

row and col from iter_formulas / iter_values are 0-based.

from xlsb_reader import col_to_letter

col_to_letter(0)   # 'A'
col_to_letter(25)  # 'Z'
col_to_letter(26)  # 'AA'

row, col = 2, 3    # 0-based → D3
cell = f"{col_to_letter(col)}{row + 1}"
print(cell)        # 'D3'

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

xlsb_reader-0.2.0.tar.gz (90.0 kB view details)

Uploaded Source

Built Distribution

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

xlsb_reader-0.2.0-py3-none-any.whl (18.5 kB view details)

Uploaded Python 3

File details

Details for the file xlsb_reader-0.2.0.tar.gz.

File metadata

  • Download URL: xlsb_reader-0.2.0.tar.gz
  • Upload date:
  • Size: 90.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for xlsb_reader-0.2.0.tar.gz
Algorithm Hash digest
SHA256 8add69c4765e614a65bb9acd3987e93a720695cf02e703d4403d9c4f53ce4104
MD5 5afebdf4573b01bddc071ae4985515c1
BLAKE2b-256 82b93cbcdb990df7fcf55d9658a255c51b70b83426fd8773414adf11c7223c18

See more details on using hashes here.

Provenance

The following attestation bundles were made for xlsb_reader-0.2.0.tar.gz:

Publisher: release.yml on parj/xslb_reader

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file xlsb_reader-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: xlsb_reader-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 18.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for xlsb_reader-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c374ac4f473dbcaabf3ac29d67cb18647d57496d72719ff1ad8569f297b547d3
MD5 f033443b4099de2ab7ce5d2d82e0e8a1
BLAKE2b-256 93f2a4bb420282e1d9b80052841e0da3556ac6203ae1b75d5eadb1c29f42773f

See more details on using hashes here.

Provenance

The following attestation bundles were made for xlsb_reader-0.2.0-py3-none-any.whl:

Publisher: release.yml on parj/xslb_reader

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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