Communication entre PHP et Excel via l'objet COM24/04/2004
Par
Stephane Eyskens (Autres articles)
J'ai assez souvent vu dans le forum PHP, des questions concernant la création de fichiers Excel. Cet article va
donc démontrer comment créer des fichiers Excel (pas des .csv) de manière dynamique à l'aide de l'objet COM.
Je remercie Jérôme pour ses corrections apportées à ce tuto.
1. Introduction
2. Création de la base de données MYSQL
2.1. Phpmyadmin
3. Génération du fichier Excel sans graphique
3.1. Explication du résultat voulu
3.2. Code PHP
4. Génération du fichier Excel avec graphique
4.1. Explication du résultat voulu
4.2. Code PHP
5. Astuces
6. Téléchargement et utilisation des scripts
Tout d'abord, je dois vous préciser que les exemples qui vont suivre ne fonctionnent que lorsque PHP est
hébergé sur une plateforme Windows que l'objet COM puisse communiquer avec Excel.
Aucune activation d'extension particulière n'est nécessaire pour travailler avec COM. Nous allons donc réaliser ce qui suit:
- Création d'une petite base de données MYSQL
- Création d'un script PHP qui va extraire ces données et générer un fichier Excel formaté.
- Création d'un script PHP qui va extraire ces données et générer un fichier Excel contenant un graphique basé sur les données
2. Création de la base de données MYSQL
Via PhpMyadmin, créez une base de donnée nommée "phpexcel" et copier/coller le code suivant afin de créer votre table.
# Base de données: `phpexcel`
#
# --------------------------------------------------------
#
# Structure de la table `appels_clients`
#
CREATE TABLE `appels_clients` (
`ID_APPEL` smallint(6) NOT NULL auto_increment,
`XID_CLIENT` smallint(6) NOT NULL default '0',
`DATE_APPEL` datetime NOT NULL default '0000-00-00 00:00:00',
`SUJET_APPEL` varchar(255) NOT NULL default '',
PRIMARY KEY (`ID_APPEL`)
) TYPE=MyISAM AUTO_INCREMENT=42 ;
#
# Contenu de la table `appels_clients`
#
INSERT INTO `appels_clients` VALUES (1, 1, '2004-04-24 12:40:25', 'Problème avec application X');
INSERT INTO `appels_clients` VALUES (2, 1, '2004-04-24 08:10:00', 'Problème avec Application Y');
INSERT INTO `appels_clients` VALUES (3, 2, '2004-04-24 07:40:45', 'Problème avec l\'application Z');
INSERT INTO `appels_clients` VALUES (4, 3, '2004-04-24 12:40:25', 'Problème avec l\'application A');
INSERT INTO `appels_clients` VALUES (5, 4, '2004-04-21 12:40:25', 'Problème avec l\'application 123');
INSERT INTO `appels_clients` VALUES (6, 5, '2004-04-24 12:00:00', '');
INSERT INTO `appels_clients` VALUES (7, 6, '2004-04-24 12:00:00', '');
INSERT INTO `appels_clients` VALUES (8, 7, '2004-04-24 12:00:00', '');
INSERT INTO `appels_clients` VALUES (9, 8, '2004-04-24 12:00:00', '');
INSERT INTO `appels_clients` VALUES (10, 9, '2004-04-24 12:00:00', '');
INSERT INTO `appels_clients` VALUES (11, 10, '2004-04-24 12:00:00', '');
INSERT INTO `appels_clients` VALUES (35, 2, '2002-04-21 12:40:25', 'Problème avec l\'application 123');
INSERT INTO `appels_clients` VALUES (34, 2, '2002-04-24 12:40:25', 'Problème avec l\'application A');
INSERT INTO `appels_clients` VALUES (33, 2, '2004-04-24 07:40:45', 'Problème avec l\'application Z');
INSERT INTO `appels_clients` VALUES (32, 1, '2004-04-24 08:10:00', 'Problème avec Application Y');
INSERT INTO `appels_clients` VALUES (31, 1, '2004-04-24 12:40:25', 'Problème avec application X');
INSERT INTO `appels_clients` VALUES (36, 2, '2002-04-26 12:00:00', '');
INSERT INTO `appels_clients` VALUES (37, 3, '2004-04-27 12:00:00', '');
INSERT INTO `appels_clients` VALUES (38, 3, '2004-04-28 12:00:00', '');
INSERT INTO `appels_clients` VALUES (39, 3, '2004-03-24 12:00:00', '');
INSERT INTO `appels_clients` VALUES (40, 4, '2004-02-10 12:00:00', '');
INSERT INTO `appels_clients` VALUES (41, 5, '2003-04-24 12:00:00', '');
# --------------------------------------------------------
#
# Structure de la table `clients`
#
CREATE TABLE `clients` (
`ID_CLIENT` smallint(6) NOT NULL auto_increment,
`NOM_CLIENT` varchar(25) NOT NULL default '',
PRIMARY KEY (`ID_CLIENT`)
) TYPE=MyISAM AUTO_INCREMENT=29 ;
#
# Contenu de la table `clients`
#
INSERT INTO `clients` VALUES (1, 'Client 1');
INSERT INTO `clients` VALUES (2, 'Client 2');
INSERT INTO `clients` VALUES (3, 'Client 3');
INSERT INTO `clients` VALUES (4, 'Client 4');
INSERT INTO `clients` VALUES (5, 'client5');
INSERT INTO `clients` VALUES (6, 'client6');
INSERT INTO `clients` VALUES (7, 'client7');
INSERT INTO `clients` VALUES (8, 'client8');
INSERT INTO `clients` VALUES (9, 'client9');
INSERT INTO `clients` VALUES (10, 'client10');
Votre base de données est maintenant prête.
3. Génération du fichier Excel sans graphique
3.1. Explication du résultat voulu
Nous allons créer un fichier Excel qui contiendra tous les appels des clients, en ayant, un client par colonne
et le total du nombre d'appels par client en bas de chaque colonne.
Comme vous vous en doutez, ne sachant pas à l'avance combien de clients ont effectué des appels, il nous faudra appliquer un algorithme pouvant déterminer à la volée, dans quelle colonne, il faudra placer les données.
Les colonnes Excel sont intitulées de la manière suivante "A" "B" "C"....."Z" "AA" "AB" "AC"..."BA" "BB"..
Si plus de 26 clients ont appelé, il faudra donc placer le client 27 dans la colonne "AA" et ainsi de suite.
Pour pouvoir réaliser cela, nous allons jouer sur les codes ASCII, il y a peut-être d'autres méthodes mais celle-ci me convient.
Voici à quoi le fichier Excel ressemblera

<?
define("FILENAME","votre_racine_web\\phpexcel.xls");
$conn=mysql_connect('votre_hôte','utilisateur','mdp') or die('Probleme lors de la connexion a la BD MYSQL');
mysql_select_db('phpexcel',$conn) or die('Problème lors de la sélection de la BD MYSQL');
$query="SELECT DATE_APPEL,NOM_CLIENT,XID_CLIENT FROM APPELS_CLIENTS INNER JOIN CLIENTS ON ";
$query.="ID_CLIENT=XID_CLIENT ORDER BY XID_CLIENT,DATE_APPEL";
$res=mysql_query($query) or die('Problème lors de la réception des enregistrements '.$query);
if(mysql_num_rows($res)>0){
if(file_exists(FILENAME)){
unlink(FILENAME);
}
$excel=new COM("Excel.application");
$excel->sheetsinnewworkbook=1;
$excel->Workbooks->Add();
$book=$excel->Workbooks(1);
$sheet=$book->Worksheets(1);
$sheet->Name="Rapport appel des clients";
$j=64;
$jj=64;
$client_prec=0;
$nombre_ligne=0;
while($row=mysql_fetch_object($res)){
if($client_prec != $row->XID_CLIENT){
$j++;
$i=3;
if($nombre_ligne>0){
$lignes[]=$nombre_ligne;
$nombre_ligne=0;
}
if($jj==64){
$cell=$sheet->Range(chr($j).'1');
}
else{
$cell=$sheet->Range(chr($jj).chr($j).'1');
}
$cell->value=$row->NOM_CLIENT;
$cell->HorizontalAlignment=-4108;
$cell->Font->ColorIndex = 41;
}
$nombre_ligne++;
if($jj==64){
$cell=$sheet->Range(chr($j).$i);
}
else{
$cell=$sheet->Range(chr($jj).chr($j).$i);
}
if(chr($j)=='Z'){
$jj++;
$j=64;
}
$cell->value=$row->DATE_APPEL;
$cell->NumberFormat="jj/mm/aaaa hh:mm:ss";
$client_prec=$row->XID_CLIENT;
$i++;
}
}
else{
die('Les tables sont vides ou pas de jointure possible');
}
$lignes[]=$nombre_ligne;
$sorted=$lignes;
sort($sorted);
$max_val=5+$sorted[count($sorted)-1];
$colonne=65;
$colonne2=64;
for($i=0;$i<count($lignes);$i++){
if($colonne2>64){
$cell=$sheet->Range(chr($colonne2).chr($colonne).$max_val);
}
else{
$cell=$sheet->Range(chr($colonne).$max_val);
}
if(chr($colonne)=='Z'){
$colonne2++;
$colonne=64;
}
$cell->value="Total: ".$lignes[$i];
$cell->HorizontalAlignment=-4108;
$cell->Font->ColorIndex=3;
$colonne++;
}
$book->saveas(FILENAME);
unset($sheet);
unset($book);
$excel->Workbooks->Close();
$excel->Quit();
unset($excel);
?>
4. Génération du fichier Excel avec graphique
4.1. Explication du résultat voulu
Nous allons créer un fichier Excel qui contiendra un graphique montrant le nombre d'appels par client. Voici à quoi le fichier Excel ressemblera

<?
define("FILENAME","D:\\webroot\\phpexcel_graphique.xls");
$conn=mysql_connect('votre_hôte','utilisateur','mdp') or die('Probleme lors de la connexion a la BD MYSQL');
mysql_select_db('phpexcel',$conn) or die('Problème lors de la sélection de la BD MYSQL');
$query="SELECT NOM_CLIENT, COUNT( * ) AS NB_APPEL FROM CLIENTS INNER JOIN ";
$query.="APPELS_CLIENTS ON ID_CLIENT = XID_CLIENT GROUP BY ID_CLIENT";
$res=mysql_query($query) or die('Problème lors de la réception des enregistrements');
if(mysql_num_rows($res)>0){
if(file_exists(FILENAME)){
unlink(FILENAME);
}
$excel=new COM("Excel.application");
$excel->sheetsinnewworkbook=1;
$excel->Workbooks->Add();
$book=$excel->Workbooks(1);
$sheet=$book->Worksheets(1);
$sheet->Name="Graphique appel des clients";
$i=1;
while($row=mysql_fetch_object($res)){
$cell=$sheet->Range('A'.$i);
$cell->value=$row->NOM_CLIENT;
$cell=$sheet->Range('B'.$i);
$cell->value=$row->NB_APPEL;
$i++;
}
}
else{
die('Les tables sont vides ou pas de jointure possible');
}
$i--;
$selection = $sheet->range("A1:B$i");
$graph = $sheet->chartobjects->add(150, 10, 300, 250);
$graphique = $graph->chart;
$graphique->type=5;
$graphique->activate;
$graphique->setsourcedata($selection);
$graphique->ApplyDataLabels->type=5;
$graphique->HasTitle=true;
$graphique->ChartTitle->Text="Rapport des appels clients";
$book->saveas(FILENAME);
unset($sheet);
unset($book);
$excel->Workbooks->Close();
$excel->Quit();
unset($excel);
?>
Etant donné que la documentation concernant les méthodes de l'objet COM combiné à l'utilisation de PHP
est assez rare, il faut se débrouiller pour pouvoir aller plus loin.
Une technique qui permet d'aller plus loin est de simplement, ouvrir Excel et créer une macro automatique,
celle-ci enregistrera toutes vos actions jusqu'à ce que vous la stoppiez.
Ensuite, il suffit d'aller voir le code qui a été généré par Excel et de l'implémenter dans PHP.
Le code PHP diffère bien sûr du code VBA, par exemple, cette ligne de VBA:
ActiveChart.ChartType = xlPie
Ne peut bien sûr pas être retranscrite telle quelle dans PHP. Il faudra un peu la modifier, comme ceci:
$graph = $sheet->chartobjects->add(les dimensions que vous voulez);
$graphique = $graph->chart;
$graphique->type=5;
Comme vous le voyez, cela diffère un peu. La constante VBA xlPie ne peut être utilisée directement dans PHP.
Vous devez donc en connaître la valeur. Pour cela, faites simplement un
Debug.Print xlPie
dans Excel.
6. Téléchargement et utilisation des scripts
- Téléchargez le fichier zip et dézippez-le sur votre machine.
- Créez une base de données MYSQL nommée phpexcel
- Exécutez le contenu du fichier phpexcel_dump.sql
- Modifiez les connexions MYSQL dans les scripts PHP et placez-y vos propres paramètres ou créez un fichier de connexion à inclure.
Ces scripts ont été testé sous Windows XP professional/MySQL 4.0.15/PHP 4.3.3
Cet article est la propriété de www.developpez.com en tant qu'hebergeur ainsi que
celle de Stephaneey en tant que redacteur, ce texte est donc protégé par le code de la
propriété intellectuelle et est soumis à la réglementation en vigueur.
www.developpez.com ou son auteur se reserve le droit d'apporter des modifications
sans préavis. Vous pouvez utiliser cet article comme bon vous semble, faire un lien depuis
votre site Web, ou le copier en spécifiant l'auteur et la provenance (www.developpez.com)
Le non respect de cette règle equivaudrait à faire une contrefaçon. La responsabilité de
www.developpez.com, de l'un de ses membres, ou de la direction ne pourra etre engagé en cas
de destruction partielle ou totale des données ou de l'architecture système ou logicielle
inhérente à l'utilisation des ses logiciels. Les logiciels decrits ici sont la propriété de
leurs auteurs respectifs.
|