# `fastexcel`
A fast excel file reader for Python and Rust.
Docs available [here](https://fastexcel.toucantoco.dev/).
## Stability
The Python library is considered production-ready. The API is mostly stable, and we avoid breaking changes as much as
possible. v1.0.0 will be released once the [milestone](https://github.com/ToucanToco/fastexcel/milestone/2) is reached.
The Rust crate is still experimental, and breaking changes are to be expected.
## Installation
```bash
# Lightweight installation (no PyArrow dependency)
pip install fastexcel
# With Polars support only (no PyArrow needed)
pip install fastexcel[polars]
# With Pandas support (includes PyArrow)
pip install fastexcel[pandas]
# With PyArrow support
pip install fastexcel[pyarrow]
# With all integrations
pip install fastexcel[pandas,polars]
```
## Quick Start
### Modern usage (recommended)
FastExcel supports the [Arrow PyCapsule Interface](https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html) for zero-copy data exchange with libraries like Polars, without requiring pyarrow as a dependency.
Use fastexcel with any Arrow-compatible library without requiring pyarrow.
```python
import fastexcel
# Load an Excel file
reader = fastexcel.read_excel("data.xlsx")
sheet = reader.load_sheet(0) # Load first sheet
# Use with Polars (zero-copy, no pyarrow needed)
import polars as pl
df = pl.DataFrame(sheet) # Direct PyCapsule interface
print(df)
# Or use the to_polars() method (also via PyCapsule)
df = sheet.to_polars()
print(df)
# Or access the raw Arrow data via PyCapsule interface
schema = sheet.__arrow_c_schema__()
array_data = sheet.__arrow_c_array__()
```
### Traditional usage (with pandas/pyarrow)
```python
import fastexcel
reader = fastexcel.read_excel("data.xlsx")
sheet = reader.load_sheet(0)
# Convert to pandas (requires `pandas` extra)
df = sheet.to_pandas()
# Or get pyarrow RecordBatch directly
record_batch = sheet.to_arrow()
```
### Working with tables
```python
reader = fastexcel.read_excel("data.xlsx")
# List available tables
tables = reader.table_names()
print(f"Available tables: {tables}")
# Load a specific table
table = reader.load_table("MyTable")
df = pl.DataFrame(table) # Zero-copy via PyCapsule, no pyarrow needed
```
## Key Features
- **Zero-copy data exchange** via [Arrow PyCapsule Interface](https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html)
- **Flexible dependencies** - use with Polars (no PyArrow needed) or Pandas (includes PyArrow)
- **Seamless Polars integration** - `pl.DataFrame(sheet)` and `sheet.to_polars()` work without PyArrow via PyCapsule interface
- **High performance** - written in Rust with [calamine](https://github.com/tafia/calamine) and [Apache Arrow](https://arrow.apache.org/)
- **Memory efficient** - lazy loading and optional eager evaluation
- **Type safety** - automatic type inference with manual override options
## Contributing & Development
### Prerequisites
You'll need:
1. **[Rust](https://rustup.rs/)** - Rust stable or nightly
2. **[uv](https://docs.astral.sh/uv/getting-started/installation/)** - Fast Python package manager (will install Python 3.9+ automatically)
3. **[git](https://git-scm.com/)** - For version control
4. **[make](https://www.gnu.org/software/make/)** - For running development commands
**Python Version Management:**
uv handles Python installation automatically. To use a specific Python version:
```bash
uv python install 3.13 # Install Python 3.13
uv python pin 3.13 # Pin project to Python 3.13
```
### Quick Start
```bash
# Clone the repository (or from your fork)
git clone https://github.com/ToucanToco/fastexcel.git
cd fastexcel
# First-time setup: install dependencies, build debug version, and setup pre-commit hooks
make setup-dev
```
Verify your installation by running:
```bash
make
```
This runs a full development cycle: formatting, building, linting, and testing
### Development Commands
Run `make help` to see all available commands, or use these common ones:
```bash
make all # full dev cycle: format, build, lint, test
make install # install with debug build (daily development)
make install-prod # install with release build (benchmarking)
make test # to run the tests
make lint # to run the linter
make format # to format python and rust code
make doc-serve # to serve the documentation locally
```
### Useful Resources
* [`python/fastexcel/_fastexcel.pyi`](./python/fastexcel/_fastexcel.pyi) - Python API types
* [`python/tests/`](./python/tests) - Comprehensive usage examples
## Benchmarking
For benchmarking, use `make benchmarks` which automatically builds an optimised wheel.
This is required for profiling, as dev mode builds are much slower.
### Speed benchmarks
```bash
make benchmarks
```
### Memory profiling
```bash
mprof run -T 0.01 python python/tests/benchmarks/memory.py python/tests/benchmarks/fixtures/plain_data.xls
```
## Creating a release
1. Create a PR containing a commit that only updates the version in `Cargo.toml`.
2. Once it is approved, squash and merge it into main.
3. Tag the squashed commit, and push it.
4. The `release` GitHub action will take care of the rest.
## Dev tips
* Use `cargo check` to verify that your rust code compiles, no need to go through `maturin` every time
* `cargo clippy` = 💖
* Careful with arrow constructors, they tend to allocate a lot
* [`mprof`](https://github.com/pythonprofilers/memory_profiler) and `time` go a long way for perf checks,
no need to go fancy right from the start
Raw data
{
"_id": null,
"home_page": "https://github.com/ToucanToco/fastexcel",
"name": "fastexcel",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.9",
"maintainer_email": null,
"keywords": null,
"author": null,
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/40/2b/78e3dc13d71a532935662a8d531fe7aa9a2b6bdbd5eec4f1dce01904e6a7/fastexcel-0.15.1.tar.gz",
"platform": null,
"description": "# `fastexcel`\n\nA fast excel file reader for Python and Rust.\n\nDocs available [here](https://fastexcel.toucantoco.dev/).\n\n## Stability\n\nThe Python library is considered production-ready. The API is mostly stable, and we avoid breaking changes as much as\npossible. v1.0.0 will be released once the [milestone](https://github.com/ToucanToco/fastexcel/milestone/2) is reached.\n\nThe Rust crate is still experimental, and breaking changes are to be expected.\n\n## Installation\n\n```bash\n# Lightweight installation (no PyArrow dependency)\npip install fastexcel\n\n# With Polars support only (no PyArrow needed)\npip install fastexcel[polars]\n\n# With Pandas support (includes PyArrow)\npip install fastexcel[pandas]\n\n# With PyArrow support\npip install fastexcel[pyarrow]\n\n# With all integrations\npip install fastexcel[pandas,polars]\n```\n\n## Quick Start\n\n### Modern usage (recommended)\n\nFastExcel supports the [Arrow PyCapsule Interface](https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html) for zero-copy data exchange with libraries like Polars, without requiring pyarrow as a dependency.\nUse fastexcel with any Arrow-compatible library without requiring pyarrow.\n\n```python\nimport fastexcel\n\n# Load an Excel file\nreader = fastexcel.read_excel(\"data.xlsx\")\nsheet = reader.load_sheet(0) # Load first sheet\n\n# Use with Polars (zero-copy, no pyarrow needed)\nimport polars as pl\ndf = pl.DataFrame(sheet) # Direct PyCapsule interface\nprint(df)\n\n# Or use the to_polars() method (also via PyCapsule)\ndf = sheet.to_polars()\nprint(df)\n\n# Or access the raw Arrow data via PyCapsule interface\nschema = sheet.__arrow_c_schema__()\narray_data = sheet.__arrow_c_array__()\n```\n\n### Traditional usage (with pandas/pyarrow)\n\n```python\nimport fastexcel\n\nreader = fastexcel.read_excel(\"data.xlsx\")\nsheet = reader.load_sheet(0)\n\n# Convert to pandas (requires `pandas` extra)\ndf = sheet.to_pandas()\n\n# Or get pyarrow RecordBatch directly\nrecord_batch = sheet.to_arrow()\n```\n\n### Working with tables\n\n```python\nreader = fastexcel.read_excel(\"data.xlsx\")\n\n# List available tables\ntables = reader.table_names()\nprint(f\"Available tables: {tables}\")\n\n# Load a specific table\ntable = reader.load_table(\"MyTable\")\ndf = pl.DataFrame(table) # Zero-copy via PyCapsule, no pyarrow needed\n```\n\n## Key Features\n\n- **Zero-copy data exchange** via [Arrow PyCapsule Interface](https://arrow.apache.org/docs/format/CDataInterface/PyCapsuleInterface.html)\n- **Flexible dependencies** - use with Polars (no PyArrow needed) or Pandas (includes PyArrow)\n- **Seamless Polars integration** - `pl.DataFrame(sheet)` and `sheet.to_polars()` work without PyArrow via PyCapsule interface\n- **High performance** - written in Rust with [calamine](https://github.com/tafia/calamine) and [Apache Arrow](https://arrow.apache.org/)\n- **Memory efficient** - lazy loading and optional eager evaluation\n- **Type safety** - automatic type inference with manual override options\n\n## Contributing & Development\n\n### Prerequisites\n\nYou'll need:\n1. **[Rust](https://rustup.rs/)** - Rust stable or nightly\n2. **[uv](https://docs.astral.sh/uv/getting-started/installation/)** - Fast Python package manager (will install Python 3.9+ automatically)\n3. **[git](https://git-scm.com/)** - For version control\n4. **[make](https://www.gnu.org/software/make/)** - For running development commands\n\n**Python Version Management:**\nuv handles Python installation automatically. To use a specific Python version:\n```bash\nuv python install 3.13 # Install Python 3.13\nuv python pin 3.13 # Pin project to Python 3.13\n```\n\n### Quick Start\n\n```bash\n# Clone the repository (or from your fork)\ngit clone https://github.com/ToucanToco/fastexcel.git\ncd fastexcel\n\n# First-time setup: install dependencies, build debug version, and setup pre-commit hooks\nmake setup-dev\n```\n\nVerify your installation by running:\n\n```bash\nmake\n```\n\nThis runs a full development cycle: formatting, building, linting, and testing\n\n### Development Commands\n\nRun `make help` to see all available commands, or use these common ones:\n\n```bash\nmake all # full dev cycle: format, build, lint, test\nmake install # install with debug build (daily development)\nmake install-prod # install with release build (benchmarking)\nmake test # to run the tests\nmake lint # to run the linter\nmake format # to format python and rust code\nmake doc-serve # to serve the documentation locally\n```\n\n### Useful Resources\n\n* [`python/fastexcel/_fastexcel.pyi`](./python/fastexcel/_fastexcel.pyi) - Python API types\n* [`python/tests/`](./python/tests) - Comprehensive usage examples\n\n## Benchmarking\n\nFor benchmarking, use `make benchmarks` which automatically builds an optimised wheel.\nThis is required for profiling, as dev mode builds are much slower.\n\n### Speed benchmarks\n```bash\nmake benchmarks\n```\n\n### Memory profiling\n```bash\nmprof run -T 0.01 python python/tests/benchmarks/memory.py python/tests/benchmarks/fixtures/plain_data.xls\n```\n\n## Creating a release\n\n1. Create a PR containing a commit that only updates the version in `Cargo.toml`.\n2. Once it is approved, squash and merge it into main.\n3. Tag the squashed commit, and push it.\n4. The `release` GitHub action will take care of the rest.\n\n## Dev tips\n\n* Use `cargo check` to verify that your rust code compiles, no need to go through `maturin` every time\n* `cargo clippy` = \ud83d\udc96\n* Careful with arrow constructors, they tend to allocate a lot\n* [`mprof`](https://github.com/pythonprofilers/memory_profiler) and `time` go a long way for perf checks,\n no need to go fancy right from the start\n\n",
"bugtrack_url": null,
"license": null,
"summary": "A fast excel file reader for Python, written in Rust",
"version": "0.15.1",
"project_urls": {
"Homepage": "https://github.com/ToucanToco/fastexcel",
"Issues": "https://github.com/ToucanToco/fastexcel",
"Source Code": "https://github.com/ToucanToco/fastexcel"
},
"split_keywords": [],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "a84fa39a0093cd7480e63ae88b7c3e310ddc3e3a59c6360191583ccedf305979",
"md5": "b416a178c038d8170fea3fdc822f120a",
"sha256": "d839bbb8326b37e6d167ecef522a1f20b14e0a7f18f9d1bba9530e12decf8628"
},
"downloads": -1,
"filename": "fastexcel-0.15.1-cp39-abi3-macosx_10_12_x86_64.whl",
"has_sig": false,
"md5_digest": "b416a178c038d8170fea3fdc822f120a",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.9",
"size": 3040037,
"upload_time": "2025-09-02T09:33:48",
"upload_time_iso_8601": "2025-09-02T09:33:48.860927Z",
"url": "https://files.pythonhosted.org/packages/a8/4f/a39a0093cd7480e63ae88b7c3e310ddc3e3a59c6360191583ccedf305979/fastexcel-0.15.1-cp39-abi3-macosx_10_12_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "4dbb3690a11d077e101c6b2e2fb76d90464fa0af4ccdac04ce8638ab433f0a7d",
"md5": "88501343e98e31c91abc7ce5dcdbd842",
"sha256": "f94bc44026f261c0b1d212dcdfc315838b2943ea8176c5fdac389f30201eb7b6"
},
"downloads": -1,
"filename": "fastexcel-0.15.1-cp39-abi3-macosx_11_0_arm64.whl",
"has_sig": false,
"md5_digest": "88501343e98e31c91abc7ce5dcdbd842",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.9",
"size": 2795224,
"upload_time": "2025-09-02T09:33:50",
"upload_time_iso_8601": "2025-09-02T09:33:50.344366Z",
"url": "https://files.pythonhosted.org/packages/4d/bb/3690a11d077e101c6b2e2fb76d90464fa0af4ccdac04ce8638ab433f0a7d/fastexcel-0.15.1-cp39-abi3-macosx_11_0_arm64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "90bd736fce45b9dc58d3e3ffb9c27dca55e44f500491e4c73da7b4cf3c51995e",
"md5": "d9fca9c02e28d5876c7c1bf17f4e4161",
"sha256": "7707bee43eb2e9f01cd051e613748505a893d866c95505eb036d920f3dc93f21"
},
"downloads": -1,
"filename": "fastexcel-0.15.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"has_sig": false,
"md5_digest": "d9fca9c02e28d5876c7c1bf17f4e4161",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.9",
"size": 3132791,
"upload_time": "2025-09-02T09:33:44",
"upload_time_iso_8601": "2025-09-02T09:33:44.988525Z",
"url": "https://files.pythonhosted.org/packages/90/bd/736fce45b9dc58d3e3ffb9c27dca55e44f500491e4c73da7b4cf3c51995e/fastexcel-0.15.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "614b9be7f0cf1be1436506a7e9389b4e0bdaec6348d6e3cc597f1387ccc94303",
"md5": "01b6614d3747101d78782bccfe24a093",
"sha256": "b6e598848e98408800574a120dd5b7f02ecbf3490b430829161240202f923140"
},
"downloads": -1,
"filename": "fastexcel-0.15.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "01b6614d3747101d78782bccfe24a093",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.9",
"size": 3317592,
"upload_time": "2025-09-02T09:33:47",
"upload_time_iso_8601": "2025-09-02T09:33:47.469151Z",
"url": "https://files.pythonhosted.org/packages/61/4b/9be7f0cf1be1436506a7e9389b4e0bdaec6348d6e3cc597f1387ccc94303/fastexcel-0.15.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "304b423fdbcd7475f373fad5f002acaf1bddf3fb8e915675e23cb58807ac11a1",
"md5": "78c6234e414fc19d26ec5c2bdb7390c5",
"sha256": "e002ad806cb07867a28787db2c0b4f62c91826219edf92a68b86cb7b177badef"
},
"downloads": -1,
"filename": "fastexcel-0.15.1-cp39-abi3-win_amd64.whl",
"has_sig": false,
"md5_digest": "78c6234e414fc19d26ec5c2bdb7390c5",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.9",
"size": 2805715,
"upload_time": "2025-09-02T09:33:52",
"upload_time_iso_8601": "2025-09-02T09:33:52.016103Z",
"url": "https://files.pythonhosted.org/packages/30/4b/423fdbcd7475f373fad5f002acaf1bddf3fb8e915675e23cb58807ac11a1/fastexcel-0.15.1-cp39-abi3-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "402b78e3dc13d71a532935662a8d531fe7aa9a2b6bdbd5eec4f1dce01904e6a7",
"md5": "1d97c446672988ca24bf87c16d59a13d",
"sha256": "bce738c82c4d043704fbcff802823c51f830ed75e8da64962859d2060d6c743b"
},
"downloads": -1,
"filename": "fastexcel-0.15.1.tar.gz",
"has_sig": false,
"md5_digest": "1d97c446672988ca24bf87c16d59a13d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.9",
"size": 58890,
"upload_time": "2025-09-02T09:33:53",
"upload_time_iso_8601": "2025-09-02T09:33:53.537927Z",
"url": "https://files.pythonhosted.org/packages/40/2b/78e3dc13d71a532935662a8d531fe7aa9a2b6bdbd5eec4f1dce01904e6a7/fastexcel-0.15.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-02 09:33:53",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ToucanToco",
"github_project": "fastexcel",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "fastexcel"
}