Soubory CSV jsou velmi rozšířeny a přesto, že momentálně nejrozšířenější kódování je Unicode, soubor CSV s diakritikou v tomto kódování dělá problém MS Office. Problém ale není úplně v MS Office, ale ve způsobu generování. Naštěstí oprava je velmi jednoduchá. Níže je také krátký popis CSV souborů a good practices.
Pro pokročilejší práci s CSV doporučuji využít knihovnu CSV od PHP League.
UTF BOM
Aby MS Office, i některý další software, poznal, že se jedná o soubor v kódování Unicode je potřeba vložit na začátek souboru BOM neboli byte order mark. Je to značka, která určuje, jak je soubor kódován. Pro UTF-8 BOM je složen ze 3, UTF-16 ze 2 a UTF-32 ze 4 bajtů. U UTF-16 a 32 BOM převážně určuje, jestli se jedná o kódování BE (big endian) nebo LE (little endian).
Protože PHP skripty jsou nejčastěji v UTF-8 kódování, zajímá nás hlavně UTF-8 BOM, který je EF BB BF (hexadecimální zápis). Jiné jazyky, např. C#, používá kódování UTF-16. Seznam všech BOM pro Unicode je na Wikipedii.
Aby se soubor dal otevřít jak v MS Office, tak v Libre Office bez problému, je potřeba na začátek souboru vložit UTF-8 BOM. Starší Office na Mac měly s tímto problém, již se problém zdá vyřešen. Soubor otestován na Windows v MS Office 2007 a 2016, na Mac v MS Office 2016 a na Ubuntu v LibreOffice 3.
$csvFile = fopen("export.csv", "w"); if ($csvFile === false) { die("Cannot create file"); } fwrite($csvFile, "\xEF\xBB\xBF");// UTF-8 boom fputcsv($csvFile, [1, "Pavel", "Kutáč", "muj@email.xxx"], ";"); fclose($csvFile);
Něco o CSV a jak je správně generovat
CSV je zkratka pro comma-separated values, neboli hodnoty oddělené čárkou. Jedná se o soubor, kde jsou jednotlivé hodnoty záznamu odděleny čárkou, nové záznamy poté vždy na novém řádku. Díky tomu se dají velmi jednoduše CSV soubory znázornit jako tabulka a MS Office i LibreOffice otevírají soubory *.csv automaticky v tabulkovém editoru.
Oddělovače jsou i jiné
Protože ale ve velké části světa se používá desetinná čárka místo tečky (viz. Wikipedia), existuje i verze CSV, kde je oddělovač středník. Pokud je potřeba do buňky vložit oddělovač, je celá buňka uzavřena do dvojitých uvozovek. Pokud buňka navíc obsahuje uvozovky, v textu jsou poté zdvojené.
// Oddělovač je čárka, do souboru uloží // 1,Strednik;,"A ""uvozovky"" taky" fputcsv($csvFile, [1, "Strednik;", "A \"uvozovky\" taky"]); // Oddělovač je středník, do souboru uloží // 1;"Strednik;";"A ""uvozovky"" taky" fputcsv($csvFile, [1, "Strednik;", "A \"uvozovky\" taky"], ";");
Záhlaví sloupců
Je dobrým zvykem, že první řádek neobsahuje data, ale záhlaví. Pokud soubor otevře člověk, podle záhlaví dokáže rozpoznat, co který sloupec obsahuje. Pokud ale soubor je dále zpracován strojově, pokročilejší knihovny dokáží využívat názvy sloupců jako indexy v poli. Poté je možné přistupovat ke sloupci pomoci jejího jména. I když se soubor vygeneruje s větším počtem sloupců, třeba i v jiném pořadí, zpracování programem pak nemusí skončit chybou.
Následuje pár dobrých rad, na co si dát pozor při generování CSV.
- Záhlaví přidat pokud možno vždy.
- V celém souboru používat jednotný oddělovač, nejlépe pouze čárku nebo středník.
- Pro strojové zpracování zvolit indexy alfanumerické. Knihovna automaticky rozpozná použitý oddělovač.
- Prázdný záznam nestačí zapsat jako prázdný řádek, musí obsahovat alespoň 1 oddělovač. Knihovny mohou prázdné řádky ignorovat.
Máte nějaké problémy ať už s Unicode kódováním nebo zpracováním CSV. Podělte se v komentářích
K tomuto článku již není možné přidávat další komentáře