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 denBeginPrint
Event reinhängt.Ich persönlich würde dazu vermutlich von
PrintDocument
ableiten und denStreamReader
zu nem Member vonMyPrintDocument
machen. Oder gleich das ganze File in den Speicher laden und einList<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
beiBeginPrint
wieder auf Anfang zu setzen. DerPrintDialog
muss ja z.B. die Seitenanzahl ermitteln, also muss er schonmal dasPrintDocument
durchackern bis dieses sagt dass es fertig ist.
Andrerseits kann man imPrintDialog
dann so Sachen wie Margins ändern, und die können sich im Ausdruck nur ändern wenn dasPrintDocument
danach nochmal durchgespult wird.
Und da ich in deinem Code nichts sehe was das mehrmalige durchgehen desPrintDocument
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), wirdppeArgs.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
undPrintDocument
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.