Espace membres

Bonjour Anonyme

Inscription

Email :
Mot de passe :

Mot de passe oublié ?

Nos scripts

MySpeach

MySpeach est un chat php sans base de donnée, rapide, léger et facile à prendre en main. DEMO

MyPHPUpload

MyPHPUpload est un script d'upload sécurisé écrit en PHP. DEMO

GrapAgenda

Agenda PHP et MySQL avec comptes utilisateurs et administration. DEMO

Livre PHP

mysql vers excel via php et sylk

Cours / tutoriel écrit le 17-06-2010 par sky

Par J-Pierre Dézélus Septembre 2001
Tutoriel de : www.phpinfo.net

Pourquoi le format SYLK ?

Lorsque l'on veut récupérer des données MySQL sous Excel , deux méthodes rapides s'offrent généralement à nous.
La première nécessite que le serveur Web tourne sur une plateforme Win32. Elle s'appuie sur les objets COM , pas toujours faciles à utiliser comme nous le montre l'article d'Arnaud Limbourg : Objets COM en PHP, une première approche .

La seconde, qui ne dépend pas de la plateforme, s'appuie sur le format CSV . Les fichiers générés sont de type texte, et reconnus par de nombreux tableurs et applications de bases de données.
Mais ce format ne permet que la récupération de donnée brutes, sans aucune mise en forme.

Il existe une troisième méthode, méconnue des développeurs, qui s'appuie elle sur le format SYLK (pour SYmbolic LinK ).
J'ai rencontré plusieurs fois ce format de fichier dans des applications métier, lorsqu'il était nécessaire par exemple de pouvoir récupérer sous Excel des informations issues de la base de données de l'entreprise stockée sur gros système.
Je l'ai donc étudié, et je lui ai découvert de nombreux avantages :

* les fichiers sont de type texte comme pour CSV,
* les données peuvent être mises en forme (alignement, choix et tailles des polices, styles, ...),
* c'est un format reconnu par la majorité des tableurs (dont Excel ),
* les scripts php utilisés pour générer des fichiers SYLK sont indépendants de l'OS du serveur Web.

Je me propose de vous d'écrire ici comment mettre en oeuvre ce format.

Spécifications du format SYLK
Les informations concernant ce format sont plutôt rares. Issu de Multiplan (donc Microsoft il me semble), le format SYLK a été imaginé pour permettre l'échange de données inter-applications et inter-plateformes.

Pour développer mon script je me suis appuyé sur 2 spécifications trouvées sur le net.
La 1ère sur Wotsit , un site incontournable lorsque l'on souhaite étudier un format de fichier particulier (Cf. sylk.zip ).
La seconde est ici . Il s'agit document provenant de Microsoft et disponible sur le site de Russell Schulz (Cf. sylksum.doc ).

J'ai aussi fait de nombreux tests sous Excel, en enregistrant des petits fichiers pour étudier comment les informations étaient mises en forme au format SYLK.
Attention Microsoft a largement étendu ce format dans les dernières versions d'Excel... Limitez-vous aux éléments décrits dans les 2 documents cités ci-dessus.


Structure d'un document SYLK
Un fichier SYLK se décompose globalement en 4 parties :

* l'en-tête où l'on définit : les formats de données manipulés (entiers, réels, textes), les polices (noms, tailles et attributs), et enfin le nombre de lignes et de colonnes que contiendra le document
* vient ensuite une section où l'on indique la largeur (je ne sais pas en quelle unite !?) des différentes colonnes.
* puis suivent les données utiles, où pour chaque cellule nous avons 2 lignes de texte : 1 pour le format, 1 pour la donnée.
* et pour terminer un délimiteur de fin de fichier.

Voici un exemple de fichier SYLK, avec 1 seule ligne de données (les lignes de pointillés sont juste là pour vous montrer les différentes parties du fichiers) :


ID ; PExemple

P ; PGeneral
P ; P #,##0.00
P ; P #,##0
P ; P @

P ; EArial ; M200
P ; EArial ; M200
P ; EArial ; M200
P ; FArial ; M200 ; SB

B ; Y1 ; X4
..............................................
F ; W1 1 5
F ; W2 2 20
F ; W3 3 70
F ; W4 4 20
F ; W5 256 8
..............................................
F ; SDM4 ; FG0C ; Y1 ; X1
C ; N ; K "N°"
F ; SDM4 ; FG0C ; X2
C ; N ; K "Rubrique"
F ; SDM4 ; FG0C ; X3
C ; N ; K "Astuce"
F ; SDM4 ; FG0C ; X4
C ; N ; K "Auteur"

F ; P2 ; FF0R ; Y2 ; X1
C ; N ; K38
F ; P3 ; FG0L ; X2
C ; N ; K "Chaînes"
F ; P3 ; FG0L ; X3
C ; N ; K "Accéder à chaque caractère d'une chaîne"
F ; P3 ; FG0C ; X4
C ; N ; K ""
..............................................
E



Exemple de script PHP
Pour vous montrer comment utiliser le format SYLK , je vous propose de récupérer dans un fichier le contenu de la table Astuces de phpInfo.net. Enfin une petite partie des informations !!

Voici le script PHP suffisamment commenté je l'espère :

<?php
define("FORMAT_REEL", 1); // #,##0.00
define("FORMAT_ENTIER", 2); // #,##0
define("FORMAT_TEXTE", 3); // @

