Liste drucken / Druckerauswahl & Druckereinstellungen



  • Mir ist es gelungen, eine Liste auf dem aktuellen Drucker zu drucken. Die Liste wurde zunächst als TXT-Datei ausgegeben. Die Überschriften und Seitennummern sind dabei. Blattwechsel sind durch eine Zeile ".page" gekennzeichnet.

    Ich kann die Liste drucken, es fehlen jedoch die Druckerauswahl und das setzen von Druckereinstellungen, wie Vorder- und Rückseite bedrucken, nur Seite von-bis drucken usw.

    Vielleicht hat dazu jemand einen Hinweis (oder auch mehrere..)
    Hier der Code für den Listendruck:

           // bei class definiert
            private Font DruckFont;
            private StreamReader reader;
            private PrintDocument printDocument1 = new PrintDocument();
            public string ListenDatei = ""; 
    
            private void BDrucken_Click(object sender, EventArgs e)
            {
                if (File.Exists(ListenDatei))
                { 
                    reader = new StreamReader(ListenDatei); 
                    DruckFont = new Font("Courier New", 10); // Courier New Schrift mit der Größe 10
                    PrintDocument pd = new PrintDocument();  // PrintDocument-Objekt
                    pd.PrintPage += new PrintPageEventHandler(this.PrintTextFileHandler); 
                    pd.Print(); // Druckmethode aufrufen
                    if (reader != null)
                       reader.Close();
                }
            }
    
            private void PrintTextFileHandler(object sender, PrintPageEventArgs ppeArgs)
            {
                Graphics g = ppeArgs.Graphics; // Graphics-Objekt
                float linesPerPage = 0;
                float yPos = 0;
                int count = 0;
                float LinkerRand = ppeArgs.MarginBounds.Left; // Linker Rand von PrintPageEventArgs
                float ObererRand = ppeArgs.MarginBounds.Top;  // Oberer Rand von PrintPageEventArgs
                string line = null;
                //Zeilen pro Seite aus Seitenhöhe und Schrifthöhe
                //linesPerPage = ppeArgs.MarginBounds.Height / DruckFont.GetHeight(g); // nicht genutzt
                linesPerPage = 100; // weil Blattwechsel mit .page markiert in rtfBox
                while (count < linesPerPage && ((line = reader.ReadLine()) != null))
                {
                    yPos = ObererRand + (count * DruckFont.GetHeight(g));
                    if (line.Length == 5)
                    {
                        if (line == ".page") // Seitenwechsel erforderlich ?
                        {
                            line = " ";
                            count = 1000; // Blattwechsel erzwingen
                        }
                    }
                    // Text zeichnen
                    g.DrawString(line, DruckFont, Brushes.Black, LinkerRand, yPos, new StringFormat());
    
                    count++; // nächste Zeile 
                }
    
                if (line != null) // Datei-Ende noch nicht erreicht ?
                {
                    ppeArgs.HasMorePages = true; // Es gibt weitere Seiten
                }
                else
                {
                    ppeArgs.HasMorePages = false; // Es gibt keine weiteren Seiten
                }
            }
    
    


  • Hab nicht viel Plan von C#, aber mit C++ und der WINAPI brauchst du dazu den PrintDlg.
    Hier das Pendant dazu in C#, vielleicht isses ja das, was du suchst.



  • @hkdd Der Link von @DocShoe sollte passen. Allerdings musst du dazu deinen Code etwas anpassen, denn dein PrintDocument muss es dann unterstützen mehrfach gedruckt zu werden.
    Ich schätze mal das macht man am einfachsten indem man sich in den BeginPrint Event reinhängt.

    Ich persönlich würde dazu vermutlich von PrintDocument ableiten und den StreamReader zu nem Member von MyPrintDocument machen. Oder gleich das ganze File in den Speicher laden und ein List<String> Member statt dessen machen.



  • Ich danke Euch für die Hinweise. Ich habe inzwischen ein Lösung gefunden, die gut funktioniert. Es geht um die Anweisung

      pd.Print(); // Druckmethode aufrufen
    

    Genau dort musste die Druckerauswahl eingebaut werden. Ich kann jetzt auch Druckereinstellungen machen, wie Vorder- und Rückseite bedrucken usw.Nun sieht es folgendermaßen aus

            private void BDrucken_Click(object sender, EventArgs e)
            {
                if (File.Exists(ListenDatei))
                { 
                    reader = new StreamReader(ListenDatei);  // StreamReader-Objekt
                    DruckFont = new Font("Courier New", 10); // Courier New Schrift mit der Größe 10
                    PrintDocument pd = new PrintDocument();  // PrintDocument-Objekt
                    pd.PrintPage += new PrintPageEventHandler(this.PrintTextFileHandler); //PrintPage-Ereignishandler hinzufügen
    
                    PrintDialog printDialog = new PrintDialog();
                    printDialog.Document = pd;
                    printDialog.AllowSelection = true;
                    printDialog.AllowSomePages = true;
    
                    if (printDialog.ShowDialog() == DialogResult.OK)
                    {
                        pd.Print(); //Druckmethode aufrufen
                    }
    
                    if (reader != null)
                       reader.Close(); // Reader schliessen
                }
            }
    
            private void PrintTextFileHandler(object sender, PrintPageEventArgs ppeArgs)
            {
                Graphics g = ppeArgs.Graphics; // Graphics-Objekt
                float linesPerPage = 0;
                float yPos = 0;
                int count = 0;
                float LinkerRand = ppeArgs.MarginBounds.Left; // Linker Rand von PrintPageEventArgs
                float ObererRand = ppeArgs.MarginBounds.Top;  // Oberer Rand von PrintPageEventArgs
                string line = null;
                //Berechnen Sie die Zeilen pro Seite anhand der Seitenhöhe und der Höhe der Schrift
                //linesPerPage = ppeArgs.MarginBounds.Height / DruckFont.GetHeight(g);
                linesPerPage = 100; // weil Blattwechsel mit .page markiert in rtfBox
                while (count < linesPerPage && ((line = reader.ReadLine()) != null)) // Zeile lesen
                {
                    yPos = ObererRand + (count * DruckFont.GetHeight(g)); // Startposition
    
                    if (line.Length == 5)
                    {
                        if (line == ".page") // Seitenwechsel erforderlich ?
                        {
                            line = " ";
                            count = 1000; // Blattwechsel erzwingen
                        }
                    }
                    //Text zeichnen
                    g.DrawString(line, DruckFont, Brushes.Black, LinkerRand, yPos, new StringFormat());
                    
    
                    count++; // nächste Zeile 
                }
    
                if (line != null) // Datei-Ende noch nicht erreicht ?
                {
                    ppeArgs.HasMorePages = true; // Es gibt weitere Seiten
                }
                else
                {
                    ppeArgs.HasMorePages = false; // Es gibt keine weiteren Seiten
                }
            }
    
    
    


  • @hkdd Funktioniert das wirklich so?

    Ich wüsste nämlich ehrlich gesagt nicht wie es funktionieren soll wenn da kein Code ist um den StreamReader bei BeginPrint wieder auf Anfang zu setzen. Der PrintDialog muss ja z.B. die Seitenanzahl ermitteln, also muss er schonmal das PrintDocument durchackern bis dieses sagt dass es fertig ist.
    Andrerseits kann man im PrintDialog dann so Sachen wie Margins ändern, und die können sich im Ausdruck nur ändern wenn das PrintDocument danach nochmal durchgespult wird.
    Und da ich in deinem Code nichts sehe was das mehrmalige durchgehen des PrintDocument ermöglicht...

    Also ich würde das an deiner Stelle auf jeden Fall nochmal testen ob das so wie gepostet wirklich funktioniert. Der PrintDialog wird so schon angezeigt werden, aber die Frage ist ob der Ausdruck dann auch stimmt.



  • @hustbaer ,
    ich hatte bereits eingangs gesagt, dass die Listendatei im Vorfeld erstellt wird. Sie wird in einer RichTextBox angezeigt mit Seiten-Nummern und Überschriften. Dabei muss natürlich bekannt sein, wie viele Zeilen bei dem gewählten Font auf eine Seite passen.

    "Die Liste wurde zunächst als TXT-Datei ausgegeben. Die Überschriften und Seitennummern sind dabei. Blattwechsel sind durch eine Zeile ".page" gekennzeichnet."

    Im PrintTextFileHandler wird auf .page abgefragt und ein Blattwechsel durch Count=1000 erzwungen (Ende der while-Schleife).
    Wenn das Dateiende noch nicht erreicht ist (also Blattwechsel wegen .page), wird

    ppeArgs.HasMorePages = true; // Es gibt weitere Seiten
    

    gesetzt, andernfalls (bei Dateiende) wird

    ppeArgs.HasMorePages = false; // Es gibt keine weiteren Seiten
    

    gesetzt.



  • @hkdd
    Das hatte ich schon verstanden, mir ging's um was anderes. Hab mich aber getäuscht, PrintDialog und PrintDocument sind weit weniger schlau als ich angenommen hatte.

    Dennoch kann dein Code mMn. nicht funktionieren. Probier mal z.B. nur Seiten 3-4 eines 10-seitigen Dokuments zu drucken. Einstellen lässt sich das mit deinem Code, aber drucken tut er trotzdem immer alles.



  • @hustbaer ,
    da hast Du Recht, es wird immer alles gedruckt.
    Einzelne Blätter u.ä. könnte man im Vorfeld machen: nur die zu druckenden Daten bereitstellen.
    Mir ging es hier darum, einen Weg zu finden, eine Liste aus einer Textdatei zu drucken und dabei vorher festgelegte Blattwechsel zu realisieren.
    Ganz früher, als wir noch auf Nadeldrucker die Listen druckten, wurde in die Datei ein FF (Form Feed = 0x0C) Zeichen eingefügt und der Drucker machte einen Blattwechsel. Heute wird darauf nicht mehr reagiert.

    In einem Word-Dokument kann man mit Strg+Enter einen Blattwechsel festlegen. In einem RTF-Dokument geht das nicht so ohne weiteres. Wordpad vom Windows kann keine Blattwechsel markieren.
    Irgendwo habe ich gelesen, man könne in eine RTF-Datei ".page" einfügen, darauf reagiert der Drucker aber leider nicht, dass muss man selbst machen, so wie ich es in diesem kleinen Testprogramm getan habe.



  • @hustbaer sagte in Liste drucken / Druckerauswahl & Druckereinstellungen:

    Probier mal z.B. nur Seiten 3-4 eines 10-seitigen Dokuments zu drucken. Einstellen lässt sich das mit deinem Code

    Das ist sehr interessant. Bei meinem Drucker Canon Pixma ip7250 kann ich mit meinem Programm bei der Druckerauswahl die Seiten von-bis nicht einstellen. Wenn ich mit Word ein Dokument drucke oder mit Adobe Reader, dann geht das schon.
    Ich kann aber einstellen: auf Vorder- und Hinterseite drucken.
    Wahrscheinlich kommt es dabei auf den Drucker und den zugehörigen Treiber an.



  • @hkdd
    Ich hab den von dir gezeigten Code mit dem PDF Printer probiert, da kann man die Seiten schon einstellen. Nur wird halt trotzdem alles gedruckt. Sieht so aus als müsse sich das PrintDocument (bzw. dessen PrintPage Event Handler) selbst darum kümmern dass nur das gedruckt wird was eingestellt wurde.


Log in to reply