Apple Numbers Spreadsheet Parser
numbers-parser is a Python module for reading and editing Apple Numbers .numbers files. It supports Numbers files generated by Numbers versions 3.x and later, and is tested against Numbers documents from 10.0 through to 15.1 (as of February 2026). It supports Python versions from 3.10 onwards and is actively maintained.
Common errors
-
No module named 'snappy'
cause The `python-snappy` package, a dependency of `numbers-parser`, requires native binary libraries which are not always automatically installed or found by `pip` on all operating systems.fixEnsure `snappy`'s binary dependencies are installed on your system. For macOS, use `brew install snappy`. For Debian/Ubuntu Linux, use `sudo apt-get install libsnappy-dev`. For Windows, you may need to find pre-compiled `python-snappy` wheels or build from source. -
AttributeError: 'Document' object has no attribute 'sheets' (or 'tables')
cause You are likely trying to call `doc.sheets()` or `sheet.tables()` as methods, which were removed in version 4.0. They are now properties.fixAccess `sheets` and `tables` as properties: `doc.sheets` and `sheet.tables`. -
numbers_parser.exceptions.UnsupportedError: Document is password-protected
cause `numbers-parser` cannot open Apple Numbers documents that are protected by a password.fixOpen the `.numbers` file in Apple Numbers and save it without a password before attempting to parse it with `numbers-parser`. -
RuntimeWarning: Cannot parse image filename with UTF-8 characters; returned None
cause This warning occurs on Python versions older than 3.11 when image filenames within the Numbers document contain UTF-8 characters, due to a limitation in Python's `ZipFile` module.fixUpgrade to Python 3.11 or newer to correctly handle such filenames, or avoid documents with UTF-8 characters in image filenames.
Warnings
- breaking In version 4.0, the methods `Document.sheets()` and `Sheet.tables()` were removed. You must now access `sheets` and `tables` as properties.
- deprecated The `image_data` and `image_filename` methods were deprecated in version 4.0 and replaced by the `cell_style` property for background image data. They will be removed in a future version.
- gotcha Password-encrypted Numbers documents cannot be opened and will raise an `UnsupportedError`. You must remove the password manually in Numbers before parsing.
- gotcha Writing to existing Numbers files is not recommended, as `numbers-parser` may not perfectly replicate all original formatting or features. It is safer to save new data to a *new* file.
- gotcha `python-snappy` (a dependency) requires platform-specific binary libraries for snappy compression. Installation may require additional OS-level package manager commands (e.g., `libsnappy-dev` on Linux, Homebrew's `snappy` on macOS, or specific pre-compiled wheels on Windows).
- gotcha Formulas cannot be written to a document. Pivot tables are unsupported, and saving a document with a pivot table issues an `UnsupportedWarning`.
- gotcha NumberCell values are limited to 15 significant figures to match Apple Numbers' floating-point implementation. Attempting to write a number with more than 15 significant digits results in a `RuntimeWarning` and rounding.
Install
-
pip install numbers-parser -
# macOS (Homebrew Python recommended): brew install snappy python3 pipx pipx install numbers-parser # Linux (Debian/Ubuntu): sudo apt-get -y install libsnappy-dev pip install numbers-parser # Windows (x86 binaries for python-snappy are not readily available on PyPI, consider using pre-compiled wheels or ARM Windows)
Imports
- Document
from numbers_parser import Document
- Sheet
from numbers_parser import Document doc = Document('file.numbers') sheet = doc.sheets[0] - Table
from numbers_parser import Document doc = Document('file.numbers') sheet = doc.sheets[0] table = sheet.tables[0]
Quickstart
from numbers_parser import Document
# Create a dummy Numbers file for demonstration
# In a real scenario, you would have an existing .numbers file.
# For this quickstart, we'll simulate a file path.
# Make sure 'mydoc.numbers' exists or replace with a real path.
# If you don't have one, create a simple one in Apple Numbers and save it.
file_path = 'example.numbers'
# You might need to create a simple example.numbers file manually
# with at least one sheet and one table for this to run.
# For example, create a new Numbers spreadsheet, add some data to Sheet 1, Table 1, and save as example.numbers.
try:
doc = Document(file_path)
sheets = doc.sheets
print(f"Document has {len(sheets)} sheets.")
if sheets:
first_sheet = sheets[0]
print(f"First sheet name: {first_sheet.name}")
if first_sheet.tables:
first_table = first_sheet.tables[0]
print(f"First table name: {first_table.name}")
print("Table data (first 5 rows):")
for row_idx, row in enumerate(first_table.rows()):
if row_idx >= 5: break
print(f" Row {row_idx}: {[cell.value for cell in row]}")
else:
print("First sheet has no tables.")
else:
print("Document has no sheets.")
except FileNotFoundError:
print(f"Error: The file '{file_path}' was not found. Please create a simple .numbers file or adjust the path.")
except Exception as e:
print(f"An error occurred: {e}")