Was ist der beste Ansatz zum Drucken / Berichten von WPF? [geschlossen]

70

Ich habe ein bevorstehendes Projekt, das in der Lage sein muss, einfache Berichte aus seinen Daten zu drucken. Es wird WPF-basiert sein und ich frage mich, welchen Weg ich gehen soll.

Ich weiß, dass WPF eine eigene Drucktechnologie (basierend auf XPS) einführt, die recht einfach zu bedienen aussieht. Ein Teil von mir fragt sich jedoch, ob es einfacher wäre, das ReportViewer-Steuerelement zu verwenden und es in ein Windows Forms-Hoststeuerelement einzubetten, da Benutzer dadurch in eine Vielzahl von Formaten exportieren und drucken können.

Hat jemand Erfahrung mit dem Drucken / Berichten von WPF? Welche Richtung würden Sie empfehlen?

Matt Hamilton
quelle
Mit SimpleWPFReporting können Sie jeden Bericht mit der vollen Leistung von WPF XAML erstellen. SimpleWPFReporting sorgt dafür, dass es als PDF exportiert oder gedruckt wird.
Max

Antworten:

25

Wir hatten das gleiche Problem und haben vorerst RDLC / ReportViewer verwendet. Es gibt kein natives WPF-Berichterstellungstool (das ich kenne) und RDLC ist ziemlich einfach zu verwenden und kostenlos. Der Laufzeitaufwand dafür ist gering (ca. 2 MB), aber Sie müssen daran denken, ihn zu verteilen, da er nicht Teil von .NET Framework ist.

Bob King
quelle
42

Einschränkungen von RDL

Ich habe ursprünglich RDLC / ReportViewer zum Drucken mit WPF verwendet, fand es aber sehr einschränkend. Einige der Einschränkungen, die ich gefunden habe, waren:

  • RDL konnte nur die langweiligsten Berichte erstellen
  • Das Erstellen eines Berichts mit RDL war viel aufwändiger als mit direktem WPF: Die Entwurfswerkzeuge sind im Vergleich zu Expression Blend- und RDL-Deals nur in Tabellen sehr primitiv
  • Ich konnte ControlTemplates, DataTemplates, Styles usw. Nicht verwenden
  • Meine Berichtsfelder und -spalten konnten aufgrund der Datengröße nicht effektiv in der Größe geändert und neu angeordnet werden
  • Grafiken mussten als Bilder importiert werden - sie konnten nicht als Vektoren gezeichnet oder bearbeitet werden
  • Die Positionierung von Elementen erforderte eher Code-Behind als Datenbindung
  • Fehlende Transformationen
  • Sehr primitive Datenbindung

Das Drucken direkt aus WPF ist sehr einfach

Aufgrund dieser Einschränkungen habe ich mich mit der Erstellung von Berichten mit reinem WPF befasst und festgestellt, dass dies wirklich ziemlich trivial ist. Mit WPF können Sie Ihre eigene DocumentPaginatorUnterklasse implementieren , die Seiten generieren kann.

Ich habe eine einfache DocumentPaginator-Unterklasse entwickelt, die alle visuellen Elemente verwendet, den visuellen Baum analysiert und ausgewählte Elemente ausblendet, um jede Seite zu erstellen.

DocumentPaginator-Details

Folgendes bewirkt meine DocumentPaginator-Unterklasse während der Initialisierung (aufgerufen beim Abrufen des ersten PageCount oder beim ersten Aufruf von GetPage ()):

  1. Scannt den visuellen Baum und erstellt eine Karte aller gescrollten Bedienfelder in ItemsControls
  2. Beginnend mit dem äußersten Punkt werden Elemente in den ItemsControls von vornherein unsichtbar, bis das Visual auf eine einzelne Seite passt, ohne dass ein Bildlauf erforderlich ist. Wenn die äußerste nicht genug reduziert werden kann, werden die Innenverkleidungen reduziert, bis sie erfolgreich sind oder nur noch ein Gegenstand auf jeder Ebene vorhanden ist. Notieren Sie den Satz sichtbarer Elemente als erste Seite.
  3. Blenden Sie die Elemente der untersten Ebene aus, die bereits auf der ersten Seite angezeigt wurden, und machen Sie nachfolgende Elemente sichtbar, bis sie nicht mehr auf die Seite passen. Notieren Sie alle Elemente außer dem zuletzt hinzugefügten als zweite Seite.
  4. Wiederholen Sie den Vorgang für alle Seiten und speichern Sie die Ergebnisse in einer Datenstruktur.

Die GetPage-Methode meines DocumentPaginator lautet wie folgt:

  1. Suchen Sie die angegebene Seitenzahl in der Datenstruktur, die während der Initialisierung generiert wurde
  2. Ausblenden und Anzeigen von Elementen im visuellen Baum, wie in der Datenstruktur angegeben
  3. Legen Sie die angehängten Eigenschaften PageNumber und NumberOfPages fest, damit der Bericht die Seitennummerierung anzeigen kann
  4. Leeren Sie den Dispatcher ( Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() => {} ));), um alle Aufgaben zum Rendern des Hintergrunds abzuschließen
  5. Erstellen Sie ein Rechteck in der Größe der Seite, deren VisualBrush das zu druckende Bild ist
  6. Messen, Anordnen und Aktualisieren Legen Sie das Rechteck fest und geben Sie es zurück

Dies stellte sich als recht einfacher Code heraus und ermöglichte es mir, praktisch alles, was ich mit WPF erstellen konnte, in Seiten umzuwandeln und auszudrucken.

Zusätzliche Berichtsunterstützung

Jetzt, da mein Paginator funktioniert, muss ich mir keine Sorgen mehr machen, ob ich meine WPF-Inhalte für Bildschirm oder Papier erstelle. Tatsächlich funktioniert die Benutzeroberfläche, die ich für die Dateneingabe und -bearbeitung erstelle, häufig auch sehr gut zum Drucken.

Von dort aus fügte ich eine einfache Symbolleiste und etwas Code hinzu, was zu einem vollwertigen Berichtssystem führte, das auf WPF basiert und weitaus leistungsfähiger als RDL ist. Mein Berichtscode kann in Dateien exportiert, auf dem Drucker gedruckt, Seitenbilder ausgeschnitten / eingefügt und Daten für Excel ausgeschnitten / eingefügt werden. Ich kann auch jede meiner Benutzeroberflächen mit einem Klick auf ein Kontrollkästchen auf "Druckansicht" umschalten, um zu sehen, wie sie beim Drucken aussehen wird. All dies in nur wenigen hundert Zeilen C # und XAML!

An diesem Punkt denke ich, dass die einzige Funktion, die RDL nicht in meinem Berichtscode hat, die Möglichkeit ist, eine formatierte Excel-Tabelle zu generieren. Ich kann sehen, wie dies getan werden kann, aber bisher war dies nicht erforderlich - das Ausschneiden und Einfügen der Daten allein hat ausgereicht.

Aus meiner Erfahrung heraus würde ich empfehlen, einen Paginator zu schreiben und dann WPF selbst zu verwenden, um Ihre Berichte zu erstellen.

Ray Burns
quelle
6
Sehr interessant, da ich daran denke, RDLC fallen zu lassen. Haben Sie den Code Ihres Dokumentenpaginators veröffentlicht?
Eduardo Molteni
2
Könnten Sie das überhaupt erweitern? Vielleicht mit einigen Beispielen für Shortcode / XAML?
Alex Hope O'Connor
1
Gefunden dies: codeproject.com/Articles/138233/…
Alex Hope O'Connor
6
"Das Drucken direkt aus WPF ist sehr einfach". Ist das wirklich? Ich habe bereits viel Zeit und Mühe in die Implementierung investiert, und das Paginieren eines datengebundenen Datagrids ist bei weitem nicht einfach. Ich fürchte, der Teufel steckt im Detail und bis ich welche sehe, ist diese Antwort nicht sehr nützlich.
Manos Dilaverakis
1
Hier, hier, @RayBurns. Sehen wir uns ein Github-Repo an, damit wir zu dieser fantastisch klingenden Implementierung beitragen können.
Killnine
8

Schauen Sie sich http://wpfreports.codeplex.com/ an.

Lukas Cenovsky
quelle
Ich habe einen Artikel auf nullskull gefunden, der Schritt für Schritt erklärt, wie man eine WPF Report Engine mit demselben Ansatz erstellt.
WiiMaxx
Sieht gut aus, aber in der Projektbeschreibung 2020/11/11 heißt es immer noch: "Dies ist eine sehr frühe Alpha-Version, die nicht für Produktionsumgebungen vorgesehen ist."
UяošKoт
3

Schauen Sie sich PdfReports an . Es handelt sich um eine Code First Reporting Engine, die auf den Bibliotheken iTextSharp und EPPlus aufbaut. Es ist sowohl mit .NET 3.5+ Web- als auch mit Windows-Anwendungen kompatibel.

VahidN
quelle
iTextSharp Lizenzen :(
JuFo
Es gibt auch eine .NET Core / Full .NET-Version dieser Bibliothek mit einer LGPL-Lizenz: github.com/VahidN/PdfReport.Core
VahidN
3

Wie wäre es mit Scryber? Damit können PDF-Berichtsvorlagen mithilfe von XML definiert und zur Laufzeit an Daten in Ihrer Anwendung gebunden werden. http://scryber.codeplex.com/

LiamV
quelle
1

Ich habe kürzlich die Aufgabe erfüllt, ein eigenes Berichtssystem zu entwickeln, das im Wesentlichen aus Designumgebung und Datenquellen-Manager besteht. Die erste Aufgabe bestand darin, eine WYSWIG-ähnliche Designumgebung zu entwickeln. Ich habe dies mit GDI + gemacht, ohne mich um das Drucken zu kümmern, da das Drucken / Generieren der Druckvorschau am einfachsten war als ich erwartet hatte. Im Allgemeinen müssen nur alle Dinge auf dem Bildschirm auf das Grafikobjekt des Druckereignisses gezeichnet werden.

Ich denke, dass es im Fall von WPF ähnlich wäre. Sie sollten sich also nur darum kümmern, Ihren Bericht auf dem Bildschirm anzuzeigen, und das Drucken würde nur wenige Codezeilen umfassen.

MoreThanChaos
quelle