Dailycode.info

Short solution for short problems

Print multiple pages with PrintDocument class

When you just want to print a single page, it very easy and all you need is a couple of lines of code:

Declare the instance:

private PrintDocument printDoc = new PrintDocument();
 

Add the eventhandler to the printdocument object:

printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage);

Then you can start printing your document in the event handler:

int yPosition = e.MarginBounds.Bottom - 10;
int xPosition = e.MarginBounds.Right - 150;
string toPrint = string.Format("Printed on {0:dd-MMM-yyyy}", DateTime.Now);
e.Graphics.DrawString(toPrint, _normalFont, new SolidBrush(Color.Black), xPosition, yPosition);
 

But when you start writing more and more lines on the page, you will notice that it will only print one page. In order to print several pages, we need to set the HasMorePages flag. What you have to understand is that setting this flag will fire a new print page event after this event is handled.

In this example I have to print a dataset with data from a database. In my loop I have to check: whether the height of the current line is not greater then the page bottom bound. If so, I will have to remember which line I'm in, set the hasmorepages flag and exit the loop. Here is the code:

private int countline = 0;
... 
private void printDoc_PrintPage(Object sender, PrintPageEventArgs e)
{
...
for (int i = countLine; i < ds.Tables[0].Rows.Count;i++)
{
	DataRow dt = ds.Tables[0].Rows[i];
	x = 20;
	e.Graphics.DrawString(dt["Study_number"].ToString(), _normalFont, Brushes.Black, x, y);
	x = x + 130;
        e.Graphics.DrawString(dt["tube"].ToString(), _normalFont, Brushes.Black, x, y);
        x = x + 130;
        e.Graphics.DrawString(dt["total"].ToString(), _normalFont, Brushes.Black, x, y);
        x = x + 130;
        y = y + 20;
        if (y + 20 > e.MarginBounds.Bottom)
        {
        	countLine = i+1;
                e.HasMorePages = true;
                break;
	}
}
 

The countline variable is declare in the class and keeps track of the record I'm handling. When a page is full, the event is ended. When a new printpage event is fired the loop starts where the last page stopped. The printdocument is a performant way to pint documents. I think its perfect for printing data tables in a simple and fast way. If you start adding style to it, you'll better look for open source or 3rd party software, because you can loose to much time.