Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
3075 connectés 

  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  [C#] Créer un fichier Excel

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C#] Créer un fichier Excel

n°1355781
Arjuna
Aircraft Ident.: F-MBSD
Posté le 28-04-2006 à 10:35:22  profilanswer
 

Salut,
 
J'arrive pas à trouver un moyen pour créer un document Excel à partir d'une application écrite en C#.
 
J'ai toujours la solution du csv, ou du fichier html renommé en xls, mais je préfèrerais faire un truc simplement.
 
Sauf que j'ai plusieurs soucis :
- Je ne trouve de la doc que pour faire de l'automation avec Office 10 ou 11 (il y a des offices 97 et 2000 -Office 7 & 8- encore là où l'appli va être déloyée)
- Moi j'ai la 2003 (11), sauf qu'il me manque les "PIA" d'Excel. Et impossible de trouver où les télécharger (y'a un lien dans la MSDN, mais ça tombe sur une liste de dwl qui n'ont rien à voir)
 
Vous avez une idée ?
Reste la solution de déployer la solution avec un VBS, qui récupère les données d'un fichier XML, et qui bidouille dans Excel comme un grand -ça y'a pas de problème avec WSH- mais ça me lourde les bidouillages, après je comprends plus rien à ce que j'ai fait :o

mood
Publicité
Posté le 28-04-2006 à 10:35:22  profilanswer
 

n°1355783
the big be​n
Posté le 28-04-2006 à 10:36:42  profilanswer
 

Tu est en .NET? Sinon j'ai trouve un composant appele CarolsAg qui est pas mal du tout!

n°1355800
Arjuna
Aircraft Ident.: F-MBSD
Posté le 28-04-2006 à 10:48:11  profilanswer
 

Yes, je suis en .NET

n°1355846
Arjuna
Aircraft Ident.: F-MBSD
Posté le 28-04-2006 à 11:52:27  profilanswer
 

Je trouve rien sur le net à propos de CarolsAg
 
La solution du VBS :

Code :
  1. Option Explicit
  2. Sub test()
  3.     Dim xls
  4.     Dim wkb
  5.     Dim sht
  6.    
  7.     Set xls = CreateObject("Excel.Application" )
  8.     Set wkb = xls.Workbooks.Add()
  9.     Set sht = wkb.Sheets.Add()
  10.    
  11.     sht.Cells(1, 1).Value = "test"
  12.     sht.Cells(1, 2).Value = "1"
  13.     sht.Cells(1, 3).Value = "2"
  14.     sht.Cells(1, 4).Value = "=R1C2+R1C3"
  15.    
  16.     xls.Visible = True
  17. End Sub
  18. Call test()


 
Pkoi on peut pas faire simplement aussi en C# ? :cry:
Je sens que je vais m'amuser encore... Pis à débuger, ça va encore être la misère tiens...

n°1355869
Arjuna
Aircraft Ident.: F-MBSD
Posté le 28-04-2006 à 12:29:23  profilanswer
 

Bon ben...
 

Code :
  1. private void button2_Click(object sender, EventArgs e)
  2.         {
  3.             Object foo = null;
  4.             IWshRuntimeLibrary.WshShellClass shell = new IWshRuntimeLibrary.WshShellClass();
  5.             shell.Run(@"c:\excel.vbs", ref foo, ref foo);
  6.         }


 
Avec le fichier VBS qui recherche les donnés dans un fichier XML qui va bien... Mon dieu que c'est crade :o Mais au moins ça marchera quelque soit la version d'Excel...

n°1355883
moi23372
Posté le 28-04-2006 à 12:55:54  profilanswer
 

pour Carlos AG il s'agit de produire des fichiers EXCEL au format XML. Ces fichiers ne sont lisibles qu'avec EXCEL 2003 puisque ce format est apparu avec Microsoft Office 2003.
L'avantage d'une telle solution de reporting est qu'il ne fait pas avoir microsoft Excel sur la machine pour produire les XML compréhensible par EXCEL.  
CarlosAg à produit une lib permettant de générer facilement un fichier au format XML.  
 
plus d'infos ici sur ce format:
http://www.labo-dotnet.com/Article [...] /1547.aspx

n°1355931
the big be​n
Posté le 28-04-2006 à 13:39:36  profilanswer
 

on peut pas dire que tu ai cherché beaucoup alors pcq le premier lien sur google c'est celui la!  
http://www.carlosag.net/Tools/Exce [...] fault.aspx

n°1355936
the big be​n
Posté le 28-04-2006 à 13:44:29  profilanswer
 

en fait ton fichier peut avoir l'extention xls avec ca aussi mais il sera effectivement en xml et donc lisible sous Excel 2003

n°1356022
Xas
Freshershist
Posté le 28-04-2006 à 15:14:30  profilanswer
 

Hmmm, Excel sous .NET ça pose pas de problème, si ?
 

Code :
  1. ' J'ouvre
  2. m_oExcel = New Excel.Application
  3. ' Je mets une valeur
  4. mySheet.Range(maCellule).Value = maValeure
  5. ' Je récupère une valeur
  6. Dim objResult As Object = maFeuille.Range(maCellule).Value


 
Ca reste l'appel aux objets classiques en C.
Excel.Application, puis le WorkBook, puis les Worksheets, ...


---------------
H. - 48h en fiat et j'ai déjà perdu la maitrise de mon argent
n°1356029
moi23372
Posté le 28-04-2006 à 15:29:56  profilanswer
 

le problème avec ole automation c'est que si ça plante, c'est un plantage massif... alors qu'avec la lib, c'est plus performant et ça ne plante pas puisque c'est que de la construction d'xml

mood
Publicité
Posté le 28-04-2006 à 15:29:56  profilanswer
 

n°1356040
the big be​n
Posté le 28-04-2006 à 15:37:55  profilanswer
 

de plus l'ole est souvent fort lent...

n°1356047
Arjuna
Aircraft Ident.: F-MBSD
Posté le 28-04-2006 à 15:42:35  profilanswer
 

moi23372 a écrit :

pour Carlos AG il s'agit de produire des fichiers EXCEL au format XML. Ces fichiers ne sont lisibles qu'avec EXCEL 2003 puisque ce format est apparu avec Microsoft Office 2003.
L'avantage d'une telle solution de reporting est qu'il ne fait pas avoir microsoft Excel sur la machine pour produire les XML compréhensible par EXCEL.  
CarlosAg à produit une lib permettant de générer facilement un fichier au format XML.  
 
plus d'infos ici sur ce format:
http://www.labo-dotnet.com/Article [...] /1547.aspx


ouais, ok, donc ça m'intéresse pas ;)
 
je sais écrire ces fichiers à la main, donc passer par un objet ne me sert à rien. et surtout, faut que Excel 97 puisse les relire... :/

n°1356049
Arjuna
Aircraft Ident.: F-MBSD
Posté le 28-04-2006 à 15:44:35  profilanswer
 

Xas a écrit :

Hmmm, Excel sous .NET ça pose pas de problème, si ?
 

Code :
  1. ' J'ouvre
  2. m_oExcel = New Excel.Application
  3. ' Je mets une valeur
  4. mySheet.Range(maCellule).Value = maValeure
  5. ' Je récupère une valeur
  6. Dim objResult As Object = maFeuille.Range(maCellule).Value


 
Ca reste l'appel aux objets classiques en C.
Excel.Application, puis le WorkBook, puis les Worksheets, ...


ouais, sauf que "Excel.Application", pas moyen de trouver la référence à mettre. J'ai essayé les libs .NET (Office.Tools) et les objets COM (Excel 5.0 et Excel 11.0 -me demandez pas pkoi il y a des bouts de Excel 5.0 sur mon 2003 Server :o-)
Du coup, je ne peux rien faire. En plus, il me gueule dessus parcequ'il manque une référence "Microsoft.Office.Interop", sauf que je n'ai pas cette référence... Don't know why.
 
Et sinon, ça revient au même que mon VBS, sauf qu'avec "CreateObject", l'intérêt, c'est que je ne suis pas les poings liés avec la version référencée dans mon code : il prends la version de l'objet qui se trouve sur le PC de l'utilisateur. Ca m'évite de déployer 25 versions différentes de mon EXE (et d'installer 25 versions différentes d'Office sur mon PC...)


Message édité par Arjuna le 28-04-2006 à 15:47:03
n°1356052
Arjuna
Aircraft Ident.: F-MBSD
Posté le 28-04-2006 à 15:45:30  profilanswer
 

moi23372 a écrit :

le problème avec ole automation c'est que si ça plante, c'est un plantage massif... alors qu'avec la lib, c'est plus performant et ça ne plante pas puisque c'est que de la construction d'xml


Oui, mais relis mon premier post : XML = interdit. Je suis le seul dans toute la boîte à avoir Office 2003.
Sinon, j'aurais même pas posé la question : j'aurai utilisé le format XML d'entrée de jeu, c'est un vrai bonheur à utiliser, d'autant qu'on peut y inclure des macro autrement que sous forme de *.mso liés au fichier (on fout direct le code de la macro dans une balise spécifique et zou)


Message édité par Arjuna le 28-04-2006 à 15:48:19
n°1356075
Xas
Freshershist
Posté le 28-04-2006 à 16:03:36  profilanswer
 

C:\WINDOWS\assembly\GAC\Microsoft.Office.Interop.Excel\11.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Excel.dll
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\office.dll

 
J'ai que ça dans mes références et ça fonctionne...


---------------
H. - 48h en fiat et j'ai déjà perdu la maitrise de mon argent
n°1356077
moi23372
Posté le 28-04-2006 à 16:04:00  profilanswer
 

ah excuse moi... j'ai lu en diagonale. Dans ce cas la il te reste ole automation. Pas trop le choix...  
 
Sinon une autre solution consisterait tout de même à créer le fichier EXCEL en xml et de reconvertir ensuite avec XSL-FO vers un fichier Excel Classique... Mais sincèrement je crois pas que ça changerait bcp que de faire directement tout en ole automation.

n°1356082
Xas
Freshershist
Posté le 28-04-2006 à 16:05:10  profilanswer
 

moi23372 a écrit :

le problème avec ole automation c'est que si ça plante, c'est un plantage massif... alors qu'avec la lib, c'est plus performant et ça ne plante pas puisque c'est que de la construction d'xml


Suffit de faire une petite classe qui gère les E/S avec Excel.
Un petit try/catch quand on accède aux données et quand ça plante, ben on est toujours sain et sauf coté référence.

Message cité 1 fois
Message édité par Xas le 28-04-2006 à 16:05:48

---------------
H. - 48h en fiat et j'ai déjà perdu la maitrise de mon argent
n°1356086
Arjuna
Aircraft Ident.: F-MBSD
Posté le 28-04-2006 à 16:06:28  profilanswer
 

Xas a écrit :

C:\WINDOWS\assembly\GAC\Microsoft.Office.Interop.Excel\11.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Excel.dll
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\office.dll

 
J'ai que ça dans mes références et ça fonctionne...


A priori, il me manque le premier. Je ne sais pas pkoi. Quand je fais "add reference", il n'est pas présent.

n°1356092
Arjuna
Aircraft Ident.: F-MBSD
Posté le 28-04-2006 à 16:10:42  profilanswer
 

moi23372 a écrit :

ah excuse moi... j'ai lu en diagonale. Dans ce cas la il te reste ole automation. Pas trop le choix...  
 
Sinon une autre solution consisterait tout de même à créer le fichier EXCEL en xml et de reconvertir ensuite avec XSL-FO vers un fichier Excel Classique... Mais sincèrement je crois pas que ça changerait bcp que de faire directement tout en ole automation.


Ca va surtout être la grosse prise de tête ;)
 
Avec OLE, ça devrait aller.
Je récupère mon DS. J'en fait un "WriteXml", je passe en paramètre à mon VBS le fichier généré.
Je le parse avec MSXML dans le VBS, et je construis dynamiquement mon document Excel via une instance d'Excel ouverte.
Quand j'ai fini, j'affiche la fenêtre et je rends la main au programme.
Comme ça le gus choisi d'enregistrer ou non le fichier, et l'appli peut continuer à tourner pendant ce temps. C'est à la limite mieux qu'avec une lib, parceque Excel est directement ouvert avec le fichier comme ça ;)
 
Couche de décodage du flux XML à part, j'ai testé et ça marche. Je termine le reste de l'appli, et après je passe à ça. Je vais plus être emmerdé par l'absence d'IDE pour VBS (pratique pour retrouver le nom des méthodes d'un objet créé avec "CreateObject" :D) qu'autrechose, pour le reste ça va marcher comme une bête acro Excel (d'ailleurs, je crois que je vais commencer par le faire sous forme de Macro avant d'en faire un VBS).

n°1356095
Arjuna
Aircraft Ident.: F-MBSD
Posté le 28-04-2006 à 16:12:02  profilanswer
 

Xas a écrit :

Suffit de faire une petite classe qui gère les E/S avec Excel.
Un petit try/catch quand on accède aux données et quand ça plante, ben on est toujours sain et sauf coté référence.


Borf, un bon gros "On Error Resume Next" dans mon VBS et c'est bon :D
En plus, l'intérêt c'est que le VBS sera appelé par un Shell.Run() donc même s'il plante, ça foutra pas en l'air mon appli, qui tourne dans un processus totalement séparé :)


Message édité par Arjuna le 28-04-2006 à 16:12:19
n°1363134
Arjuna
Aircraft Ident.: F-MBSD
Posté le 10-05-2006 à 11:35:33  profilanswer
 

Bon, pour ceux que ça intéresse, je suis donc finalement arrivé à la phase de développement où je pouvais plus faire sans cette fonctionnalité :D
 
Du coup j'ai torché ça en 1 heure, ça marche pour moi. C'est à complèter, mais ça pourrais aider à démarrer une personne bloquée comme moi.
 

Code :
  1. Option Explicit
  2. ' Titre : DS2XLS
  3. ' Auteur : MagicBuzz
  4. ' Version : 1.0
  5. ' Date : 10-05-2006
  6. '
  7. ' Script VBS qui génère un document Excel à partir d'un extract "ToXml()" d'un Objet DataSet de .NET
  8. ' Ce script est censé fonctionner sur n'importe quelle version de Windows, et n'importe quelle version d'Excel
  9. ' Bon, rien n'est garanti non plus hein...
  10. ' Constantes
  11. ' Ces GUID génériques ont l'avantage d'être idetiques pour toutes les versions
  12. ' Il faut alors faire confiance à Microsoft pour ne pas changer la structure des objets d'une version à l'autre
  13. Const EXCEL_GUID = "Excel.Application"
  14. Const MSXML_GUID = "MSXML.DOMDocument"
  15. ' Méthodes
  16. Sub Main()
  17.     ' Excel objects
  18.     Dim xls
  19.     Dim wkb
  20.     Dim sht
  21.    
  22.     ' DOM objects
  23.     Dim dom
  24.     Dim declaration
  25.     Dim table
  26.     Dim colonne
  27.     Dim ligne
  28.    
  29.     ' Common variables
  30.     Dim tabName
  31.     Dim arrColonnes()
  32.    
  33.     ' Compteurs
  34.     Dim i
  35.     Dim j
  36.    
  37.     ' Création d'une instance d'Excel
  38.     Set xls = CreateObject(EXCEL_GUID)
  39.     ' On ne l'affiche pas
  40.     'xls.Visible = True
  41.    
  42.     ' Ajout d'un espace de travail (par défaut, Excel s'ouvre vide)
  43.     Set wkb = xls.Workbooks.Add()
  44.    
  45.     ' L'espace de travail contient de base 3 sheets. On en vire deux et on renomme la dernière
  46.     ' En effet, un espace de travail doit au moins toujours contenir une feuille...
  47.     For i = wkb.WorkSheets.Count To 2 Step -1
  48.         wkb.WorkSheets(i).Delete
  49.     Next
  50.     wkb.WorkSheets(1).Name = "tmpSheet"
  51.    
  52.     ' Ouverture du document XML contenant les données du dataset à sauvegarder
  53.     Set dom = CreateObject(MSXML_GUID)
  54.     dom.Load "export.xml"
  55.    
  56.     ' Recherche du tag de description des DataTables
  57.     Set declaration = dom.DocumentElement.SelectNodes("xs:schema/xs:element/xs:complexType/xs:choice/xs:element" )
  58.    
  59.     ' C'est parti !
  60.     For Each table In declaration
  61.         tabName = GetAttributeByName(table, "name" )
  62.         Set sht = wkb.WorkSheets.Add()
  63.         sht.Name = tabName
  64.         ReDim arrColonnes(1)
  65.         i = 0
  66.         For Each colonne In table.SelectNodes("xs:complexType/xs:sequence/xs:element" )
  67.             i = i + 1
  68.             ReDim Preserve arrColonnes(i)
  69.             ' En-tête
  70.             arrColonnes(i) = GetAttributeByName(colonne, "name" )
  71.             sht.Cells(1, i).Value = GetAttributeByName(colonne, "name" )
  72.             sht.Cells(1, i).Interior.ColorIndex = 36
  73.             sht.Cells(1, i).Font.Bold = True
  74.             ' Formattage du type de la colonne
  75.             Select Case GetAttributeByName(colonne, "type" )
  76.                 Case "xs:string"
  77.                     sht.Columns(i).NumberFormat = "@"
  78.                 Case "xs:decimal"
  79.                     sht.Columns(i).NumberFormat = "0.00"
  80.                 Case Else
  81.                     ' Ouais, ben désolé, moi je me sert que de string et decimal...
  82.                     sht.Columns(i).Interior.ColorIndex = 3
  83.                     MsgBox("Type inconnu : " & GetAttributeByName(colonne, "type" ))
  84.             End Select
  85.         Next
  86.        
  87.         ' Maintenant, on parcours l'ensemble des éléments correspondant au datatable en cours de lecture
  88.         j = 1
  89.         For Each ligne In dom.DocumentElement.SelectNodes(tabName)
  90.             j = j + 1
  91.             For i = 1 To UBound(arrColonnes)
  92.                 ' On recopie bêtement le contenu du tag portant le nom de la colonne désirée
  93.                 sht.Cells(j, i).Value = ligne.SelectSingleNode(arrColonnes(i)).Text
  94.             Next
  95.         Next
  96.        
  97.         ' Ca c'est pour faire joli (si faire se peut)
  98.         sht.Columns.EntireColumn.AutoFit
  99.     Next
  100.    
  101.     ' Vous vous rappelez de la sheet renommée ? Ben on la zigouille maintenant
  102.     wkb.WorkSheets("tmpSheet" ).Delete
  103.    
  104.     ' On indique qu'on ferme l'espace de travail en enregistrant le document (une popup d'enregistrement apparaît)
  105.     wkb.Close(true)
  106.    
  107.     ' On quitte Excel
  108.     xls.Quit
  109. End Sub
  110. Function GetAttributeByName(node, attributeName)
  111.     ' Impossible d'utiliser les collections nommées en VBS. Du coup on fait avec les moyens du bords...
  112.     Dim tmpRet
  113.     Dim att
  114.     tmpRet = ""
  115.     For Each att in node.attributes
  116.         If att.Name = attributeName Then
  117.             tmpRet = att.Value
  118.             Exit For
  119.         End If
  120.     Next
  121.    
  122.     GetAttributeByName = tmpRet
  123. End Function
  124. ' Démarrage du programme
  125. Call Main()

n°1363170
alien_nan
Posté le 10-05-2006 à 12:13:11  profilanswer
 

sinon :
ftp://ftp2.developpez.be/developp [...] ficeCs.pdf
 
c'est un pdf qui explique comment generer des docs office au sens large

n°1363347
ixemul
Nan mais sans blague ! ⚡
Posté le 10-05-2006 à 14:35:05  profilanswer
 

Perso, j'utilise la librairie Koogra sur sourceforge, totalement independante d'excel (aucunement besoin d'avoir office sur la machine). Par contre, faut se faire la grille à la mano :D

n°1363378
Arjuna
Aircraft Ident.: F-MBSD
Posté le 10-05-2006 à 14:54:04  profilanswer
 

Merci pour le lien :)
 
Par contre, même si c'est crade, je conserve ma version : ton exemple repose sur les COM "de base" c'est à dire que je dois lier la DLL à ma version d'Excel.
 
Résultat, si je veux que l'appli soit compatible avec plusieurs versions d'Office, je dois installer chaque version d'Excel sur mon poste, puis compiler une version de mon programme pour chaque version d'Excel.
Je préfère donc utiliser mon bignou à deux balles, qui :
-> Instancie depuis C# un environnement de commande, quelle que soit la version de Windows
-> Lance Excel et joue dedans, quelle que soit la version d'Office
 
Bon, après, je suis d'accord, ça reste un bon gros script de grand-mère mais bon, on peut pas tout avoir...

n°1363382
breizhbugs
Posté le 10-05-2006 à 15:00:03  profilanswer
 

Citation :


' Constantes' Ces GUID génériques ont l'avantage d'être idetiques pour toutes les versions' Il faut alors faire confiance à Microsoft pour ne pas changer la structure des objets d'une version à l'autre
Const EXCEL_GUID = "Excel.Application"


Si tu regardes la base des registres, tu verras que [HKEY_CLASSES_ROOT\] Excel.Application [\CurVer] pointe vers la version qui est installé sur l'ordinateur
Donc no soucay pour les versions suivantes.


Message édité par breizhbugs le 10-05-2006 à 15:00:28
n°1363416
Arjuna
Aircraft Ident.: F-MBSD
Posté le 10-05-2006 à 15:22:30  profilanswer
 

Ben oui justement :)
Ce qui permet de distribuer le même script quelle que soit la version installée.
Le programme est capable de retrouver la DLL un peut comme l'association des fichiers : on installe un nouvel outil qui se déclare comme étant le destinataire de cet appel et hop ! pas besoin de changer les liaisons dans le programme :)

n°1423433
KibitO
Posté le 10-08-2006 à 09:54:33  profilanswer
 

Arjuna a écrit :

Moi j'ai la 2003 (11), sauf qu'il me manque les "PIA" d'Excel. Et impossible de trouver où les télécharger (y'a un lien dans la MSDN, mais ça tombe sur une liste de dwl qui n'ont rien à voir)

 

Vous avez une idée ?

 


http://support.microsoft.com/defau [...] r%3B897646
 
Tu pouvais les créer toi aussi à partir des fichiers .tlb correspondants et l'outils TlbImp fourni avec Microsoft Visual Studio .NET..

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C#/.NET managed

  [C#] Créer un fichier Excel

 

Sujets relatifs
[vba Excel 97]sous excel séparer les éléments d'une cellule selon un "/"
Lancer un fichierRESOLU :comment générer un fichier excel depuis Cshell
convertir base de donnée excel en base de donnée SQLenvoyer une donnée dans excel depuis une textbox
Dectecter un Disque dur USB et executer un fichiercopie intranet de fichier en php
[VBS] Organiser la sortie d'un script dans un tableau excel 
Plus de sujets relatifs à : [C#] Créer un fichier Excel


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR