Créer un graphique Excel à la volée en PHP


Vous voulez mettre à la disposition des internautes sous forme de graphique Excel téléchargeable, des données évolutives issues d'une base de donnée en ligne, ou bien des données que le visiteur peut sélectionner à partir d'un formulaire...
Par exemple des cours de bourse avec possibilité de choix de la valeur, de la plage de durée...
Pas question de stocker sur le serveur un fichier Excel par requête (il y en a une infinité), il faut créer le graphique "à la volée", dès que le visiteur à lancé une requête.

Mais la tâche n'est pas simple, si le serveur hébergeant votre site ne dispose par de l'application Excel. Le fichier Excel muni de son graphique est en effet un objet complexe, dont la création est laborieuse.

Une solution très simple : partir d'un fichier Excel "modèle", comprenant déjà son graphique et le formattage de données souhaité, et le modifier directement par php en fonction des besoins.
Il suffit d'injecter les données chiffrées dans la feuille Excel liée au graphique.

Reste à trouver où les données se cachent et à prendre quelques précautions pour ne pas altérer le fichier.

Prenons donc un fichier Excel, inscrivons-y un tableau de chiffres quelconques (par exemple en colonnes 1 et 2) et traçons le graphique à partir de ces données.
L'examen du contenu du fichier Excel (en l'ouvrant avec notepad par exemple), ne permet pas de retrouver facilement les données chiffrées qui y sont codées :
Une succession de caractères permet d'afficher un nombre donné dans une cellule donnée. Par exemple :
Chr(3) . Chr(2) . Chr(14) . Chr(0) . Chr(2) . Chr(0) . Chr(0) . Chr(0) . Chr(15) . Chr(0) . Chr(148) . Chr(106) . Chr(159) . Chr(142) . Chr(199) . Chr(76) . Chr(64) . Chr(64)
Les deux premiers caractères chr(3) et chr(2) indiquent le code 515 (3 + 2*2^8) qui correspond à un nombre.
Les deux suivants chr(14).chr(0) codent le nombre 14 qui indique la longueur de la chaine codée qui suit
Les suivants chr(2).chr(0) puis chr(0).chr(0) indiquement les numéros de ligne (2) et colonne (0), comptés à partir de zéro. Il s'agit donc d'un nombre inscrit dans la 3ème ligne et 1ère colonne.
Les huit derniers caractères Chr(148).Chr(106).Chr(159).Chr(142).Chr(199).Chr(76).Chr(64).Chr(64) codent le nombre 32.59984 (de type double).

Rien de plus simple alors que de remplacer en php notre 32.59984 par le nombre de notre choix :
Il suffit de lire le fichier Excel comme un fichier texte par fopen + fread, et d'utiliser str_replace pour remplacer notre série de caractères par une autre qui code un autre nombre.
On peut même déplacer la cellule en changeant les numéros de colonne et ligne.

Par exemple, si $txtxl est le contenu du fichier Excel et $nouveau_nombre le nombre qu'on souhaite substituer à 32.59984 :
$arempl = Chr(3) . Chr(2) . Chr(14) . Chr(0) . Chr(2) . Chr(0) . Chr(0) . Chr(0) . Chr(15) . Chr(0) . Chr(148) . Chr(106) . Chr(159) . Chr(142) . Chr(199) . Chr(76) . Chr(64) . Chr(64);
$nouval = Chr(3) . Chr(2) . Chr(14) . Chr(0) . Chr(2) . Chr(0) . Chr(0) . Chr(0) . Chr(15) . Chr(0) . codage_double($nouveau_nombre);
$txtxl= str_replace( $arempl, $nouval,$txtxl);

$txtxl contient maintenant le code du fichier Excel modifié.
Il suffit de l'afficher par
echo $txtxl;
en prenant soin d'utiliser préalablement un header indiquant sa qualité de fichier Excel :
header("Content-Type: application/vnd.ms-excel"); //header("Content-Disposition: attachment; filename=test.xls");
header("Content-Disposition: inline; filename=test.xls");

A l'exécution du fichier php, le fichier Excel contenant les nouvelles données, et le graphique attaché, est téléchargé.

Le fichier php (grafxl.php) proposé en test ICI et au téléchargement ICI (fichier .txt à renommer en .php avant d'uploader sur un serveur) est basé sur ce principe. Il permet en outre de modifier le titre du graphique et il englobe le fichier "modèle". Il peut donc être utilisé directement pour créer des graphiques Excel simples par php.

Si votre hébergeur ne vous fournit pas php, vous pouvez même appeler le graphique-php de jacxl.free.fr depuis un simple formulaire html placé n'importe où :
<FORM METHOD='POST' ACTION='http://jacxl.free.fr/cours_xl/php/grafxl.php' TARGET='_blank'>
point n° 1   x=<INPUT TYPE='text' NAME='x0' SIZE='5'>   y=<INPUT TYPE='text' NAME='y0' SIZE='5'>
point n° 2   x=<INPUT TYPE='text' NAME='x1' SIZE='5'>   y=<INPUT TYPE='text' NAME='y1' SIZE='5'>
point n° 3   x=<INPUT TYPE='text' NAME='x2' SIZE='5'>   y=<INPUT TYPE='text' NAME='y2' SIZE='5'>
point n° 4   x=<INPUT TYPE='text' NAME='x3' SIZE='5'>   y=<INPUT TYPE='text' NAME='y3' SIZE='5'>
<INPUT TYPE='SUBMIT'>
point n° 1   x=   y=
point n° 2   x=   y=
point n° 3   x=   y=
point n° 4   x=   y=

Combiné avec un peu de javascript, ce genre de formulaire permet une certaine interactivité.

Le fichier grafxl.php permet de construire en php des graphique x-y (nuages de points) jusqu'à 200 points.
Les variables à envoyer au php (méthode POST de préférence, mais GET fonctionne pour de petites séries) sont x0, x1, x2, ...x199 pour les abscisses et y0, y1, y2, y3,... y199 pour les ordonnées. On peut également envoyer les variables titre, titre_abs et titre_ord pour définir le titre du graphique, le nom des abscisses et celui des ordonnées.