Click here to Skip to main content
Licence CPOL
First Posted 8 Jun 2006
Views 52,568
Downloads 1,019
Bookmarked 29 times

Writing Text to a Printer with LPrintWriter

By | 8 Jun 2006 | Article
A TextWriter object for writing to a printer

Introduction

Writing plain text to the screen is as simple as Console.WriteLine("{0}", myObj); Writing plain text out to a printer should be as well.

Background

Many of us learned programming with GW-Basic in MSDOS on an IBM PC (Actually, for me it was Level II Basic in TRSDOS on the TRS-80). Back then, we didn't have the fancy GUI displays we have now. Printing to the screen was simple (primitive) but simple (easy). One just had to write...

PRINT "Hello, World!"

... and the text was printed on the screen. And just as simply, if you wrote...

LPRINT "Hello, World!"

... it would be typed out on the attached printer (which was referred to as a "Line Printer", hence the LPRINT command). In fact, you could "open" the screen or printer as a pseudo-file, and direct the text to whichever at run-time:

IF Where$ = "File" THEN OPEN "Output.txt" FOR OUTPUT AS 3
ELSE IF Where$="Printer" THEN OPEN "LPT1:" FOR OUTPUT AS 3
ELSE OPEN "CONS:" FOR OUTPUT AS 3

PRINT#3, "Hello, World!"

Then came Windows, which made drawing full graphics on the screen and printer possible, but made writing anything to the screen or printer difficult. Now, we have .NET, which has reclaimed the simplicity of the Microsoft DOS command line in Console mode applications. Once again, it's just a simple...

Console.WriteLine("Hello, World!");

... to display text on the screen. Similarly, choosing between the screen or a text file can be handled like this:

TextWriter output = TextWriter.Null;
if (Where == "File")
    output = new StreamWriter("output.txt");
else 
    output = Console.Out

output.WriteLine("Hello, World!");

And yet, writing to the printer is as difficult as ever. What we need to fill the hole is a TextWriter-derived class for writing to a printer. LPrintWriter is that class.

Using the Code

Use of LPrintWriter is as simple as promised (just about):

LPrintWriter lprint = new LPrintWriter();
lprint.WriteLine("Hello, world!");
lprint.Close();

Because we are still going through Windows, where printing is still page- & spool-oriented, the Close() at the end is needed to start the actual printing. When the Close is executed, the standard Windows printer dialog is displayed so you can choose your printer and printer settings.

