HTML5 / CSS 2.x/3 / PHP / MySQL ...

Publipostage d'un document Word

Exporter un document Word au format XML

Word est un traitement de texte disponible dans l'environnement Windows et fait partie de la suite bureautique MS-Office. C'est l'outil le plus utilisé en environnement professionnel.

Une des fonctionnalités de Word est le publi-postage. Pour ce faire, on part d'un courrier type et on définit des champs de fusion, exemple:

exemple de préparation d'un publi-postage

Dans l'image ci-dessus, on a défini les champs de fusion NOM, Prenom, etc... Ces champs seront remplacés par leur valeur au moment de fusionner le document avec les données.

La technique de fusion de documents nécessite quelques connaissances et une pratique régulière.

Pour le cas qui nous intéresse, nous partons d'un document Word dont le fichier est monCourrier.doc. Les champs de fusion sont déjà définis dans le document.

Pour que notre manipulation fonctionne, il faut sauvegarder une copie de ce fichier au format XML:

Sur votre serveur Web, créez un répertoire documents et collez ce fichier monCourrier.xml. C'est ce fichier que notre script va traiter pour le publi-postage.

Le script de publi-postage

<?php
$name = 'monCourrier.xml'; // nom du fichier à ouvrir
$myFile = file_get_contents('documents/'.$name);
 
$searchReplace = array(
    '«civilité»' => 'Mr',
    '«NOM»' => 'ALEXANDRIN',
    '«Prenom»' => 'Albert',
    '«Ad1»' => '98 rue Des Poêtes',
    '«cp»' => '92260',
    '«Ad2»' => null,
    '«ville»' => 'LA CELLE SAINT CLOUD',
    '«tel»' => '0143556677'
    );
 
$search  = array_keys($searchReplace);
$replace = array_values($searchReplace);
 
// envoi d'un en-tête php qui indique au navigateur web que le contenu qui arrive 
// est de type binaire et à exploiter par Word
header('Content-Type: application/msword; name="'.$name.'"');
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="'.$name.'"');
 
// on génère le flux de données à la volée, aucun stockage sur disque
echo str_replace($search, $replace, $myFile);

Le script de publi-postage a été volontairement simplifié. Son efficacité réside dans quelques astuces fort aisées à comprendre.

Le script ouvre le contenu de monCourrier.xml et le charge dans la variable $myFile

Ensuite, on a défini un tableau $searchReplace qui est un tableau associatif clé-valeurs, à gauche les clés, à droite les valeurs qui leur sont affectées. Pour un publi-postage en production, on prendra les données issues d'une base de données. Pour notre exemple, nous avons inséré des données littérales, exemple '«NOM»' => 'ALEXANDRIN',

A partir du contenu du tableau $searchReplace on génère deux tableaux $search et $replace qui contiennent respectivement les clés d'une part, les valeurs qui leur sont affectées d'autre part. Cette manière de faire nous garantit que chaque tableau $search et $replace contiendra strictement le même nombre de valeurs et que chaque paire valleur est dans l'ordre attendu. Cette manipulation est nécessaire, car la fonction str_replace n'accepte pas les tableaux associatifs.

On a ensuite trois lignes exécutant la fonction header. Ces lignes sont destinées au navigateur qui interprétera le contenu qui arrive non pas comme une page web standard, mais comme flux binaire à traiter au travers d'une application:

exemple de sortie du fichier XML

Coté navigateur, celà se traduit par l'apparition d'une fenêtre en pop-up (image ci-dessus). L'utilisateur a deux choix:

Si on accepte d'ouvrir le fichier, Word s'ouvre et on peut visualiser le contenu de notre publi-postage:

le résultat final sous Word

Les données ont parfaitement été insérées dans notre document Word.

Conclusion

Ce script est facilement modifiable pour récupérer les données d'un client provenant d'une base de données ou d'un formulaire HTML.

Le document WORD initial peut être modifié, tant dans la forme que le fond, sous réserve cependant de conserver toujours les mêmes noms pour les champs de fusion. Il ne sera pas nécessaire de réécrire le script si on modifie le texte du document.

Cette technique est également exploitable pour les documents de type Excell. Dans ce cas, il faut adapter la partie de code qui exploite header:

header('Content-Type: application/excel; name="'.$name.'"');
header('Content-Transfer-Encoding: binary');
header('Content-Disposition: attachment; filename="'.$name.'"');

Le Content-Type: pour les fichiers Excell sera application/excel.

Tous les articles sur ce thème