← webdev
meica.ch/werkstatt/webdev/zeiterfassung-csv-export
← Webdev

Zeiterfassung: CSV export that accounting could actually open

The time-tracking tool had a CSV export. It worked. The accounting team couldn’t open it in Excel.

The problem: Excel on Windows expects UTF-16 LE with a BOM for CSV files, or UTF-8 with a BOM. The export was plain UTF-8, no BOM. Excel interpreted it as Latin-1 and the German umlauts (ä, ö, ü, ß) turned into garbage.

The fix:

// Before: plain UTF-8
const blob = new Blob([csvContent], { type: 'text/csv' });

// After: UTF-8 with BOM
const BOM = '';
const blob = new Blob([BOM + csvContent], { type: 'text/csv;charset=utf-8' });

That’s it. Two characters. The BOM () is a zero-width no-break space that Excel uses to detect UTF-8 encoding. Without it, Excel guesses. With it, Excel reads the file correctly on every Windows version I tested.

The semicolon separator also mattered — some European Excel locales use semicolons as the default CSV delimiter, not commas. Added a config option for delimiter. Default: semicolon.

Lesson: test exports with the actual software your users use, not with your own tools.