Skip to main content

sheetpeek

sheetpeek shows an Excel workbook the way Excel shows it: as HTML, Markdown, terminal output or plain text. It is pure Python, needs no office suite, and gives programs access to the rendered cells. Number formats are applied by xlformat, whose output is tested against text captured from Excel 16 for Mac.

Documentation: https://sheetpeek.readthedocs.io.

Reading a sheet

read returns a Sheet: the cached values, number formats, styles, column widths, row heights and merged ranges of one worksheet. Dates stay the serial numbers Excel stores.

>>> import tempfile, pathlib, openpyxl, sheetpeek
>>> path = pathlib.Path(tempfile.mkdtemp()) / "example.xlsx"
>>> wb = openpyxl.Workbook()
>>> wb.active["A1"] = 1234.5
>>> wb.active["A1"].number_format = "#,##0.00"
>>> wb.active.merge_cells("B1:C1")
>>> wb.save(path)
>>> sheet = sheetpeek.read(path)
>>> cell = sheet.cell(1, 1)
>>> cell.value, cell.kind, cell.number_format
(1234.5, 'number', '#,##0.00')
>>> [str(m) for m in sheet.merges]
['B1:C1']

Showing a sheet

sheetpeek.render draws a sheet with a backend. Each shows what Excel shows, as far as its format can: number formats, # for a number too wide for its column, text spilling into empty neighbors.

>>> path = pathlib.Path(tempfile.mkdtemp()) / "sales.xlsx"
>>> wb = openpyxl.Workbook()
>>> ws = wb.active
>>> ws.append(["Region", "Sales", "Change"])
>>> ws.append(["North", 1234.5, 0.125])
>>> ws.append(["South", -98765.4, -0.0425])
>>> ws.append(["A note long enough to spill"])
>>> for row in (2, 3):
...     ws.cell(row, 2).number_format = "#,##0.00;[Red]-#,##0.00"
...     ws.cell(row, 3).number_format = "0.0%"
>>> wb.save(path)
>>> sales = sheetpeek.read(path)
>>> print(sheetpeek.render(sales, "text"), end="")
Region   Sales    Change
North    1,234.50    12.5%
South    ########    -4.3%
A note long enough to spill
>>> print(sheetpeek.render(sales, "markdown"), end="")
| Region | Sales | Change |
| --- | ---: | ---: |
| North | 1,234.50 | 12.5% |
| South | -98,765.40 | -4.3% |
| A note long enough to spill |  |  |
>>> print(sheetpeek.render(sales, "csv"), end="")
Region,Sales,Change
North,"1,234.50",12.5%
South,"-98,765.40",-4.3%
A note long enough to spill,,
>>> page = sheetpeek.render(sales, "html")  # a static page in Excel's own geometry
>>> page.startswith("<!doctype html>")
True

Fixed-width text gives every column its width in characters; Markdown and CSV have no widths, so they show every value in full. HTML is drawn in points from Excel's layout: column widths, row heights, each text's position and clip window, the # runs in the section's color (the negative is red), and fills. sheetpeek.render(sales, "rich"), or rich.print(sales), draws the fixed-width layout in a terminal with fonts, colors and fills (the optional rich extra).

From the command line:

sheetpeek view sales.xlsx                 # rich on a terminal, plain text when piped
sheetpeek view sales.xlsx -t html > sales.html
sheetpeek serve reports/                  # every workbook under reports/ as HTML pages

Sheet.layout gives the layout itself, the data every backend draws from: in excel mode each column's position and width and each text's position in points, in characters mode the characters each column draws. The documentation's usage page has examples.

Cells are read with openpyxl's read-only mode, so memory does not grow with the file while it is read. The parts read-only mode leaves out, such as merges, widths and the used range, come from a separate scan of the sheet's XML. ref="A1:H40" reads part of a sheet, and sheetpeek.open reads several sheets with one load.

Installation

pip install sheetpeek
pip install "sheetpeek[rich]"   # with styled terminal output

Python 3.11 or later. Depends on openpyxl and xlformat.

sheetpeek is part of the sheetmill project, with xlformat, which applies Excel number formats. A third package, a formula engine, is in development.

Development

uv sync --group docs then uv run pytest; CONTRIBUTING.md has the pip route, the full set of checks and the commit conventions. ARCHITECTURE.md describes the design and the measurements behind it.

Most of the code is written with Claude Code, reviewed before each commit and tested against output captured from Excel; see CONTRIBUTING.md.

License

MIT.

Metadata

Release files for sheetpeek 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sheetpeek 0.1.0
File Size Uploaded Provenance Actions
sheetpeek-0.1.0.tar.gz 148.7 kB With provenance Details for sheetpeek-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for sheetpeek 0.1.0
File Interpreter ABI Platform Actions
sheetpeek-0.1.0-py3-none-any.whl Python 3 none any Details for sheetpeek-0.1.0-py3-none-any.whl

Total release size: 206.5 kB

Release files / sheetpeek-0.1.0.tar.gz

Download URL sheetpeek-0.1.0.tar.gz
Size 148.7 kB
Tags Source
SHA-256 checksum
How to use checksums
b548a4cf8829006ff698edfec58ae03bc9646d555ac8498094a73f8b67e230e3
BLAKE2b-256 checksum
How to use checksums
6afe5a30db2f41d04c7e2141b3cdfe0c720a1836b2e30210d708c63870021f3d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Release files / sheetpeek-0.1.0-py3-none-any.whl

Download URL sheetpeek-0.1.0-py3-none-any.whl
Size 57.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
47951d5a2b4fc6399b8b426797b796d1cb76a91d7b8213aae4c85ac219a2a60a
BLAKE2b-256 checksum
How to use checksums
7721444b38a67ec7ea03ad12e163a87cb936f236596db1ff777d365a57921b3f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

Security for sheetpeek 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for sheetpeek-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 1, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page