← Excel (.xlsx): all libraries · Reader board

openpyxl vs python-calamine: which one reads more real-world Excel (.xlsx) files?

openpyxl 3.1.5 and python-calamine 0.9.1 on the same 353 odd real-world files from Apache POI test files (bug reports, fuzzers, broken exporters). Measured, not opinion; re-tested by itself on every new PyPI release. Updated 06 November 2026.

More files readpython-calamine293 vs 286
Faster on this setpython-calamine2.0 s vs 19.4 s total (10× faster)
Both read282only openpyxl: 4 · only python-calamine: 11

python-calamine got text from more files: 293 vs 286 of 353. openpyxl broke (error, hang or crash) on 5 files that python-calamine read; python-calamine broke on 2 files that openpyxl read.

LibraryText from🔴 Fails where
the other reads
🟡 Empty where
the other reads
⏱ Hangs or
crashes
Median
ms/file
Total
seconds
openpyxl 3.1.5286560619.4
python-calamine 0.9.1293220<12.0

Files only openpyxl reads (4)

49783.xlsxpython-calamine: no text
duplicate-filename-case-insensitive.xlsxpython-calamine: no text
poc-shared-strings.xlsxpython-calamine: CalamineError: Range is missing the expected row component.
xlsx-corrupted.xlsxpython-calamine: XmlError: Relationships

Files only python-calamine reads (11)

123233_charts.xlsxopenpyxl: no text
49609.xlsxopenpyxl: KeyError: "There is no item named '[Content_Types].xml' in the archive"
52348.xlsxopenpyxl: no text
57914.xlsxopenpyxl: no text
LIBRE_OFFICE-128382-0.xlsxopenpyxl: TypeError: expected <class 'openpyxl.styles.fills.Fill'>
SampleSS.strict.xlsxopenpyxl: no text
SimpleStrict.xlsxopenpyxl: no text
clusterfuzz-testcase-minimized-POIXSSFFuzzer-5937385319563264.xlsxopenpyxl: BadZipFile: Bad CRC-32 for file 'xl/worksheets/sheet8.xml'
picture.xlsxopenpyxl: TypeError: CellStyle.__init__() got an unexpected keyword argument 'ZMIENNA_contentFontsCount'
sample.strict.xlsxopenpyxl: no text
style-alternate-content.xlsxopenpyxl: TypeError: <class 'openpyxl.styles.named_styles._NamedCellStyle'>.name should be <class 'str'> but value is <class 'NoneType'>

What this does not tell you

This compares not breaking: whether each library gets any text out of each file. It does not rank text quality (reading order, tables, headings), and speed is one GitHub-hosted runner, default settings, no OCR switched on. If you need structure for RAG, also look at the output on your own files.

How this is measured