Samstag, 14. Januar 2012

Drucken mit C#

In diesem Post möchte ich euch zeigen, wie man mit C# den Drucker ansteuern kann.
Hierfür gibt es bestimmt einige Möglichkeiten, ich benutze hier die Graphics Eigenschaft des Druckereignisses, das auszudruckende Resultat muss dann in dieser gezeichnet werden.

Zuerst muss System.Drawing.Printing eingebunden werden.
Die folgende Zeile initialisiert uns das benötigte Objekt, welches das zu druckende Dokument repräsentiert.

PrintDocument PrintDoc = new PrintDocument();

Installierte Drucker sind in PrinterSettings.InstalledPrinters gespeichert. In dieser Liste liegen die Namen der Drucker als Strings vor, zum Setzen des zu benutzenden Druckers benutzen wir PrintDoc.PrinterSettings.PrinterName = PrinterSettings.InstalledPrinters[Index].
Gedruckt wird das Dokument über den Befehl PrintDoc.Print().
Vorher fügen wir dem Druckdokument allerdings eine Ereignisbehandlung für sein Druckereignis hinzu: PrintDoc.PrintPage += new PrintPageEventHandler(PrintPage).
Hierbei ist PrintPage eine beliebige Funktion mit folgender Signatur: void PrintPage(object sender, PrintPageEventArgs e).
Diese wird nun aufgerufen, wann immer ein Dokument gedruckt wird.
In dieser können wir dann das gewünschte Druckresult erstellen, indem wir es in e.Graphics zeichnen. Es können z.B. auch Bilder eingelesen werden und dort hinein gezeichnet werden.
Zum Abschluss der komplette Quellcode, welcher eine Linie und einen String druckt:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Drawing.Printing;


namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Print()
        {
            PrintDocument PrintDoc = new PrintDocument();

            List<string> Printers = new List<string>();
            foreach (string p in PrinterSettings.InstalledPrinters)
                Printers.Add(p);

            // Alle verfügbaren Drucker sind in Printers gespeichert, man könnte den Benutzer daraus auswählen lassen.
            // In diesem Beispiel wird einfach immer Drucker 0 gewählt.
            PrintDoc.PrinterSettings.PrinterName = PrinterSettings.InstalledPrinters[0];

            PrintDoc.PrintPage += new PrintPageEventHandler(PrintPage);
            PrintDoc.Print();
        }

        void PrintPage(object sender, PrintPageEventArgs e)
        {
            e.Graphics.DrawLine(new Pen(Color.Black), new Point(0, 0), new Point(100, 100));
            e.Graphics.DrawString("Ich kann jetzt mit C# drucken", new Font("Times New Roman", 12), new SolidBrush(Color.Black), new Point(45, 45));

        }
    }


}

Kommentare:

  1. Hallo,

    wenn du einen Pen P1 erzeugst, muss man dann in der DrawLine Methode darunter wieder einen erzuegen oder kann einfach den P1 verwenden ?

    AntwortenLöschen
  2. Nein, danke für den Hinweis, war ein Fehler von mir, wollte es erstmal anders implementieren und hatte die Zeile dann vergessen. Also P1 braucht man nicht.
    Du kannst aber natürlich auch P1 erzeugen und diesen dann verwenden, mit dem Neuerzeugen hat das ja nichts zu tun.
    Viele Grüße
    Oliver

    AntwortenLöschen
  3. Muesste

    [code]foreach (string p in PrinterSettings.InstalledPrinters)
    Printers.Add(p);[/code]

    nicht eher

    [code]foreach (string p in PrintDoc.PrinterSettings.InstalledPrinters)
    Printers.Add(p);[/code]

    heissen

    AntwortenLöschen
  4. Hi eudaimonie,
    wieso?

    Bei mir funktioniert's nur auf die beschriebene Weise.
    PrinterSettings.InstalledPrinters benutzt eine statische Liste in der alle Drucker vorhanden sind. PrintDoc.PrinterSettings.InstalledPrinters wirft bei mir einen Syntaxfehler.

    AntwortenLöschen
  5. Kleiner Hinweis - auf diese Weise lässt sich zwar wunderbar drucken (also per Zeichnung von Hand), allerdings ist es auch sehr umständlich für größere Mengen an Daten (wie Diagramme / Protokolle etc)... daher von mir der Tipp: ein UserControl mit allen benötigten Anzeigeelementen zusammenstellen (Chart, Labels, Images), Breite und Höhe auf DinA4 setzen (auf die Auflösung in dpi aufpassen) und anschließend ganz einfach das UserControl drucken:

    [CODE]
    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) {
    Bitmap bmp = new Bitmap(this.Width, this.Height);
    this.DrawToBitmap(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
    e.Graphics.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height);
    }
    [/CODE]

    Das Control muss dafür nicht zwingend angezeigt werden. Es soll nicht verschwiegen werden, dass es kann zu kleineren Abstrichen in der Darstellung kommen kann (z.B. bei ListViews), aber es ist immer noch besser als ALLES von Hand zu zeichnen.

    Gruß
    Andi

    AntwortenLöschen
  6. Hey Andi,
    danke für deinen Beitrag!

    AntwortenLöschen
  7. Danke! Auch wenn der Beitrag schon recht alt ist hätte ich noch eine Anregung: Wie stellt man es am besten an, mehrseitig zu drucken? Beispielsweise habe ich mehrere Bilder, die alle auf eine eigene Seite gedruckt werden sollen.

    AntwortenLöschen
    Antworten
    1. Ich hab hier mal was geschrieben:
      http://computerjar.blogspot.de/2016/01/drucker-unter-c-winforms-ansteuern.html

      Löschen