Entwickler-Ecke

WinForms - Drucken von HTML Dokumenten


Csharp-programmierer - Mi 18.05.16 16:11
Titel: Drucken von HTML Dokumenten
Hallo,
ich habe ein Verwaltungsprogramm für eine kleine Firma geschrieben, wo ich unter anderem Quittungen ausdrucken muss. Meine Idee: einfach eine HTML-Datei aus den Daten erstellen und diese ausdrucken. Leichter gesagt als getan.

Ich habe mich im Internet ein wenig umgeschaut und festgestellt, dass man den WebBrowser zum drucken benutzen kann: this.webBrowser1.Print(); Bei dem Drucker kommt aber nichts an. Dann habe ich es so versucht:


C#-Quelltext
1:
2:
3:
4:
if (printDialog1.ShowDialog() == DialogResult.OK)
{
  this.webBrowser1.Print();
}


Bei anderen Programmen druckt der Drucker, aber hier nicht. Warum?


Delete - Mi 18.05.16 16:36

- Nachträglich durch die Entwickler-Ecke gelöscht -


Csharp-programmierer - Mi 18.05.16 16:44

Stimmt. Das hört sich logisch an.
Aber da das Programm für einen "Kunden" ist, muss man den Drucker einstellen können. Wie geht das?


Delete - Mi 18.05.16 16:52

- Nachträglich durch die Entwickler-Ecke gelöscht -


Csharp-programmierer - Mi 18.05.16 17:37

Perfekt. Das haut hin.
Aber nun noch 2 kleine Fragen:
1) kann man die Seiten Nummerierung ausschalten und das Datum und den Daten Pfad ausschalten? Ich finde das für eine Quittung unprofessionell.
2) wenn ich die HTML Datei mit CSS bearbeitet,druckt der Drucker dann die CSS Stiles mit?


Ralf Jansen - Mi 18.05.16 18:19

Zitat:
1) kann man die Seiten Nummerierung ausschalten und das Datum und den Daten Pfad ausschalten? Ich finde das für eine Quittung unprofessionell.
2) wenn ich die HTML Datei mit CSS bearbeitet,druckt der Drucker dann die CSS Stiles mit?


Ohne es genau geprüft zu haben aber es kommt letztlich auf den installierten Webbrowser an. Also je nachdem welche Internet Explorer Version installiert ist.
In CSS kann man explizit definieren für welches Medium ein CSS Ausdruck gelten soll (@media print oder @media screen oder ...) Ob das der Webbrowser auch berücksichtigt und wie genau ist eher undefiniert. Die Druckerstyles für css werden in den verschiedenen Webbrowser eher stiefmütterlich behandelt. Und wenn man den Browser überlässt wie er drucken soll macht er halt irgendwas (was passiert mit floating divs, wie werden Tabellen umgebrochen, was macht der mit Schusterjungen etc.)

Wenn du ein definiertes Layout brauchst das stimmen muss und nicht einfach irgendwas ungefähres ausgedruckt haben willst ist der Weg über einen Webbrowser (moving target) sicher nicht der Weg den man einschlagen sollte. Das würde ich nur tun wenn ich absolute Kontrolle hätte welcher Webbrowser den genau verwendet wird.


Csharp-programmierer - Mi 18.05.16 19:07

Am liebsten würde ich auf PDF umrüsten. Aber dann braucht man wieder ein PDF Plugin was man erlernen müsste. Oder eignet sich .rtf für solche Zwecke?


Delete - Mi 18.05.16 23:48

- Nachträglich durch die Entwickler-Ecke gelöscht -


jaenicke - Do 19.05.16 04:52

Ich wundere mich, dass noch niemand die Standardlösung für solche Fälle ins Spiel gebracht hat:
Reporting Lösungen

Die haben den Vorteil, dass das Layout frei angepasst werden kann und man je nach Lösung die Ausgabe nicht nur drucken, sondern auch als PDF usw. 1:1 speichern kann.

Beispiele:
https://msdn.microsoft.com/en-us/library/ms251671(v=vs.120).aspx
oder FyiReporting, ich finde grad nur einen Fork, da die Seite down ist:
https://github.com/majorsilence/My-FyiReporting


Delete - Do 19.05.16 13:06

- Nachträglich durch die Entwickler-Ecke gelöscht -


Csharp-programmierer - Mi 25.05.16 18:49

Also ich möchte es so programmieren, dass der Benutzer einmal die Einstellungen des Druckers / Seitenlayout über einen Button einstellen kann. Danach soll das Programm automatisch drucken, ohne die Dialoge aufzurufen.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
private void button2_Click(object sender, EventArgs e)
        {
            //Button der die Einstellungen anzeigen und speichern soll
            web.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(_ducumentCompleted);
            web.Url = new Uri(Path.Combine(Application.StartupPath, "Test.html"));
        }
        private void _ducumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            web.ShowPageSetupDialog();
            web.ShowPrintDialog();
        }



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
if (this.checkBox2.Checked == true)
            {

                BuildHTML();  //Kreiert eine HTML-Datei und speichert sie unter Druckerdatei.html
                web.Url = new Uri(Path.Combine(Application.StartupPath, "Druckerdatei.html"));
                web.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(xy);
            }

private void xy(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            web.Print();
        }


Wenn ich nun Druckereinstellungen treffe, und der Teil mit dem If-Statement ausgeführt wird, werden beide Dialoge noch einmal aufgerufen. Warum?


Ralf Jansen - Mi 25.05.16 19:05

Ich kann nur vermuten (raten) aus den Codefragmenten. Ich sehe 2 mal das du einen EventHandler hinzufügst. Wenn web die immer gleiche Instanz der Klasse ist dann hängt der EventHAndler auch 2 mal dran und wird 2 mal aufgerufen. So wie es aussieht wird vermutlich button2 auch mehrmals geklickt werden können und hängt den Eventhandler jedesmal nochmal dran bis der irgendwann dann n-mal ausgeführt wird wenn das Ereignis DocumentCompleted tatsächlich auftritt.

Also das DocumentCompleted Event besser genau einmal dran hängen. Wenn web das Webbrowser Control dann verdrahte den Event über den Winforms Designer und schmeiße das ganze Event verdrahten aus deinem eigenen Code. Dann kannst du dir sicher sein das der verdrahtet wird und das auch nur genau 1 mal.

Der EventHandler ruft 2 Methoden der web Klasse auf. Beide Methoden klingen so als würden sie einen Dialog anzeigen. Wenn der _ducumentCompleted Event ausgeführt wird werden halt auch beide Methoden darin ausgeführt und beide Dialoge angezeigt. Und da du den EventHandler mehrmals verdrahtest baust du dir da die totale DialogEskalation (2 Dialoge anzeigen, 4 Dialoge anzeigen, 6 Dialo ... u.s.w.)
Ich sehe nirgendwo Code der nur ShowPageSetupDialog oder nur ShowPrintDialog aufruft also muss ich davon ausgehen das du immer beide bekommst möglicherweise beide sogar mehrmals oder gar keinen der beiden.


Delete - Do 26.05.16 05:41

- Nachträglich durch die Entwickler-Ecke gelöscht -