Excel 2003 et ASP.Net
|
Comment attaquer Excel avec ASP.net, les problèmes rencontrés. Un tutorial qui regroupe des informations pas souvent facile à trouver sur le net.
|
|
Vu
8431
fois
|
Introduction
Dans le cadre d’un projet j’avais besoin de pouvoir attaquer Excel depuis un projet web ASP.net 1.1 ; rechercher une valeur par nom de cellule, exécuter des macros et sauvegarder. Dans un second temps j’avais aussi besoin de générer du XML via du mapping, point qu’on verra dans un prochain article.
Il existe des outils pour attaquer Office portant le nom de Visual Studio Tools for Office (VSTO) mais n’ayant pas cela sous la main j’ai utilisé l’ancienne méthode à savoir les COM (Librairie Excel 11.0).
Le problème de ces objets c’est qu’il est très compliqué de trouver de l’aide dessus et surtout répondant à certaines demandes bien précises. Les exemples sont très succins et ne marchent plus dès qu’on sort de la simple utilisation. Pour cela que je vais essayer de regrouper dans un même tutorial les différentes commandes dont j’ai eu besoin et expliquer les problèmes rencontrés.
Pré requis
- Récupérez les Microsoft Office XP Primary Interop Assemblies à l’adresse suivantes :
http://www.microsoft.com/downloads/details.aspx?familyid=C41BD61E-3060-4F71-A6B4-01FEBA508E52&displaylang=en
Une fois récupéré, installez dans un répertoire et lancer le batch register.bat qui va inscrire les DLL dans le GAC. Les DLL serviront de référence dans le projet Web.
- Donnez les droits à l’utilisateur ASP.Net via dcomcnfg.
Sous windows (XP) faites démarrer/exécuter puis dcomcnfg.exe. La fenêtre suivante apparaitra.

Déroulez l’arborescence comme sur l’image et cherchez Excel. Il porte généralement le nom “Application Microsoft Excel ” Faites propriétés dessus pour faire apparaître la fenêtre ci-dessous après avoir sélectionné l’onglet Sécurité :