(Actually, the dialog is displayed and printing started upon the Flush() method. Close() calls Flush(). The dialog is displayed only the first time Flush() is called. Thereafter, the same settings are used. To change the setting, you'd have to create a new LPrintWriter object.)

LPrintWriter will default to printing the text in the 10pt Courier New typeface -- monospaced to match output to the screen from Console.WriteLine. However, you can change that to any installed font -- fixed or proportional -- with the Font property:

 lprint.Font = new System.Drawing.Font("Arial", 22.0f);

Similarly, you can change the color of the text (assuming your printer can handle it), using the TextColor property:

lprint.TextColor = Color.Blue;

Note that the font & color settings apply to the entire printout. You cannot set different fonts for different sections of a page.

Additionally, LPrintWriter is a properly derived subclass of TextWriter, so everything you'd expect in a TextWriter class (Flush, Dispose, and the 17 variants of Write & WriteLine) is there. LPrintWriter therefore can be used anywhere a TextWriter is called for. For example, if you wanted to produce & print out some HTML code:

HtmlAnchor A = new HtmlAnchor();
A.HRef = "http://www.msn.com";
A.InnerText = "MSN";
A.RenderControl(new HtmlTextWriter(lprint));

Returning to our switchable output example:

TextWriter output = TextWriter.Null;
if (Where == "File")          output = new StreamWriter("output.txt");
else if (Where == "Printer")       output = new LPrintWriter();
else                    output = Console.Out

output.WriteLine("Hello, World!");

Note, that, despite its purpose to be used in Console application, since it uses PrintDialog, an application which uses LPrintWriter will need a reference to the System.Windows.Forms assembly.

Finally, it is written in C#, but if placed in a class library it can be used from a VB.NET application (that was actually the purpose for which it was written).

Implementation

The nice thing about TextWriter is that all its methods are written in terms of each other, so one only needs to override a minimum of methods. Basically, all you really need to do to create a derived class is code a Write(char) method. Every other Write & WriteLine method will call it (eventually). You only would have to implement other write methods if there was a particular optimization available.

However, in this case, I knew I just needed to collect the text as a big string until it was time to print it, so I derived from StringWriter (whose job is to collect text into a big string). All I had to do was override the Flush() method to handle the actual print.

Printing is pretty much straightforward. At the start, the big string is divided up into an array of little strings -- one for each line. Then for each page, the little strings are pulled from the array and sent to the print spooler until a page is filled.

History

  • 8th June, 2006 - Initial release

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

James Curran

Web Developer

United States United States

Member

20+ years as a developer : Assembly, C, C++ and C# (in that order) with sidelines in ASP/VBScript, ASP.Net, JavaScript, Perl, QuickBasic, VisualBasic, plus a few others which I'm not going to mention because if I did someone might ask me to use them again (shutter)
 
Microsoft MVP in VC++ (1994-2004)
 
I also run www.NJTheater.com as a hobby.
 
Full resume & stuff at NovelTheory.com
 
Underused blog at HonestIllusion.com


Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralThe wizard behind the curtain.. Pinmembercraigg757:17 25 Aug '08  
GeneralRe: The wizard behind the curtain.. PinmemberJames Curran13:18 25 Aug '08  
GeneralWorks great - and a question [modified] PinmemberNina987657:26 5 Dec '06  
GeneralRe: Works great - and a question PinmemberJames Curran1:47 6 Dec '06  
GeneralRe: Works great - and a question PinmemberNina987656:18 6 Dec '06  
Thanks for your reply. Before I got it, I figured out a solution, albeit a different one. I created two additional properties for the LPrintWriter, one named Landscape (bool) and one named Margin (int). In the Flush method I added the following code:
public override void Flush()
{
if (printDocument == null)
{
PrintDialog printDialog = new PrintDialog();
printDialog.Document = new System.Drawing.Printing.PrintDocument();

if (blnLandscape == true) 
				{
					printDialog.Document.DefaultPageSettings.Landscape = true;
				}
if(printDialog.ShowDialog() == DialogResult.OK)
{
printDocument = printDialog.Document;
this.printDocument.BeginPrint += new System.Drawing.Printing.PrintEventHandler(this.OnBeginPrint);
this.printDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(this.OnPrintPage);
 
}
}
if (printDocument != null)
{
printDocument.Print();
base.GetStringBuilder().Length = 0;
 
}
base.Flush ();
}

 
and in the OnPrintPage method I changed the following line of code:
int x = e.MarginBounds.Left;
to
int x = intMargin;.
 
This works well for me. Thank you once more for your code - it is precisely what I needed.
 
Cheers,
Nina
 


QuestionLooks great but how do i... PinmemberGaZbI2:15 14 Jun '06  
AnswerRe: Looks great but how do i... PinmemberJames Curran9:18 14 Jun '06  
GeneralRe: Looks great but how do i... PinmemberGaZbI4:34 15 Jun '06  
GeneralRe: Looks great but how do i... PinmemberMember 135347217:37 11 Jun '08  
GeneralExcellant Pinmemberrippo20:50 12 Jun '06  
GeneralRe: Excellant PinmemberJames Curran2:00 13 Jun '06  
QuestionRe: Excellant PinmemberMarkSchultz9:04 20 Nov '06  
GeneralGreat LPrint is back Pinmemberruben ruvalcaba14:54 12 Jun '06  
GeneralRe: Great LPrint is back PinmemberJames Curran16:42 12 Jun '06  
QuestionRe: Great LPrint is back PinmemberMarkSchultz9:06 20 Nov '06  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120529.1 | Last Updated 8 Jun 2006
Article Copyright 2006 by James Curran
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid