Crystal Report et .Net

Un tutorial simplifié au maximum, pour rapidement faire un etat avec Crystal Report pour .Net Vu 40310  fois

 

Ce How-To a pour but de vous expliquer rapidement comment faire facilement un rapport Crystal Report avec .Net. J’exposerai les 2 méthodes, et détaillerai la meilleure des 2.

Crystal Report  (CR) est intégré à .Net, il faut bien évidemment l’avoir sélectionné dans la liste des composants lors de l’installation de Visual Studio.Net. Ensuite il sera accessible dans un projet en ajoutant un “Etat Crystal Report”.

Les 2 méthodes concernent les données du Crystal Report. Soit on remplie les données directement à partir d’une connexion à une base de données, soit on remplie via un DataSet fortement typé. La première solution est à bannir car c’est une calamité pour la simple raison qu’il faudra se balader avec les paramètres de connexion à chaque fois.
Je vais donc expliquer la deuxième solution.

-         Qu’est ce qu’un DataSet Fortement Typé ?

c’est juste la définition de Tables sur lesquelles le rapport CR se basera pour afficher les données. Le DataSet est en fait un fichier XML qui définit les différentes tables qui composeront le rapport.

-         Pourquoi utiliser cette technique ?

Cela permet d’éviter de baser le rapport sur une connexion base de données. En fait le rapport se basera sur le DataSet fortement typé qu’on aura définit. Il fera le lien entre sa Source et le DataSet. Ce qui évite toute connexion à la base de données par CR.

Pour ajouter un DataSet au projet il faut ajouter l’élément “DataSet” (format XSD).

test

Ensuite il faut définir les différentes tables (Éléments). Prenons comme exemple une liste d’élèves. Pour cela ajoutons un élement. Clic droit sur le XSD (onglet DataSet) puis ajouter un élément.

Définir le nom de l’élément à ELEVES puis 2 champs (nom et prénom) en string.

mode wizard

Vous pouvez visualiser le XML généré par cette action en cliquant sur l’onglet XML. Maintenant que le DataSet est fait, on peut passer à la création de notre rapport.
Le moyen le plus simple et le plus rapide est d’utiliser l’assistant de création. Ouvrez ou Ajoutez l’etat crystal report en mode Design. Puis Faites un bouton droit Etat/Expert Etat. Il passera en mode Wizard. Lors de l’ajout d’un nouvel état il passera automatiquement en mode Wizard.

Attention, passer en mode Wizard implique de supprimer toute la mise en page des données sur l’état courant.

Le Wizard se présente ainsi :  

wizard

La première chose à faire est de sélectionner la source de données, en l’occurrence le DataSet fortement typé que nous avons préalablement créé (voir l’image ci-dessus). Puis d’insérer toutes les tables dont on a besoin (ELEVES pour les lecteurs qui ne suivent pas). Ensuite, il faut sélectionner les champs de la table que l'on souhaite afficher :

 

wizard 2

Puis cliquez sur terminer. Le Wizard génèrera alors un État pré rempli avec toutes les données. A votre guise bien évidemment de modifier l’interface. Maintenant il nous reste à tester l’état avec des données. Pour cela ajoutez au projet une page web et mettez un composant CrystalReportViewer.

Puis en code behind mettez le code suivant :

DataTable dt = new DataTable("ELEVES");
dt.Columns.Add(new DataColumn("nom",typeof(string)));
dt.Columns.Add(new DataColumn("prenom",typeof(string)));


DataRow dr = dt.NewRow();
dr["nom"] = "toto";
dr["prenom"] = "ducheo";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["nom"] = "titi";
dr["prenom"] = "mize";
dt.Rows.Add(dr);


cr_test crt = new cr_test();
crt.SetDataSource(dt);


CrystalReportViewer1.ReportSource = crt;
CrystalReportViewer1.DataBind();

Lancez la page et vous pourrez constater le remarquable rapport que vous venez de créer. C’est bien beau et bien gentil tout ça mais comment faire quand on a des données un peu plus compliqué à manipuler ?

Modifions le DataSet en rajoutant une table (élément). Appelez la table CLASSE avec un Code et un libellé. Puis rajoutez comme champ le code de la table CLASSE dans la table ELEVES. 

DataSet complet

 Vous comprendrez avec un tel DataSet qu’on veut chaque élève groupé par sa Classe. Ceci paraît presque simple mais il y a quelques choses à savoir. Si on modifie un DataSet, le lien dans le rapport de CR ne sera pas automatiquement rafraîchi. Le seul moyen que j’ai trouvé est le suivant :

 1 – Bouton Droit : Base de données puis connexion/déconnexion du serveur. Déconnecter la “connexion actuelle” qui fait référence à votre DataSet.

2 – Bouton Droit : Base de données puis Ajouter/supprimer une base de données. Enlevez la table ELEVES de la liste des tables sélectionnées puis rafraîchir les tables de la liste de gauche. Pour cela il faut rétrécir la racine de ADO DataSet et rouvrir la racine. Ajoutez bien évidemment les 2 tables.

Maintenant que les 2 tables ont été rajoutées, un nouvel onglet fait son apparition ; Liaison. C’est dans cet onglet, qu’on définit les liaisons entre les tables. Supprimer toutes les liaisons et faites le lien entre le CODE de ELEVES et le CODE de CLASSE. Vous pourrez revenir à tout moment dans les liaisons en faisant bouton droit/base de données/expert liaisons virtuelles.

Ensuite relancez le Wizard afin de redéfinir notre affichage. Procédez comme précédemment. Mais cette fois-ci allez jusqu'à l’étape des GROUPES. Définissez comme champs de groupe le CODE de la table CLASSE. Faites Terminer puis repassons dans le code pour modifier la source de données comme cela :

DataSet ds = new DataSet("DataSet_ftype");


DataTable dt = new DataTable("CLASSE");
dt.Columns.Add(new DataColumn("code",typeof(int)));
dt.Columns.Add(new DataColumn("libelle",typeof(string)));


DataRow dr = dt.NewRow();
dr["code"] = "1";
dr["libelle"] = "CLASSE 1";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["code"] = "2";
dr["libelle"] = "CLASSE 2";
dt.Rows.Add(dr);


ds.Tables.Add(dt);


dt = new DataTable("ELEVES");
dt.Columns.Add(new DataColumn("nom",typeof(string)));
dt.Columns.Add(new DataColumn("prenom",typeof(string)));
dt.Columns.Add(new DataColumn("code",typeof(int)));


dr = dt.NewRow();
dr["nom"] = "toto";
dr["prenom"] = "ducheo";
dr["code"] = 1;
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["nom"] = "titi";
dr["prenom"] = "mize";
dr["code"] = 2;
dt.Rows.Add(dr);


ds.Tables.Add(dt);
cr_test crt = new cr_test();
crt.SetDataSource(ds);


CrystalReportViewer1.ReportSource = crt;
CrystalReportViewer1.DataBind();

Faites bien attention à ce que les Tables créées dans le DataSet du CodeBehind portent le même nom que celles du DataSet fortement typé.

Ensuite testez et admirez votre œuvre. Comme vous avez pu le constater, Crystal Report génère une page aspx avec une gestion des pages suivantes et précédentes etc. Mais il y a d’autres moyens d’afficher beaucoup plus sympathiques.

Avec Crystal Report on peut exporter sous différents formats de données ; Word, Excel, RTF, et surtout PDF !

Regardez attentivement le Code ci-dessous à placer après le code ci-dessus.

MemoryStream oStream; 
CrystalDecisions.Shared.ExportFormatType t = CrystalDecisions.Shared.ExportFormatType.WordForWindows;
string content_type = "application/doc";
int export_voulu = 2;
   
/******************************
   * 1 - application/vnd.ms-excel"
   * 2 - application/pdf
   * 3 - application/word
   * 4 - application/rtf (il faut WordForWindows et non RichText)
   * *****************************/

switch (export_voulu)
{
   case 1:
   t = CrystalDecisions.Shared.ExportFormatType.Excel ;
      content_type="application/vnd.ms-excel";
      break;
   case 2:
   t = CrystalDecisions.Shared.ExportFormatType.PortableDocFormat ;
      content_type = "application/pdf";
      break;
   case 3:
   t = CrystalDecisions.Shared.ExportFormatType.WordForWindows ;
      content_type = "application/msword";
      break;
   case 4:
   t = CrystalDecisions.Shared.ExportFormatType.RichText;
      content_type = "application/rtf";
      break;

}
oStream = (MemoryStream)crt.ExportToStream(t);
            
Response.Clear();
Response.Buffer= true;
Response.ContentType = content_type;
Response.BinaryWrite(oStream.ToArray());

Voila le code que j’utilise afin d’exporter sous le format dont j’ai besoin. Le code est assez explicite. En fait je modifie le flux de sortie HTML via un MemoryStream généré par la fonction ExportToStream du rapport. Modifiez export_voulu par la valeur souhaitée afin de tester les différents formats.

Le format PDF est mon préféré puisqu’il intègre toutes les fonctions de mise en page et d’impression sans rien coder J

Crystal Report pour .Net est très bien quand on arrive à s’en servir correctement. Au début, il peut s’avérer très lourdingue mais à force on s’y habitue et limite on apprécie la facilité d’utilisation. Je n’ai pas exposé toutes les options comme les totaux ou les sauts de pages mais il n’est pas difficile de trouver par soi-même.

Bonne chance à tous. Et n’hésitez pas à demander de l’aide :)


 

Publié le  13/05/2005
Auteur:  FeelTheWay

 

Commentaires

Posté le : 02/06/2005 Par : pench

Bonjour, votre article m'a bcp aidé
pour faire le lien entre dataset et crystal report.

J'utilise ASP.net et les composant crystal report.
J'ai fouillé pour faire des histogrammes, j'y arrive mais plusieurs pbms :
La taille en largeur du graphique reste fixe qqsoit le nombre de batons a afficher (la largeur de chq baton est proportionnelle a la largeur de l'histogramme selon le nb de batons)
Pour un nb eleve de batons a afficher, c donc illisible.
2/ Pour afficher des mois sur l'axe des abcisses, a partir des nb (1, 2,3, ...12) j'ai reussi a convertir en libelle (1= janvier..) grace a Format, mais je n'arrive pas a trier dans l'ordre croissant des mois.

Merci de votre aide

Posté le : 03/06/2005 Par : FeelTheWay

Merci de ton commentaire.
Ca serait avec plaisir de t'aider et surtout de compléter mon article par les fonctions un peu plus avancées. Malheureusement en ce moment je suis beaucoup pris par une mission.

Ce week end j'aurais peut etre un moment de libre, j'essaierais d'y jeter un oeil. Mais le mieux c'est d'en parler sur le forum :)

Posté le : 15/12/2005 Par : patlemagnifik

Extra ce tuto !!!!
Mais j'ai une question ...
d'où vient l'objet cr_test crt=new cr_test() ???

y a til un un espace de nom à utiliser en particulier ?

Posté le : 15/12/2005 Par : FeelTheWay

Salut,

cr_test est en fait l'objet représentant l'état Crystal Report dans .Net.

Quand tu ajoutes un état crystal report dans ta solution .Net, il va te créer tous les fichiers. Ton état sera utilisable dans le Code via l'objet représentant cet état.

Si tu crées un objet TOTO tu auras une classe TOTO dans le fichier TOTO.CS.

Posté le : 19/12/2005 Par : patlemagnifik

Merci pour ta réponse !!!

je te recontacte FeelTheWay pour savoir si tu n'avais pas un tuto un peu plus détaillé sur la création d'états Crystal Report ...
J'ai une état à créer mais qui comporte plusieurs pages. Dois je tout mettre dans le rpt ou dois je en créer un nouveau ??? ;)

Posté le : 26/01/2006 Par : pierron

Bonjour,
En effet, ce tuto est très bien. Juste une question avez vous déjà rencontré des pb lors de l'utilisation de pdf.
Dans mon appli, lorsque j'utilise pdf, j'ai un message d'erreur d'acrobat redear m'indiquant : "Une erreur est survenue lors de l'ouverture de ce document. Le fichier est endommagé et n'a pu être réparé". En Word ça marche mais c'est pas cool ! Une piste ?
Merci d'avance. LP

Posté le : 16/02/2006 Par : napi

Bonjour
Je cherche à relier mon formulaire à un dataset de mon projet C++.
J'ai créé un état dans mon projet et dans la liste des datatsets à lier, il n'y a rien.
Quelqu'un pour me dépanner ?
Merci

Posté le : 16/02/2006 Par : FeelTheWay

Tu peux relier un Formulaire à un DataSet Fortement Typé, et tu associes ton DataSet (classique) à ton DataSet Fortement Typé.

Posté le : 04/05/2006 Par : tzar

salut
merci pour ce tuto
Ma question est la suivante je vais vous donner un ex pour etre plus clair
Je replie ma table par une requette
StrSql="SELECT A.Prix,A.Qte,A.Prix*A.Qte AS Valeur FROM Achat A"
et je remplis ma table comme tu l'as explique mais lorsque je veut faire la somme des valeurs dans le crystal report la fonction somme me donne le nombre d'enregistrement.
ex si j'ai deux valeur d'un article 10 et 20 au lieux d'avoir 30 elle me donne 2

Posté le : 04/05/2006 Par : FeelTheWay

Peux tu me dire comment tu as fait pour faire la "somme", tu n' pas utiliser COUNT au lieu de SUM ?

Posté le : 06/05/2006 Par : tzar

salut
je m'excuse pour le retard s'est que je n'ai pas internet chez moi
j'ai utilise la somme qui existe dans le crystal report expert mais ca n'a rien donne
je vais essaye de te decrire ce que je suis en train de faire
mon projet comporte un etat du stock dans la quelle il y a le stock initial,sa veleur, les achat et leur valeur les ventes et leur valeur le stock actuel avec sa valeur
le probleme est que parfois on a un article dans le stock initiale mais on n'a pas fait des achat sur ce dernier cette annee mais on faite des vente ta methode ma vraiment aider mais j'ai beaucoup de calcule dans mon etat alors que faire tout mon projet repose sur cette phase et merci encore une fois

Posté le : 06/05/2006 Par : tzar

Schema

stock ini Achat vente stock
Article couleur Qte valeur Qte valeur Qte valeur Qte Valeur
12 verte 500 50000 100 6000 200 16000 400 40000
SUM SUM SUM SUM SUM SUM SUM SUM
14 rose 600 6000 100 1400 500 4600
SUM SUM 0 0 SUM SUM SUM SUM
la somme pour chaque article en plus du calcule du CUMP
si tu as un idee merci pour tout

Posté le : 06/05/2006 Par : tzar

je m'excuse pour le shema je l'ai bien fait mais apres avoir valider tout s'est melanger

Posté le : 07/05/2006 Par : FeelTheWay

Oui j'avoue avoir du mal à comprendre ton machin :)

mais en gros pour crystal report le mieux c'est d'avoir une proc stock quifait toute le métier (les sommes etc...) ca sera nettement plus performant après.

Posté le : 19/05/2006 Par : eliot

Je viens d'écrire le code suivant en VB :
Dim dt As System.Data.DataTable
Dim dr As DataRow
dt = New DataTable("ELEVES")
dt.Columns.Add(New DataColumn("nom"))
dt.Columns.Add(New DataColumn("prenom"))

dr = dt.NewRow()
dr.Item(0) = "toto"
dr.Item(1) = "echo"
dt.Rows.Add(dr)

Dim crt2 As New cr_test
crt2.SetDataSource(dt)
CrystalReportViewer1.ReportSource = crt2
CrystalReportViewer1.DataBind()

et j'obtiens toujours le message d'erreur :

Chaîne de classe incorrecte
Description : Une exception non gérée s'est produite au moment de l'exécution de la demande Web actuelle. Contrôlez la trace de la pile pour plus d'informations sur l'erreur et son origine dans le code.

Détails de l'exception: System.Runtime.InteropServices.COMException: Chaîne de classe incorrecte

Erreur source:


Ligne 37 :
Ligne 38 : Dim crt2 As New cr_test
Ligne 39 : crt2.SetDataSource(dt)
Ligne 40 : CrystalReportViewer1.ReportSource = crt2
Ligne 41 : CrystalReportViewer1.DataBind()


Fichier source : c:\inetpub\wwwroot\WebApplication5\WebForm1.aspx.vb Ligne : 39

Posté le : 15/06/2006 Par : 2710hriadh

Bonjour, votre article m'a bcp aidé
pour faire le lien entre dataset et crystal report.
Ma question est la suivante:
une fois que j'ai remplis mes deux table je veux imprimer non tous le contenu mais une sélection par exemple je veux imprimer seulement un eleve avec son classe.

Posté le : 18/07/2006 Par : Yeude

salut
merci pour ce tuto, il m'a bcq aidé.
En fait, j'ai un petit pb... j'ai créé un rapport crystal a partir d'une procédure stockée et tout se passe bien sauf pour un champs du rapport, il se met par défaut en chaine(10) et me tronque une des données de ce champs, pourtant quand je lance ma procédure stockée via sql server elle me renvoie le champs en entier. Je ne sais pas où est ce qu'on peut changer la taille, pourriez vous m'aider svp...

Posté le : 22/08/2006 Par : juliette

salut,
j'ai bien aimé votre façon d'expliquer. vous avez traité exactement la partie dont j'avais besoin, sauf que j'ai fait a la lettre ce que vous m'avez demandé mais ça marche pas pour moi.
veuillez m'aider s'il vous plaît.
Merci

Posté le : 22/08/2006 Par : FeelTheWay

je vous ai demandé quoi exactement ? :D

Posté le : 25/11/2006 Par : dahid

Comment télécharger l'article?

Posté le : 25/11/2006 Par : dahid

Envoyer moi l'article sur mon E-mail
dahid_sidi@yahoo.fr s'il vous plaît.
Merci

Posté le : 11/04/2008 Par : pavnguyen

Bonjour,

Comment on peut exporter sous le format HTML?

Si vous souhaitez ajouter un commentaire vous devez être authentifié.

 

ASP MAGAZINE  ASP-PHP.NET  C²I  CodePPC  CodeS-SourceS  Dotnet-News.com  Tech Head Brothers 

Dotnet-Project.com© tous droits réservés
Webmaster Aleks. Ont collaboré à l'aboutissement de ce projet :
CodeS-SourceS.com, ASP-PHP.Net, DotNet-FR.org, C2i.fr, Newsletter ASP.NET.