[PHP] Quelques lignes qui transforment un fichier excel en extract CSV !

PTS-Sexy-Girls-Billiards-Snooker-Pool-HD-Wallpapers-Free-2

 

Coucou les d'jeun's !

 

Bon j'imagine que vous avez déjà préparé vos reserves de nourriture pour demain ?!?
Entre la grève SNCF et les manifestations contre la loi el khomri ...
Il risque d'y avoir du monde dehors ^^

Pour vous divertir une fois de plus, car je suis là pour ça (entre autres)
J'ai créé un court script PHP qui vous permet d'extraire les données d'un fichier excel, qu'importe qu'il soit sur plusieurs pages ou non, et de le formater en CSV !!!

 

/*
*             Convert Excel to CSV
*                    V 1.0
*                  Dyrk.org
*          (c) Dave Hill 2016 - 2017
*/

if (! isset($argv[1]) || ! is_file($argv[1]))
        exit("[usage] ./$argv[0] myexcelfile.xlsx\n");

//       Text Dictionnary
$handle = fopen("zip://$argv[1]#xl/sharedStrings.xml", 'r');
if ($handle){
        $result = '';
        while (!feof($handle))  $result .= fread($handle, 8192);
        fclose($handle);
        $content = str_replace("\n", "", $result);
        if (preg_match_all('/\<si>(.*?)\<\/si>/s', $result, $match)){
             $dico = $match[1];
             foreach ($match[1] as $k => $v) $dico[$k] = strip_tags($v);
        }
}


if (($zip = zip_open($argv[1]))) {
        while ($zip_entry = zip_read($zip)) {
                if (! zip_entry_open($zip, $zip_entry)) continue;
                $filename = zip_entry_name($zip_entry);
                if (preg_match("/xl\/worksheets\/sheet([0-9]{0,3}).xml/",$filename,$fileId)) {
                        //     Open File
                        $filesize = intval(zip_entry_filesize($zip_entry));
                        $content = zip_entry_read($zip_entry, $filesize);
                        echo "\n\n\n\nFilename :; $filename;\n\n\n\n";
                        $rowReg     = '/\<row [A-Za-z-0-9^_.:="\' ]{0,200}>(.*?)\<\/row>/s';
                        if (preg_match_all($rowReg, $content, $data)){
                                $rows = $data[1];
                                //       Read All Data Line
                                foreach ($rows as $k => $v){
                                        $colReg = '/\<c [A-Za-z-0-9^_.:="\' ]{0,200}(\>\<v>(.*?)\<\/v>|\/\>)/s';
                                        if (preg_match_all($colReg, $v, $row)){
                                                $rowData = $row[2];
                                                //       Extract All Record from Line
                                                foreach ($rowData as $k => $v){
                                                        if (strstr($row[0][$k], 't="s"')) $v = str_replace("\n",'\n',$dico[$v]);
                                                        echo '"'.addslashes(($v=='/>')?'':$v).'";';
                                                }
                                                echo "\n";
                                        }
                                }
                        }
                }
                zip_entry_close($zip_entry);
        }
   zip_close($zip);
}

 

Je sais que beaucoup me diront les Regex, c'est vintage, l'utilisation du DOM  c'est mieux :D

 

Et  vous aurez surement raison ..
Mais j'arrive avec ces quelques lignes à faire un extract CSV d'un fichier excel de 3 Mo en 1 seconde.
Ce qui à mon sens, n'est pas trop mal ;)

 

Capture

 

Maintenant à vous d'adapter en fonction de vos besoins ;)

 

 

Pour ceux qui veulent comprendre
comment ça marche !

 

Pour les plus curieux, je tiens à vous dire que j'ai exploré seul ces sentiers ...
Aussi, je peux vous certifier, que vous aurez surement un peu de mal à comprendre au début.
Je vous invite par conséquent à créer un petit fichier excel avec peu de contenu pour faire vos tests.

 

Capture

 

Un fichier excel n'est rien d'autre qu'une archive ...
Aussi en la renommant en .zip, vous pourrez explorer un peu ses entrailles !

 

Capture

 

 

Les diverses feuilles Excel que peut contenir votre document

Capture

 

Sont stockées ici dans le dossier xl\worksheets\

 

Capture

 

 

Ce sont tous les fichiers .xml, préfixés par un "sheet"
À l'intérieur vous découvrirez un fichier xml classique, avec toutes les lignes de votre feuille "<row>"

Capture

 

Et pour chaque ligne, vous aurez les cellules de celle-ci "<c>"

Capture

 

Exemple ici pour la ligne 1 : A1, B1, C1, ...

C'est là que ça se complique un peu ( mais pas trop ;) )
Comme je le montre sur la capture d'écran ci-dessous, certaines cellules affichent un t="s"
Ce "t", c'est le type, ça signifie "type string"
En gros .. le contenu de cette cellule sera une chaîne de caractères ...
Si tel n'est pas le cas, vous pourrez considérer que le contenu de la cellule est un chiffre / nombre "entier" ou un "float" (chiffre / nombre à virgule)

 

Aussi le contenu de chaque cellule sera représenté ainsi par <v> (value) :

 

Capture

Si c'est un entier, la valeur ici sera bien 0, sauf que comme vous êtes malin et que vous voyez ' t="s" ', vous vous doutez que ce qui est attendu ici c'est une chaîne de caractère  !
Et donc non, ici 0 ne sera pas la chaîne de caractères !
ça sera juste une information pour nous dire d'aller lire l’occurrence n°0 d'un fichier contenant les chaines de caractères !

Ce fichier c'est "xl/sharedStrings.xml" !

 

Capture

Donc nous irons lire ce fichier, et récupérer l’occurrence "0"
Quand je parle d’occurrence ...  c'est que les lignes ne sont pas numérotées ...
Excel considère que ce fichier est dans l'ordre et va ligne ligne par ligne ...
Chaque chaîne de caractères sera contenu entre <si> :

Capture

 

Bref en prenant donc l’occurrence 0 (la première)
Le contenu est entre <t> (texte)

 

Capture

 

 

Aussi, pour en revenir à notre exemple ...
La cellule A1, contiendra ici le texte "Mon Texte !"

 

Eh voilà !
Nous avons fait le tour de ce dont nous avons besoin de connaitre pour comprendre mieux le script fourni au début de cet article ;)

Partagez ce contenu

3 comments

  • Bonjour,
    Votre script semble répondre complètement à ce que je veux faire, mais voilà je ne suis pas du tout programmeur, ,et je ne comprends pas comment l’utiliser.
    Je suppose qu’il faut indiquer le chemin du fichier .xls pour pouvoir l’ouvrir et aussi ou le sauvegarder le .csv

    Merci d’avance si vous pouviez m’éclairer un peu à ce sujet.
    Cordialement
    Pascal

  • Bonjour,

    Ce post est très intéressant et m’a été très utile pour travailler avec un fichier de 13Mo !

    Je voudrais savoir comment effectuer le processus inverse ? C’est-à-dire passer du fichier csv à un fichier Excel ?

    Est-il possible de créer un fichier zip/excel à partir d’un fichier csv ?

Laisser une réponse

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *