Publipostage de données d'une appli c# vers word

Contenu du snippet

Bonjour,
le code présent ici lance un publipostage sous Word avec des données contenues dans un fichier texte.

Je poste ma solution, car après de nombreuses recherches et de nombreux tests de code trouvés sur le net, je n'était pas satisfait du résultat.

A la base, les données peuvent provenir de n'importe où. Dans mon cas, les données proviennent d'un listview d'une appli C#.
Le fichier texte qui doit être créé, doit contenir en première ligne les entêtes de colonne, qui correspondront aux noms des champs dans notre publipostage.
Toutes les données, dans mon cas, sont séparées par un point virgule.

NB : ne pas oublier d'ajouter la référence Word à votre projet

Pour mon exemple :
- j'ai créé un modèle .dot (appelé modèle.dot situé sous c:\) avec la trame d'étiquette 3*7. N'importe quelle trame de segmentation de votre page fonctionne sans souci.

Source / Exemple :


//A ne pas oublier dans le code du modèle.dot
//Cette macro dans le modèle est indispensable, car pas d'équivalent en .net (c'est ce que j'en ai déduit après de longues recherches infructueuses)
Sub propager()
    WordBasic.MailMergePropagateLabel
End Sub

//Dans votre code C#
object path = "C:\\modèle.dot"
object o = Type.Missing;
object oTrue = true;
object oFalse = false;
object field = "";
object index = 0;
object type = Word.WdFieldType.wdFieldMergeField;
object format = Word.WdOpenFormat.wdOpenFormatAuto;
object subType = Word.WdMergeSubType.wdMergeSubTypeOther;
try
{
        //On ouvre un nouveau fichier Word d'après le modèle "c:\modèle.dot"
	wrd.Documents.Add(ref path, ref o, ref o, ref o);
	for(int i = 1 ; i <= nbLigne ; i++)
        //nbLigne --> Représente dans mon code le nombre de lignes max qu'il peut y avoir dans le modèle d'étiquette
	{
		nbOccur = 0;
                //Pour chaque ligne de mon étiquette
		foreach(string champ in publi.récupField(i, nbLigne).Split(new char[]{'#'}, 5)) 
                //récupFiled me récupère tous les champs souhaités pour chaque ligne de l'étiquette (séparés par des #)
		{
			if(champ != "")
			{
								
				field = "\"" + champ.Replace(' ', '_').Replace("\'", "") + "\"";
                                //Replace nécessaire car les champs sous Word ne doivent pas avoir d'espace ni d'apostrophe
                                //ni d'autres caractères spéciaux très probablement
				if(nbOccur != 0)
				{
					wrd.Selection.TypeText(" ");
                                        //Nécessaire pour espacer les champs sur la même ligne
				}
                                //On ajoute le champ dans la première étiquette du modèle
				wrd.ActiveDocument.Fields.Add(wrd.Selection.Range, ref type, ref field, ref o);
			}
			nbOccur += 1;
		}
                //Après chaque ligne de champs, on passe à la ligne suivante dans le fichier Word
		wrd.Selection.TypeText("\r");
	}
	string file = dataExtract();
        //dataExtract me récupère le nom du fichier temporaire que je créé, il contient les données de mon listview avec en première ligne
        //les entêtes de colonne (tous les champs sont séparés par un ";")
	if(file == "error")
	{
		MessageBox.Show("Le programme ne peut pas finaliser la publication : problème de droits d'accès.", "Droits d'accès", MessageBoxButtons.OK, MessageBoxIcon.Error);
	}
	else
	{
                //On lie le fichier source à notre document Word
		wrd.ActiveDocument.MailMerge.OpenDataSource(file, ref format, ref oFalse, ref oFalse, ref oTrue, ref oFalse, ref o, ref o, ref oFalse, ref o, ref o, ref o, ref o, ref o, ref o, ref subType);
                //On appelle la macro "propager" inclue dans le fichier Word pour propager la configuration sur tous les étiquettes du fichier
		wrd.Run("propager", ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o, ref o);
		//On exécute le publipostage
                wrd.ActiveDocument.MailMerge.Execute(ref oFalse);
		wrd.Visible = true;
		wrd.Activate();
	}
}
catch(Exception ex)
{
	MessageBox.Show("Le programme a rencontré l'erreur suivante :\r\r" + ex.Message);
}

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.