$cfg_formats [FORMAT_ENTIER] = "FF0";
$cfg_formats [FORMAT_REEL] = "FF2";
$cfg_formats [FORMAT_TEXTE] = "FG0";

// ----------------------------------------------------------------------------

$cfg_hote = 'localhost';
$cfg_user = 'root';
$cfg_pass = '';
$cfg_base = 'mabase';

// ----------------------------------------------------------------------------

if (mysql_connect($cfg_hote, $cfg_user, $cfg_pass)) {
// construction de la requête
    // ------------------------------------------------------------------------
    $sql = "SELECT code, rubrique, titre, auteur ";
    $sql .= "FROM astuces ";
    $sql .= "WHERE theme=1 "; // PHP
    $sql .= "ORDER BY rubrique, titre";

// définition des différentes colonnes de données
    // ------------------------------------------------------------------------
    $champs = Array(
//     champ       en-tête     format         alignement  largeur
        Array('code', 'N°', FORMAT_ENTIER, 'R', 5),
        Array('rubrique', 'Rubrique', FORMAT_TEXTE, 'L', 20),
        Array('titre', 'Astuce', FORMAT_TEXTE, 'L', 70),
        Array('auteur', 'Auteur', FORMAT_TEXTE, 'C', 20)
    );
// ------------------------------------------------------------------------


    if ($resultat = mysql_db_query($cfg_base, $sql)) {
// en-tête HTTP
        // --------------------------------------------------------------------
        header('Content-disposition: filename=astuces.slk');
        header('Content-type: application/octetstream');
        header('Pragma: no-cache');
        header('Expires: 0');

// en-tête du fichier SYLK
        // --------------------------------------------------------------------
        echo "ID;PASTUCES-phpInfo.net\n"; // ID;Pappli
        echo "\n";
// formats
        echo "P;PGeneraln";
        echo "P;P#,##0.00n";        // P;Pformat_1 (reels)
        echo "P;P#,##0n";           // P;Pformat_2 (entiers)
        echo "P;P@n";               // P;Pformat_3 (textes)
        echo "\n";
// polices
        echo "P;EArial;M200n";
        echo "P;EArial;M200n";
        echo "P;EArial;M200n";
        echo "P;FArial;M200;SB\n";
        echo "\n";
// nb lignes * nb colonnes :  B;Yligmax;Xcolmax
        echo "B;Y" . ( mysql_num_rows($resultat) + 1 );
        echo ";X" . ( $nbcol = mysql_num_fields($resultat)) . "\n";
        echo "\n";

// récupération des infos de formatage des colonnes
        // --------------------------------------------------------------------
        for ($cpt = 0; $cpt < $nbcol; $cpt++) {
            $num_format [$cpt] = $champs [$cpt][2];
            $format [$cpt] = $cfg_formats [$num_format [$cpt]] . $champs [$cpt][3];
        }

// largeurs des colonnes
        // --------------------------------------------------------------------
        for ($cpt = 1; $cpt <= $nbcol; $cpt++) {
// F;Wcoldeb colfin largeur
            echo "F;W" . $cpt . " " . $cpt . " " . $champs [$cpt - 1][4] . "\n";
        }
        echo "F;W" . $cpt . " 256 8n"; // F;Wcoldeb colfin largeur
        echo "\n";

// en-tête des colonnes (en gras --> SDM4)
        // --------------------------------------------------------------------
        for ($cpt = 1; $cpt <= $nbcol; $cpt++) {
            echo "F;SDM4;FG0C;" . ( $cpt == 1 ? "Y1;" : "" ) . "X" . $cpt . "\n";
            echo "C;N;K" . $champs [$cpt - 1][1] . "\n";
        }
        echo "\n";

// données utiles
        // --------------------------------------------------------------------
        $ligne = 2;
        while ($enr = mysql_fetch_array($resultat)) {
// parcours des champs
            for ($cpt = 0; $cpt < $nbcol; $cpt++) {
// format
                echo "F;P" . $num_format [$cpt] . ";" . $format [$cpt];
                echo ( $cpt == 0 ? ";Y" . $ligne : "" ) . ";X" . ( $cpt + 1 ) . "\n";
// valeur
                if ($num_format [$cpt] == FORMAT_TEXTE)
                    echo "C;N;K" . str_replace(';', ';;', $enr [$cpt]) . "\n";
                else
                    echo "C;N;K" . $enr [$cpt] . "\n";
            }
            echo "\n";
            $ligne++;
        }

// fin du fichier
        // --------------------------------------------------------------------
        echo "End";
    }

    mysql_close ();
}
?>

Commentaires

zu le 25-05-2012

effectivement, le code ci-dessus comporte pas mal d'erreurs, notamment des oubli d'antislashes devant de nombreux "n" :
le premier est "P;PGeneraln" et doit être corrigé en "P;PGeneral\n"

Ensuite, à la fin, il faut écrire echo "E" à la place de echo "End".

Enfin, mysql_db_query est obsolète et doit être remplacée par mysql_query, ce qui entraîne d'autre changements.
Bon courage

xihab le 26-04-2012

ça marche pas le test

cod75 le 31-10-2010

Je ne comprends pas la fin du code
Pouvez-vous m'aider
merci

Pseudo
Email
Commentaire

Merci d'écrire le code ici :