Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

A customizable printing text class

3.67/5 (5 votes)
2 Jun 20062 min read 1   1.3K  
A text document printing class that adds customizable header, footer, and line numbers to your printed text. The text can also be printed using three different styles.

PrintTextDocument test application.

Introduction

At least once, in the life of a programmer, it succeeds that the moment arrives to print a text document. The task is quite simple for a .NET programmer, but even more with PrintTextDocument class. This class was written to help in printing text documents, adding customizable header and footer and line numbers to the printed text. The text can be printed wrapping the exceeding text to the next line, truncating it, or spanning it through many pages. The last mode is useful when printing text banners like the ones coming from ASCII Art or from text tables with many columns. PrintTextDocumen is derived from System.Drawing.Printing.PrintDocument and provides some extra properties that set the class behavior during printing.

Using the code

The class is very simple to use. Typically, you create an instance of the PrintTextDocument class, set the properties that describe how to print, for example, header and footer, and call the Print method to start the printing process; just like you do with the PrintDocument class. The class constructor is: PrintTextDocument(string filepath), where filepath is the full path of the text document to print.

C#
//
// Simple use of PrintTextDocument class
//
// assume filename a string that contains the full path of
// an ASCII file.
//

PrintTextDocument toPrint = new PrintTextDocument(filename);
toPrint.PrintMode = PrintTextMode.WrapText;
toPrint.PrintLineNumbers = true;

toPrint.Print();

Points of interest

When I wrote the code, the first version was quite simple. The OnPrintPage override was made of a loop that scanned through the text file and called the MeasureString and DrawText methods. After some trials, I noticed that there was a bug in the text wrapping. It was as if MeasureString did not take care of the spaces at the end of the line. This was because of the way I wrote the GetLineBreakCharPosition function. This function checks the result of MeasureString and makes the adjustment according to the number of spaces that came at the end of the measured text. I don’t know if this is a bug of MeasureString. I did not find any useful information regarding this strange behavior. I even tried to use StringFormat with the MeasureString method but it did not get better. I’d like to know if there is another way to do what GetLineBreakCharPosition does.

C#
private int GetLineBreakCharPosition(Graphics gfx, 
            string text, RectangleF rectangle)
{
    StringFormat fmt = 
      new StringFormat(StringFormatFlags.MeasureTrailingSpaces);

    int charactersOnLine = 0;
    int lines = 0;

    // Sets the value of charactersOnPage to the number of characters 
    // of stringToPrint that will fit within the bounds of the rectangle.
    SizeF sizeText = gfx.MeasureString(text, _printFont,
        rectangle.Size, fmt,
        out charactersOnLine, out lines);

    string rem = text.Substring(0, charactersOnLine);

    // Fix MeasureString issue with trailing spaces
    if(rem.EndsWith(" ") && (charactersOnLine < text.Length))
    {
        string noSpaces = rem.TrimEnd(new Char[] { ' ' });
        int nSpaces = rem.Length - noSpaces.Length;

        SizeF sizeChunk = gfx.MeasureString(noSpaces, 
            _printFont,
            rectangle.Size, fmt,
            out charactersOnLine, out lines);

        // Measure white space width
        string spacer = String.Empty;

        // Loop until all available space are filled
        while(sizeChunk.Width <= rectangle.Width)
        {
            spacer += " ";
            sizeChunk = gfx.MeasureString(noSpaces + spacer, 
                _printFont,
                new PointF(0, 0), fmt);
        }

        charactersOnLine += spacer.Length - 
            ((sizeChunk.Width > rectangle.Width) ? 1 : 0);
    }

    return charactersOnLine;
}

History

  • 28/05/2006 - v.1.0.0.0 - PrintTextDocument simple text file print class with custom header, footer, and printing mode.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here