Modifier « Autorisation d’exécution et d’activation » et « autorisations d’accès » en donnant les droits nécessaires à l’utilisateur ASPNET de la machine locale.
ASP.Net et Excel 2003
Première chose à faire est de référencer la DLL Microsoft.Office.Interop.Excel puis d’utiliser cette référence dans le code.
using Microsoft.Office.Interop.Excel;
|
Nous allons voir maintenant les différentes étapes pour ouvrir un fichier excel, modifier les données, exécuter une macro et sauvegarder et enfin fermer les objets proprement.
_xlApp = new ApplicationClass(); _xlApp.Visible = false; //cache l’application _xlApp.DisplayAlerts=true; //n’affiche pas les alertes |
Vous verrez souvent cela dans les pages qui suivent, c’est en fait une sorte de valeur null utilisé par les fonctions des objets COM. Missing.Value provient de System.Reflection.
Workbook _xlbook = _xlApp.Workbooks.Open([Nom du Fichier],Missing.Value,Missing.Value,Missing.Value, Missing.Value,Missing.Value,Missing.Value,Missing.Value, Missing.Value,Missing.Value,Missing.Value,Missing.Value, Missing.Value,Missing.Value,Missing.Value); |
Pour les paramètres je vous les laisse découvrir via l’IntelliSense mais le 1er paramètre est le nom du fichier, le 3ème permet de définir la lecture seule, et qu’on peut aussi définir entre autre le mot de passe, le format d’ouverture du fichier etc.
- récupérer une Feuille Excel (Worksheet)
Worksheet _xlSheet =_xlBook.Sheets.get_Item([NomDeLaFeuille]); |
Par défaut les feuilles se nomment Feuil1, Feuil2 et Feuil3 lors de la création d’un nouveau classeur.
Range rng = wc.get_Range(CelluleDebut,CelluleFin);
return rng.Text.ToString(); |
CelluleDebut et CelluleFin peuvent pointer sur la même cellule afin de récupérer sa valeur
- Modifier la valeur d’une cellule
Range rng = wc.get_Range(CelluleDebut,CelluleFin);
rng.Value2 = “TOTO”; |
On utilise la propriété Value2 car la propriété Text est en lecture seule.
Si une cellule contient une formule on peut l’exécuter en faisant rng.Calculate()
_xlBook.Activate();
_xlSheet.Activate();
_xlSheet.Select(Missing.Value);
object ret ==_xlSheet.Application.Run([NomMacro], Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value); |
Les 30 Missing.Value sont les 30 paramètres possibles pour la macro au cas où votre macro aurait des paramètres. Par conséquent ne fait pas de macro ayant plus de 30 paramètres J
La macro peut être une fonction retournant une valeur dans ce cas la, l’objet ret sera l’objet retourné. Je n’ai pas essayé de retourner un type autre qu’Int ou String donc je ne sais pas comment il se comporte avec des objets complexes.
J’ai rencontré des problèmes quand j’ai voulu ouvrir plusieurs fichiers Excel comportant des macros. A l’exécution le comportement ne fonctionnait pas tout à fait. C’est pourquoi j’ai rajouté les 2 lignes Activate et la ligne Select avant d’exécuter la macro. Ces lignes ont permis de résoudre mes problèmes.
3 méthodes :
Enregistre le fichier ouvert.
_xlBook.SaveAs([NomDuFichier],Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,XlSaveAsAccessMode.xlExclusive,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value);
|
Enregistrement plus complet avec plein de paramètres (voir IntelliSense)
_xlBook.SaveCopyAs([NomDunFichier]); |
Enregistrer une copie du fichier
J’ai eu des problèmes avec les sauvegardes. En fait quand je sauvegardais avec la 2ème méthode j’avais une erreur de Lecture Seule, avec la 1ère méthode il m’enregistrait dans “C:\My Documents”.
Pour résoudre le problème j’ai du donner les droits d’écriture et de lecture sur le répertoire ou sont les fichiers traités pour l’utilisateur ASPNET.
- Quitter l’application proprement
Sur internet on trouve beaucoup de questions concernant des problèmes sur les processus Excel restant actifs, on trouve souvent le même bout de code avec certaines variantes. Donc je mets ici le regroupement des différents codes que j’ai vu
_xlBook.Close ([SaveChanges],_xlBook.FullName,Missing.Value);
_xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(_xlApp);
Process[] prc = Process.GetProcessesByName("EXCEL");
for (int i = 0; i < prc.Length; i++)
if (((Process)prc[i]).StartTime >= _dteApp.AddSeconds(((double)-10)) ||((Process)prc[i]).StartTime>=_dteApp.AddSeconds(((double)10))) {
((Process)prc[i]).Kill(); }
GC.Collect(); |
La première ligne permet de fermer le fichier en précisant si on veut sauvegarder les changements, ensuite on ferme Excel puis on libère l’objet COM via une fonction spéciale. Puis on s’assure que le processus Excel créé est bien détruit via une magouille. Avant de créer une nouvelle instance d’excel (voir Lancement d’Excel) on stocke la date courante (_dteApp) Ensuite on regarde dans les processus d’Excel, ceux qui s’approchent de cette date à +ou- 10 puis on kill le processus.
Librairie personnelle
Afin de me faciliter le développement, j’ai fais une petite librairie permettant d’exécuter ces tâches plus facilement sans redondance.
Voici son utilisation via le un scénario utilisant les fonctions précédemment citées.
ExcelHelper.Excel ex = new ExcelHelper.Excel(false,false);
ex.Open(FileName);
ex["testMB.xls"].SetValue("Formulaire","CEL01","TOTO");
ex["testMB.xls"].ExecuteMacro("Formulaire","Controle_QuandClic");
ex["testMB.xls"].Save();
ex.Quit(false); |
La suite ?
Ce tutorial sera probablement suivi d’un tutorial sur l’utilisation de XML et des mappings sur Excel et si possible d’une comparaison avec les possibilités de VSTO. D’ailleurs si quelqu’un a un lien pour télécharger VSTO version 2003 je suis preneur.
|