Skip to main content
Symptoms first, in the order people hit them.
Errors raised from the Rust core arrive as OSError, not ValueError. Catch OSError when you need to handle a failed write.

The file won’t open

Usually a malformed custom number format code, since Jetxl passes anything containing a digit straight through to Excel. Try the column formats one at a time, or switch to a built-in name to confirm.Overlapping table ranges cause the same symptom. Two tables covering any of the same cells makes Excel reject the workbook.
Check for an exception you might be swallowing. Jetxl validates the schema before writing, so an unsupported column type raises rather than producing a partial file. See Data types.

A feature didn’t appear

This is the most common class of problem, because several mistakes are dropped silently rather than raised.
An unrecognized rule_type causes the whole rule to be dropped, with no error. Check the spelling against cell_value, color_scale, data_bar and top10.
A table dictionary missing a required key, such as name, is dropped the same way.
Jetxl drops colors it can’t parse and writes the file anyway. Named colors such as "red" and three-digit shorthand such as "F00" are both dropped. Use six or eight hex digits. See Conventions.
Check the spelling of operator. An unrecognized value silently becomes greater_than, so greater_then gives you a working file with the wrong rule.
After adding a conditional format, table or chart, open the file once and confirm it’s there. A dropped feature looks identical to one you forgot to add.

Something looks wrong

Built-in percentage formats multiply by 100 for display. Store 0.15 for 15 percent rather than 15.
Indexing isn’t uniform. cell_styles, header_content and table ranges use 1-based rows with 0-based columns, while chart and image positions are 0-based on both axes.
NaN and infinity are written as empty cells, because neither is valid in the spreadsheet format. Fill them before writing if they carry meaning.
Control characters other than tab, newline and carriage return are stripped, since they have no legal representation in the underlying XML. Scraped or legacy text is the usual source.
The cell holds a real date; it just has no format. Set column_formats to "date" or "datetime" for that column.
styled_headers applies bold only. There’s no fill. Use cell_styles on the header row if you want a background color.
Excel’s grid stops at 1,048,576 rows and 16,384 columns, and Jetxl raises rather than truncating. The row limit counts the header, so a frame of exactly 1,048,576 rows is one over.

It’s slower than expected

auto_width measures every row. On large exports set explicit column_widths instead. The project’s own guidance is to disable auto-width for speed.
write_sheet reads Python lists rather than Arrow buffers and benchmarks at roughly twice the time. Switch to write_sheet_arrow.
Parallelism is per sheet, so extra threads do nothing. Use min(os.cpu_count(), len(sheets)).

It runs out of memory

The bytes functions hold the entire workbook in memory before returning it, which approaches a gigabyte at a million rows. Write to a file instead, or split the export across several files.

Reporting a bug

Jetxl is experimental, and combining several formatting parameters is where bugs are most likely. If something looks wrong, try removing optional parameters one at a time to find which pair interacts badly. That reduction is also the most useful thing to put in a bug report.
Open an issue on GitHub with the Jetxl version, the DataFrame library and version, and a minimal failing example.