A PHP, az Excel meg az utf-8

vezerkepEgy szövegfájl beolvasása és feldolgozása PHP-val valami olyasmi amit egy 8 éves gyerek 5 perc alatt összehoz. Az a szép a webfejlesztő életében amikor egy ilyen feladattal bármikor sikerülhet egy teljes napot elpiszmognia. A miértre a válasz mindig más és természetesen az operációs rendszerek ködbe vesző csakmer’ típusú történetében lapulnak. Szomorú történetem következik mások okulására.

A vidáman indult reggelemet azzal indítottam, hogy a Laksmi nevezetű, böngészőben futó, platformfüggetlen könyvelő program projektem egy apró funkcióját fogom megcsinálni mielőtt belekezdenék valami vemhesebb feladatba. A Laksmiról hamarosan írok majd bővebben, jelen pillanatban annyi a lényeg, hogy szükségünk volt egy olyan funkcióra amelyben Excel-ből tudunk adatokat importálni.

Az elképzelés egyszerű volt, mégpedig az, hogy az Excel file szóban forgó munkalapját elmentem CSV-ként, amit szépen beszipkázok PHP-val, majd pár egyszerű hibaellenőrzés után SQL utasításokká alakítok és ráeresztem az adatbázis kezelőre. Az egész ügy a fájl feltöltéssel, hibakezeléssel és SQL visszakeresésekkel együtt egy 20 perces feladatnak látszott, mivel ez lett volna a 172-ik szövegfájl feldolgozós scriptem a semmi különös fajtából.

Több meglepetés is ért. Az egyik az, hogy az Excel a CSV fájlokat nem text/csv típusúnak, hanem application/vnd.ms-excel típusúnak állítja be. A miértre a válasz valószínűleg valahol Redmond egyik agytekervényében bujkál. No, mindegy ezen még könnyen túltettem magam, azt leszámítva, hogy ha ugynazt a CSV-t linux alól küldtem rá a PHP-ra akkor text/scv-ként azonosította. Egy ideig eltartott, de végül ezt még megfejtettem.

A másik keményebb nyalóka a karakterkódolások körül lépett fel. A PHP, a fájlok, az SQl, a kapcsolat a fejlécek, és minden más egyéb réteg utf-8 kódolású a karakterkódolási problémák minimalizálása érdekében. Olyan régen dolgoztam Ablax-szal, hogy már el is felejtettem, hogy nem utf-et használ, mert ugye miért is azt használná. Ehelyett Windows-1252 karakterkódolást használ magyar nyelv esetén. Persze, hogy a másik magánzó se maradjon ki a listából a MacOS X sem az utf-at komálja, hanem valami saját kódolást.

Először persze elfelejtettem, hogy ez problematikus lesz, csak a hibakezelő kidobott egy pár hibát amiben az ékezetes betűk totális káoszban jelentek meg. Gondoltam, hogy akkor fogom és megmondom az Excelnek, hogy utf-8-ban mentsen. Sajna határozottan úgy néz ki, hogy csv-t egyáltalán nem tud utf-be menteni. Txt-re volt ilyen opció, de a neve ellenére nem utf-ben mentett. Illetve abba mentett, csak az ékezetes karaktereket mind elrontotta. Viva Ablax!

Ekkor gondoltam sebaj ott a PHP majd átkódolom vele. Ott az mb_string, az iconv, az utf_encode és társaik. Sajnos a leírások és a mostani tapasztalataim alapján nem olyan egyszerű az ügy PHP oldalról sem. A bonyodalom legfőbb oka az, hogy az utf-8 készlet magába foglalja teljes egészében a Win 1252 készletet. Illetve megfeleltethetőek a karakterek egy hibás párnak. Szóval a karakterkészlet azonosítók utf-8 nak látják a szöveget akkor is ha nem az, csak rosszul kódolják. Az átkódolási kísérleteim is kudarcba fulladtak mivel volt olyan, hogy egy soron belül az egyik stringet szépen átalakította, a másik két mezővel arrébb lévő ugyanolyan stringet (uganolyan érts byteról bytera ugyanaz) meg hibásan alakította át. Ez végképp kiverte a biztosítékomat.

Végül az hozott megoldást, hogy a sok kísérletezgetés után egy lépést tettem hátra, újra átvizsgálva a problémámat. Pár óra küzdelem után már kezdtem el is felejteni, hogy eredetileg egy csv fájlt akarok importálni aminek rosszul kezeli az ékezetes betűit. Ennek örömére fogtam az excel fájlt megnyitottam open office-ban és megcsináltam azzal a csv-t. Az open office gond nélkül mentett utf-8 kódolással, azaz probléma megoldva.

Tanulság: legközelebb tényleg 20 perc alatt meglesz 🙂

