Excel is the most-shipped data format in the world after CSV, and the cost of touching it always shows up in three places: type confusion, hidden state, and round-trip drift.
Type confusion
Excel auto-detects types when you open or paste a file. Once detected, the type is stored in the cell — meaning that opening a CSV in Excel and saving it again can permanently change values. The classic offenders:
- Leading zeros gone (
00123ZIP code becomes123). - Long IDs in scientific notation (
1234567890123456becomes1.23457E+15, losing the last digits). - Gene names parsed as dates (
MARCH1becomes1-Mar). - Strings that look like fractions parsed as fractions (
1/2becomes0.5).
Hidden state
An Excel file isn't just cell values. It's also formulas, conditional formatting, named ranges, hidden columns, autofilters, comments, change tracking, embedded objects, and macros. Reading an XLSX with openpyxl or pandas ignores most of that — which is fine, but means the file you read is not the file the human sees.
Round-trip drift
Even if you read and write the same file with no edits, formula evaluation order, locale-specific separators, and floating-point representation can cause tiny diffs that ruin git commits and trip up downstream consumers.
The rule: read Excel only at the boundary of a pipeline (when a human supplies one), and convert to Parquet immediately. Never make Excel a stage in your pipeline; only an input or an output.