| Page d'accueil |
| Télécharger |
| Où acheter |
| Devenir betatesteur |
| À propos de nous |
| Contact |
| Anciens numéros |
| Newsletter |
| Articles |
| Devenir auteur |
| Partneraires |
AutomationPiloter Office depuis une application .NET Microsoft Office est la suite bureautique la plus utilisée et la plus connue dans le monde. Son ergonomie, sa facilité d’utilisation, et ses fonctionnalités l’ont rendue célèbre voire universelle. En tant que développeur, nous sommes rapidement confrontés à la nécessité de piloter, d’intégrer, ou de générer des documents Office. Cet article explique :
A l’aube de la sortie d’Office 2007, il peut être intéressant de faire le point sur les techniques, et les technologies existantes pour manipuler les documents Office. Lorsqu’on aborde pour la première fois la plateforme de développement pour Office, l’exhaustivité des techniques est au premier abord déroutant. Pour simplifier, on distingue :
La technologie COM (Component Object Model) Pour beaucoup de développeurs .net, utiliser la technologie COM pour piloter un diaporama, ou générer un document complexe, relève de l’arrachage de cheveux et la difficulté vient probablement d’abord du manque d’information que Microsoft consent à donner sur le sujet ! Mais une fois apprivoisée, cette technologie se révèle remarquablement puissante et permet un fort contrôle sur l’application. Quelques définitions s’imposent avant de nous lancer dans notre petite application. Qu’est ce que COM ? COM est d’abord un modèle de conception que Microsoft a utilisé pour permettre l’interaction des applications entre elles. On définit dans COM des interfaces, des objets implémentant ces interfaces et constitués d’un certain nombre de propriétés et de méthodes. Prenant un contexte plus généraliste, Automation, ou OLE Automation, représente chez Microsoft à la fois la technologie COM mais aussi les outils, langages de scripts, permettant de créer et de manipuler l’application. On parle ainsi d’Automation sur la suite Office car on peut à la fois créer des macros et des add-ins en VBA et manipuler à distance l’application par l’intermédiaire de COM. Dans le cas de language managé comme dans .net, la communication avec COM est possible grâce à un intermédiaire, un wrapper, qui fait le lien entre les types du langage managé, et les types COM. C’est pourquoi lorsque vous ajoutez une référence COM sur Visual Studio, l’environnement génère ou utilise un wrapper (RCW pour Runtime Callable Wrapper). Ce wrapper est compilé dans un assembly appelé interop assembly parce qu’il assure justement cette interopérabilité. Bien que COM représente une technologie ancienne, il est fortement utilisé dans le monde des développeurs sur Windows et sera toujours utilisé pour Office 2007 et Windows Vista. Les Primary Interop Assembly Les applications Office se comportent comme des serveurs COM, exposant un certain nombre d’objets. Pour communiquer avec COM, Le CLR (Commun Langage Runtime) de .net nécessite qu’on lui fournisse un assembly d’interopérabilité dont nous venons de parler. Microsoft fournit justement ces assembly, qu’il appelle PIA pour Primary Interop Assembly. C’est à partir de cet assembly que l’on peut fournir à .NET la description des interfaces et types COM. Microsoft a fournit des PIA pour Office 2000 et Office 2003. à chaque version est associé ses propres PIA.
Avant toute chose, il faut installer sur sa machine les PIA Office. Ceux-ci sont disponibles dans l’installation personnalisée d’office par l’option (Prise en charge de la programmabilité .net), à cocher dans chacune des applications Office (Word, Excel, PowerPoint,Outlook, MSGraph). à noter que ces options ne s’affichent que si le framework .NET (1.1) est déjà installé sur votre ordinateur, soyez donc à jour ! Ces prérequis sont indispensables pour exécuter les exemples de cet article. Tableau 1. Tableau simplifié, venant de MSDN, montrant une partie des PIA d’Office (Source : Installing and Using the Office 2003 Primary Interop Assembly, http://msdn.microsoft.com/office/tool/net/default.aspx?pull=/library/en-us/dno2k3ta/html/officeprimaryinteropassembliesfaq.asp)
Pour aborder de manière sereine l’Automation Office, vous devez explorer et apprendre à naviguer avec les interfaces et objets COM exposés dans le Document Object Model de chacune des applications d’Office. Vous pouvez les consulter par le site MSDN ou directement sur l’aide Office (dans la table des matières, choisissez Référence Visual Basic) La structure même des DOM Office est complexe et liée aux standards d’évolutivité fixés par COM. Chaque modèle expose des objets, des collections d’objets (Application, Window, Shape,…), des propriétés et des méthodes. Bien que peu documentés, les modèles vous serviront de référence pour l’automatisation Office. Un premier exemple : un générateur de diapositives PowerPoint Commençons donc par ajouter une référence sur Visual Studio 2005 Microsoft PowerPoint 11.0 Object Library (menu Projet, Ajouter une référence, onglet COM). Vous constaterez que votre référence est ajoutée l’explorateur de solution. Le Listing 1 vous montre la classe PowerPoint.cs qui servira de support à notre article. Le namespace permettant de retrouver les objets COM est relativement long … Ajoutons simplement un alias : using PPT = Microsoft.Office.Interop. PowerPoint; Nous manipulerons les définitions des objets COM par l’intermédiaire de cet alias. (Par exemple, PPT.Application). Stockons aussi nos référence d’objets les plus importantes : private PPT.Application monAppli; private PPT.Presentation diaporama; Nous pouvons maintenant créer une fonction LanceApplication() pour lancer l’application. On peut tout à fait lancer PowerPoint directement : this.monAppli = new PPT.Application(); Cependant on préfèrerait plutôt vérifier si l’application est déjà lancée. Pour cela, on cherche le processus powerpnt dans la liste des processus et on l’ouvre. System.Diagnostics.Process[] proc = System.Diagnostics.Process.GetProcessesByName("powerpnt"); if (proc.GetLength(0) > 0) try { this.monAppli = (PPT.Application)System. Rutime.InteropServices.Marshal. GetActiveObject("PPT.Application"); } catch { this.monAppli = new PPT.Application(); } else this.monAppli = new PPT.Application(); monAppli est alors affecté à la référence de l’application PowerPoint. On veut aussi rendre visible l’application, car l’utilisateur doit pouvoir s’en servir… this.monAppli.Visible =Microsoft.Office.ore.MsoTriState.msoTrue; Notez que la propriété Visible fait référence à une énumération dans le namespace commun pour toutes les applications office, Microsoft.Office.Core. Notez aussi que sur le DOM, les opérateurs booléens true/false sont en général remplacées par l’énumération MsoTriState. Prenez les valeurs msoTrue et msoFalse pour les opérations booléennes. Dans notre application, on va simplement créer une nouvelle présentation de novo, à l’aide de la fonction NouvellePresentation() : this.diaporama = this.monAppli. Presentations.Add(Microsoft.Office.Core. MsoTriState.msoTrue); Créez un formulaire Windows, un bouton, et appelez ces deux fonctions. Voila, vous avez ouvert PowerPoint et créé votre document !
Dans PowerPoint, lorsque vous ajoutez une diapositive, le panneau Mise en page des Diapositives vous permet de choisir plusieurs modèles de mise en page de shapes (titre, résumé, graphe) de disposition différente. Les shapes ainsi rendues ont ceci de spéciales qu’elles ont été créées par le modèle de mise en page, et portent le nom de zones réservées. Au niveau du code, nous pouvons tout à fait choisir notre modèle de mise en page par l’intermédiaire de l’énumération PpSlideLayout. La génération d’une diapositive est relativement simple : il suffit d’appeler la méthode Add de la propriété Slides sur l’objet Presentation. Ici, nous ajouterons un modèle simple générant une diapositive avec un titre, et un résumé : this.diaporama.Slides.Add(this.diaporama.Slides.Count + 1, PpSlideLayout.ppLayoutText);
/// typezonereservee est notre zone réservée /// rechercher, slide est notre diapositive foreach (PPT.Shape s in slide.Shapes.Placeholders) if (s.PlaceholderFormat.Type == typezonereservee) s.TextFrame.TextRange.Text = texte; Notez que la collection slide. Shapes liste l’ensemble des shapes. Alors que slide.Shapes.Placeholders liste l’ensemble des shapes de type zone réservée. Notez aussi que l’index d’énumération d’un tableau sur PowerPoint commence toujours à 1 : slide.Shapes[0] n’existe donc pas et renverra une exception. Vous trouverez sur le Listing 1 les fonctions : PPT.Slide CreerDiapositive (PPT.PpSlideLayout layout) void SetTexteDiapositive (PPT.Slide slide, string texte, PPT.PpPlaceholderType typezonereservee) Si vous voulez associer un masque précis avec votre diapositive, il faut d’abord nommer le masque sur PowerPoint (en allant sur le masque, puis dans le menu contextuel de la vignette du masque en cliquant sur renommer le masque). à noter que l’on accède au masque par la propriété Designs de l’objet présentation. Dans tous les cas, n’oubliez pas que l’utilisateur peut tout à fait renommer un masque, supprimer une slide, ou fermer une présentation : il conserve le contrôle de son application Office. Il est donc essentiel de sécuriser votre environnement et de gérer les exceptions soulevées par PowerPoint.
Nous allons maintenant faire un peu plus compliqué, en pilotant directement le mode diaporama de Powerpoint et lui demander de changer de slide de manière aléatoire. Nous ajouterons un évènement qui nous informera qu’une slide a été modifiée. Le tout vous est présenté sur le Listing. Pour diffuser un diaporama (plein écran), une seule instruction suffit : this.diaporama.SlideShowSettings.Run(); Pour choisir la bonne diapositive (slideindex), il faut connaître la propriété slideindex de la diapo, c'est-à-dire son index dans la collection de diapositives (de 1 à n diapositive, l’énumération commençant à partir de 1 et non 0). this.diaporama.SlideShowWindow.View.GotoSli de(slideindex, Microsoft.Office.Core.MsoTriS tate.msoTrue); Vous remarquez que les instructions sont simples, mais le chemin pour y arriver est confus : pour diffuser un diaporama, vous utilisez directement la propriété SlideShowSettings, pour arrêter la diffusion, vous utilisez SlideShowWindow.View.Exit() , pour changer de diapositive, SlideShowWindow.View.GotoSlide(). Difficile de s’y retrouver quelque fois, alors n’hésitez pas à bien consulter les DOM sur le site MSDN ou présent directement dans l’aide d’Office (voir plus haut dans l’article). Un second exemple : un rapport généré avec Word Comme toutes les applications Office, la plupart des utilisateurs de Word ne se servent que d’un très petit nombre de fonctionnalités par rapport à la totalité existente. L’automation Word peut être très utile pour rédiger des rapports, des formulaires, etc… On écrit généralement un modèle de document que l’on enregistre (template) , contenant des signets nommés (menu insertion > signet), ou des champs. Les signets sont comme un marqueur où l’on se place pour coller un texte, alors qu’un champ permet d’encadrer la valeur à changer. Vous pourrez trouver de nombreux articles sur le Web pour automatiser Word, je ne vous en donne qu’un bref aperçu. Dans notre application, nous nous servirons de Word simplement pour ajouter un tableau, et nous illustrerons deux fonctions servant à ajouter du texte à partir de signets et de champs. Lancer l’Application Lancer Word est similaire à PowerPoint, et relativement simple. Dans notre cas, nous ajoutons un simple document (Listing 2), sans nommer explicitement le template. Sur Word, les paramètres doivent être passés par référence, et lorsqu’ils sont optionnels, on ajoute la référence d’un type inconnu sur le CLR : private object missing = Type.Missing; Word est à ce point de vue bien plus permissif que PowerPoint, la plupart des arguments des fonctions étant optionnels. Pour lancer un document Word, l’instruction a donc la forme suivante, correspondant à un document vide, sans template, et sans mise en page particulière monAppli.Documents. Add(ref missing, ref missing, ref missing, ref missing); Dans le cas où l’on veut travailler avec un document associé à un template, nous permettant de conserver ainsi une mise en page, un gabarit, des signets et des champs, on référence le nom du template, normalement conservé dans {Lecteur}Documents and Settings{Nom User}Application DataMicrosoftModèles object nom = “montemplate”; this.doc = msWord.Documents. Add(ref nom,ref missing, ref missing, ref missing); Ajouter un tableau Un tableau s’ajoute ligne par ligne puis cellules par cellules. Word stocke l’ensemble de ses tableaux dans une collection d’objet Table : object zero = 0; tabCourant = doc.Tables.Add (this.doc.Range(ref zero, ref zero), 1, 2, ref missing, ref missing); Pour ajouter un tableau, on doit renseigner à Word où on peut le placer. Word utilise pour cela l’objet Range (que l’on utilise pour pratiquement toutes les opérations de texte) , qui peut s’imaginer : comme un curseur à un endroit du document, par exemple au caractère 5 : Range(5, 5) ) ; ou comme une sélection de texte, par exemple du caractère 1 au caractère 5 : Range(1, 5). Sur le Listing 2, vous trouverez les fonctions AddTab et AddRow, qui illustrent ces propos. Travailler avec les signets et les champs En travaillant avec un template, on peut mémoriser des signets pour insérer du texte, en générant des documents. Cela nécessite dans un premier temps, de réaliser le modèle et de l’enregistrer. Une fois le document Word ouvert et associé au bon template, on peut chercher son signet et remplacer des éléments de texte. Pour cela, on accède d’abord au signet par l’objet BookMark : Range copy = doc.Bookmarks. get_Item(reflesignet).Range; Le paramètre fournit en exemple est la référence de l’identifiant du signet. Le signet va nous fournir un range, donc un marqueur, qui sera utilisé pour insérer notre texte. doc.Bookmarks.get_Item(ref lesignet) .Range .Text = "Notre texte"; Le principe est identique pour la mise à jour de champs, que l’on accède par l’objet FormFields : doc.FormFields.get_Item(ref objet).Result = c.Value;
Cet article est aussi disponible dans la version pdf a télécharger : http://mscoder.org/fr/mscoder/download.html |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|