Read large binary Excel files from Delta tables efficiently on resource-constrained Databricks clusters.
Use Case: SharePoint ingestion pipeline using Databricks Lakeflow Connect
Reading binary Excel data stored in Delta tables using PySpark/Pandas fails on shared Databricks clusters due to:
- Driver OOM – Spark serializes large binary blobs through driver memory
- gRPC limits – Spark Connect enforces 128MB message size limit
- JVM heap pressure – Apache POI loads entire workbook into memory
Traditional approaches require 64GB+ clusters to process 500MB Excel files, yet remain slower, leading to increased cloud costs.
Bypass Spark's serialization layer entirely:
Executor writes binary to UC Volume → Polars reads directly → Parquet → Spark
Tested on 16GB single-node cluster (Standard_DC4as_v5, DBR 17.3):
| File Size | Rows | Cols | pandas + openpyxl | This library | Speedup |
|---|---|---|---|---|---|
| 100MB | 79,500 | 135 | 2m 2s | 38s | 3.2x |
| 500MB | 390,000 | 135 | OOM | 130s | ∞ |
| 1GB | 780,000 | 135 | OOM | 449s | ∞ |
| Excel File Size | Minimum RAM | Recommended RAM |
|---|---|---|
| 100MB | 4GB | 8GB |
| 500MB | 8GB | 16GB |
| 1GB | 16GB | 32GB |
Add to cluster libraries (Compute → Libraries → Install new → PyPI):
fastexcel
polars
To test with sample data:
- Run
setup_test_data.pyto generate test Excel and load as binary into Delta table - Update configuration in
databricks_excel_reader.pywith your catalog/schema/volume - Run
databricks_excel_reader.py
The setup script generates synthetic data with mixed types (strings, numbers, dates, nulls) similar to real-world Excel files.
from databricks_excel_reader import read_binary_excel
df = read_binary_excel(
spark=spark,
table_name="catalog.schema.excel_table",
binary_column="content",
sheet_name="Sheet1",
volume_base_path="/Volumes/catalog/schema/volume",
)
df.write.format("delta").saveAsTable("catalog.schema.output")| Parameter | Description | Default |
|---|---|---|
table_name |
Delta table containing binary Excel data | required |
binary_column |
Column name with binary content | required |
sheet_name |
Excel sheet to read | required |
volume_base_path |
Unity Catalog Volume for temp files | required |
foreachPartition writes binary to Volume with no return value, avoiding driver memory.
Then:
- Polars + Calamine (Rust) parses Excel
- Writes Parquet to Volume
- Spark reads Parquet natively
localCheckpoint()breaks lineage- Cleanup removes temp files
- Databricks Runtime 13.0+
- Unity Catalog Volume access
- Python packages:
fastexcel,polars
Run setup_test_data.py in your Databricks workspace to generate test data:
- Import the notebook
- Update the configuration (catalog, schema, volume path)
- Choose test size:
small(10MB),medium(100MB), orlarge(500MB) - Run all cells
This creates a Delta table with binary Excel content matching the expected schema.
- Requires Unity Catalog Volume for temp storage
- Single-threaded Excel parsing (Polars limitation)
- Schema inferred from first 10,000 rows
MIT
databricks-excel-reader/
├── README.md
├── LICENSE
├── databricks_excel_reader.py # Main solution
├── setup_test_data.py # Test data generator
├── init_script.sh # Cluster setup
└── examples/ # Comparison approaches
├── pandas_approach.py
└── pyspark_approach.py
└── new_pyspark_approach.py