21 thoughts on “A PHP, az Excel meg az utf-8

  1. Egyszer én is csináltam ilye nCSV import-ot, szintén adódtak gondok, de a tanulság csak annyi volt, hogy az Excel export-nál figyelni kell a CSV típusára, ugyanis sok van neki. És valamelyik jó volt 🙂 (Mac-es MS Office).

    “Persze, hogy a másik magánzó se maradjon ki a listából a MacOS X sem az utf-at komálja, hanem valami saját kódolást.”

    Ezt nem teljesen értem, az OS X teljes mértékben Unicode karakterkódolásra épül.

  2. Én ugyan nem merültem el ennyire a témában, hasonló szituban 10 perc után hagytam Billy cuccát a fenébe, és Openoffice-t indítottam.
    Azért ha van rá jó megoldás az érdekelne, mert akármikor belefuthatok ebbe.

  3. Egyszer én is belefutottam a problémába, de nálunk annyival cifrább volt a dolog, hogy nekem ugye nincs Excel-em (me’ minek kéne, ha van OpenOffice), így a végfelhasználónál jelentkezett a probléma. Minek utána az istennek nem volt hajlandó UTF-et gyártani (a többi kódolásban meg elvarázsolt néhány speciális karaktert, többek között az ő-ket is), így végül feltetettem nekik egy OO-t, és azóta nincs semmi gond vele 🙂
    Próbálkoztam egy keveset a probléma megoldásával, de csak két – látszólag megvalósítható – megoldás van a kódolásra (amit találtam): XLSX használata (amihez viszont elég komplikált parsert kell összedobni), vagy natív XLS feldolgozás (ami ugyebár még összetettebb, bináris és verziónként különbözik). Letöltöttem az XLS specifikációját, kinyitom. 16000 oldal. Becsuktam és marad az OO. Vagy fizet az ügyfél sok dellát, és veszek egy kész modult PHP-hoz 🙂

  4. rrd, grof arra hívta fel a figyelmed, ami az előző postod témája volt: a helyesírás. 🙂 Ahogy most leírtad, valóban azt jelenti a mondat, hogy egy xy nevű böngésző. Mondatszerkezetileg az xy a programodnak a neve, nem az őt futtató böngészőé. De nem offolok már, mert levágod a tö… nyelvemet. 😀

  5. hell

    nekem is volt ilyen gondom, en is szívtam vele eleget sajnos mar nem emlekszem milyen modon oldottam meg, de ha jol emlekszem szinten open office volt a megoldva.
    Nem ertem miert nem lehet megadni a kodolast, mert jo, hogy az ember megoldja open officeal de a userek azok meg a csv-t sem nagyon fogjak tudni normalisan lementeni nemhogy meg open officeal bajlodjanak. Nemtudom neked akadt-e gondod vele hogy az office szereti felvaltva hasznalni a rovid es a hosszu kotojelet (-) 🙁

  6. Érdekes különben az, hogy az Excel 2000-től 2007-ig bezárólag simán megeszi a natív html táblázatot, mint application/vnd.ms-excel. Ezek után fogtam magam, és megformáztam egy sima html táblázatot, beletoltam az adatot, és megnyitottam excelben. És ez tényleg 20 perces feladat volt 🙂

  7. deejayy: Pont egy ilyet csináltam ma reggel (ártáblázat letöltése). Ám egy kis szépséghiba volt: utf8-ban jöttek volna az adatok, ám az egyiket jól jelenítette meg excel, a másikat meg rosszul. Pedig ugyanazon karakterek voltak mindkettőben. Persze az iconv(“utf-8″,”ISO-8859-2”,$this->excel) megoldotta a problémát, de azért kicsit fura…

  8. Már elnézést, de az OS X valóban unicode-ban dolgozik és nem valami saját kódolásban, szóval ne bántsuk. Ha mindenki olyan korrekten kezelné a karaktertáblákat és kódolásokat mint az Apple, akkor nem itt tartanánk. Én is rengetegszer szívok ilyesmikkel és olyankor csókoltatom Billy bá’-t 🙁

    • @Kobzee Nekem márpedig egyszer a linux alatt utf8-ban elmentett fájlaimat amikor átmásoltam mac alá akkor az szépen se szó se beszéd átkonvertálta mac-akármivé. Ettől persze meghalt minden amikor felmásoltam őket. Abban igazad van, hogy némiképpen barátibb az ablax-nál.

  9. “Pár óra küzdelem után már kezdtem el is felejteni, hogy eredetileg egy csv fájlt akarok importálni aminek rosszul kezeli az ékezetes betűit.”

    “Pár óra” > “20 perc” 😀
    Ezen a mondaton jót nevettem, már a pár óra résznél. 😀
    Talán mert jártam már én is így párszor. 😀

  10. Kedves rrd!
    Ugyan egy kis idő már eltelt a cikk keletkezése óta, de a hiba még mindig fent áll, csak én most xls file-t akarok megnyitni és hiába van megmondva a scriptnek, hogy utf-8-ban nyissa meg, utf-8-as kódolás minden file-on, minden be- és kimeneten, de ugyan úgy kérdőjelek jelennek meg…
    Jahh, viszont az xls file kódolását nem tudtam még másra átírni, mert ez a “hiper szuper modern”, “”””nagyon”””” jó ofisz 2010-ben nem található ilyen opció…

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöljük.