69 votes

Quelle est la meilleure approche pour imprimer / créer des rapports à partir de WPF?

J'ai un projet à venir qui devront être en mesure d'imprimer des rapports à partir de ses données. Ce sera en fonction de WPF, et je me demandais où aller.

Je sais que WPF présente sa propre technologie d'impression (basé sur XPS) qui semble assez facile à utiliser. Toutefois, une partie de moi se demande si ce serait plus facile d'utiliser le contrôle ReportViewer et de l'intégrer dans un Windows Forms de contrôle d'hôte, depuis que donnera aux utilisateurs la possibilité d'exporter vers une variété de formats, ainsi que de l'impression.

Quelqu'un a eu une expérience avec l'impression/création de rapports à partir de WPF? La direction recommanderiez-vous?

42voto

Ray Burns Points 38537

Les limites de la RDL

J'y suis allé avec RDLC/ReportViewer pour l'impression avec WPF, mais il lui est très limitant. Certaines des limites que j'ai trouvées étaient:

  • RDL ne peut créer que le plus ennuyeux de rapports
  • Il était beaucoup plus de travail pour créer un rapport en utilisant RDL que dans droit en WPF: Les outils de conception sont très primitives par rapport à Expression Blend et de la RDL ne traite que des tableaux
  • Je n'ai pas eu la possibilité d'utiliser ControlTemplates, DataTemplates, Styles, etc
  • Mon champs de rapport et les colonnes ne pouvaient effectivement redimensionner et réorganiser selon la taille des données
  • Les graphismes ont dû être importés que des images - il n'a pas pu être établis ou modifiés en tant que vecteurs
  • Le positionnement des éléments requis code-behind plutôt que de la liaison de données
  • Manque de transformations
  • Très primitive de la liaison de données

Impression directement à partir de WPF est très facile

En raison de ces limitations, j'ai regardé dans la création de rapports à l'aide de pure WPF et a découvert qu'il était vraiment tout à fait banale. WPF permet de mettre en oeuvre votre propre DocumentPaginator sous-classe qui peuvent générer des pages.

J'ai développé un simple DocumentPaginator sous-classe qui prend tout Visuel, analyse visuelle de l'arbre, et masque les éléments sélectionnés à la création de chaque page.

DocumentPaginator de détails

Voici ce que ma DocumentPaginator sous-classe ne lors de l'initialisation (appelée lors de la première propriété pagecount est rapportée, ou lors de la première GetPage ()):

  1. Des Scans de l'arbre visuel et rend une carte de tous défiler les panneaux à l'intérieur de ItemsControls
  2. En commençant par l'extérieur, rend éléments dans le ItemsControls invisible de la dernière à la première jusqu'à ce que le Visuel tient sur une seule page, sans avoir à faire défiler. Si l'extérieur ne peut pas être assez réduit, réduit les panneaux intérieurs jusqu'à ce qu'il réussisse ou n'a qu'un seul élément à chaque niveau. Enregistrement de l'ensemble des éléments visibles que la première page.
  3. Cacher le plus bas niveau, les éléments qui ont déjà été indiqué sur la première page, puis effectuer par la suite des éléments visibles jusqu'à ce qu'ils ne peuvent plus tenir sur la page. Enregistrement de tous, mais le dernier élément ajouté à la deuxième page.
  4. Répétez le processus pour toutes les pages, en stockant le résultat dans une structure de données.

Mon DocumentPaginator de GetPage méthode est comme suit:

  1. Rechercher le numéro de page dans la structure de données générées lors de l'initialisation
  2. Masquer et afficher des éléments dans l'arborescence visuelle, comme indiqué dans la structure de données
  3. Ensemble PageNumber et NumberOfPages attaché propriétés, ce rapport peut afficher les numéros de page
  4. Rincer le Répartiteur (Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => {} ));) pour obtenir de rendu en arrière-plan des tâches à remplir
  5. Créer un Rectangle de la taille de la page dont VisualBrush est le visuel imprimé
  6. Mesure, d'Organiser et d'UpdateLayout le rectangle, puis le retourner

Ceci s'est avéré être tout à fait simple code, et m'a permis de transformer pratiquement tout ce que j'ai pu créer avec WPF en pages et impression.

Des rapports supplémentaires de soutien

Maintenant que mon paginator est au travail, je n'ai plus à vous inquiéter beaucoup de savoir si je suis la création de mon WPF contenu de l'écran ou sur papier. En fait, souvent de l'INTERFACE utilisateur que je construis pour la saisie des données et l'édition fonctionne aussi très bien pour l'impression.

À partir de là, j'ai ajouté une simple barre d'outils et un peu de code derrière, résultant en un véritable système de déclaration construit autour de WPF qui était beaucoup plus performant que RDL. Mon code de signalement peut exporter des fichiers, d'impression à l'imprimante, copier/coller des images de page, et couper/coller des données pour Excel. Je peux aussi passer tout de mon INTERFACE utilisateur pour l'impression d'une vue" avec un clic sur une case à cocher pour voir ce qu'il va ressembler si elles sont imprimées. Tout cela, en quelques centaines de lignes de C# et XAML!

À ce stade, je pense que la seule fonction de RDL a que mon code de signalement ne pas avoir est la capacité à générer de la mise en forme de feuille de calcul Excel. Je peux voir comment cela pourrait être fait, mais jusqu'à présent il n'y a pas besoin de couper et coller les données a été suffisant.

De mon expérience, ma recommandation serait d'écrire un paginator, puis commencer à utiliser WPF pour créer vos rapports.

25voto

Bob King Points 12913

Nous avons eu le même problème et avons fini par utiliser RDLC / ReportViewer pour le moment. À ma connaissance, il n'existe pas d'outil de génération de rapports WPF natif, et RDLC est assez simple à utiliser et gratuit. La surcharge d’exécution de ce logiciel est faible (environ 2 Mo), mais vous devez vous rappeler de le distribuer car il ne fait pas partie du .NET Framework.

8voto

Lukas Cenovsky Points 2425

3voto

VahidN Points 3905

Jetez un coup d'oeil à PdfReports . Il s'agit d'un premier moteur de génération de rapports basé sur les bibliothèques iTextSharp et EPPlus. Il est compatible avec les applications Web et Windows .NET 3.5+.

0voto

Doug Points 21

Sans entrer dans toute une discussion politique sur l'avenir de WPF, la meilleure option que nous avons trouvée consistait à envelopper ReportViewer dans un contrôle hôte Windows Forms.

http://blog.pineywoodstech.com/index.php/2012/01/using-microsoft-reportviewer-with-wpf/

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X