How to print a document using C# code?
Categories:
Printing Documents Programmatically in C#

Learn how to integrate printing functionality into your C# applications, covering basic text, graphics, and multi-page documents using WinForms.
Integrating printing capabilities into a C# application is a common requirement for many desktop applications, especially those built with Windows Forms. This article will guide you through the process of printing various types of content, from simple text to complex graphics and multi-page documents, using the System.Drawing.Printing
namespace. We'll cover the essential components and event handlers needed to achieve robust printing functionality.
Understanding the Printing Architecture
The System.Drawing.Printing
namespace provides the core classes for printing in C#. The primary class you'll interact with is PrintDocument
. This class represents the document to be printed and exposes events that allow you to control the printing process page by page. Other important classes include PrintDialog
for user interaction (selecting printers, setting preferences) and PrintPreviewDialog
for previewing the document before printing.
flowchart TD A[User Initiates Print] --> B{PrintDialog.ShowDialog()} B -- User Confirms --> C[PrintDocument.Print()] C --> D{PrintDocument.BeginPrint Event} D --> E{PrintDocument.PrintPage Event} E -- For Each Page --> F[Draw Content on Graphics Object] F --> E E -- No More Pages --> G{PrintDocument.EndPrint Event} G --> H[Printing Complete]
Flowchart of the C# Printing Process
The printing process is event-driven. When PrintDocument.Print()
is called, it triggers a sequence of events:
BeginPrint
: Occurs once before the first page is printed. Useful for initialization.PrintPage
: Occurs for each page that needs to be printed. This is where you draw your content onto theGraphics
object provided by the event arguments.EndPrint
: Occurs once after the last page has been printed or the printing process is canceled. Useful for cleanup.
Basic Text Printing Example
Let's start with a simple example: printing a block of text. This involves creating a PrintDocument
instance, handling its PrintPage
event, and then using a PrintDialog
to allow the user to select a printer and initiate printing.
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
public class SimplePrinter
{
private PrintDocument printDoc;
private string textToPrint = "This is a sample text to be printed.\nIt can span multiple lines.\n\nHello, C# Printing!";
private int currentPage = 0;
public SimplePrinter()
{
printDoc = new PrintDocument();
printDoc.PrintPage += new PrintPageEventHandler(PrintDoc_PrintPage);
}
public void PrintText()
{
PrintDialog printDialog = new PrintDialog();
printDialog.Document = printDoc;
if (printDialog.ShowDialog() == DialogResult.OK)
{
currentPage = 0; // Reset page counter for new print job
printDoc.Print();
}
}
private void PrintDoc_PrintPage(object sender, PrintPageEventArgs e)
{
// Define font and brush
Font printFont = new Font("Arial", 12);
SolidBrush blackBrush = new SolidBrush(Color.Black);
// Calculate layout
float linesPerPage = 0;
float yPos = 0;
int count = 0;
float leftMargin = e.MarginBounds.Left;
float topMargin = e.MarginBounds.Top;
// Split text into lines
string[] lines = textToPrint.Split('\n');
// Calculate the number of lines that will fit on the page
linesPerPage = e.MarginBounds.Height / printFont.GetHeight(e.Graphics);
// Iterate over the lines and draw them
while (count < lines.Length && yPos < e.MarginBounds.Bottom)
{
// Check if we are on the current page's lines
if (count >= currentPage * linesPerPage && count < (currentPage + 1) * linesPerPage)
{
yPos = topMargin + (count % linesPerPage * printFont.GetHeight(e.Graphics));
e.Graphics.DrawString(lines[count], printFont, blackBrush, leftMargin, yPos, new StringFormat());
}
count++;
}
// If there are more lines, tell the PrintDocument to print another page.
if (count < lines.Length)
{
currentPage++;
e.HasMorePages = true;
}
else
{
e.HasMorePages = false;
currentPage = 0; // Reset for next print job
}
// Clean up
printFont.Dispose();
blackBrush.Dispose();
}
// Example usage (e.g., from a button click event in a WinForms app)
/*
private void btnPrint_Click(object sender, EventArgs e)
{
SimplePrinter printer = new SimplePrinter();
printer.PrintText();
}
*/
}
C# code for printing simple text with multi-page support.
TextRenderer.DrawText
or a rich text box control's printing capabilities, which handle word wrapping and advanced layout automatically.Printing Graphics and Images
Printing images or custom graphics follows a similar pattern. Instead of DrawString
, you'll use methods like DrawImage
or other Graphics
drawing methods within the PrintPage
event handler. You need to manage the image's position and size on the page.
using System.Drawing;
using System.Drawing.Printing;
using System.Windows.Forms;
public class ImagePrinter
{
private PrintDocument printDoc;
private Image imageToPrint;
public ImagePrinter(Image image)
{
imageToPrint = image;
printDoc = new PrintDocument();
printDoc.PrintPage += new PrintPageEventHandler(PrintDoc_PrintPage);
}
public void PrintImage()
{
PrintDialog printDialog = new PrintDialog();
printDialog.Document = printDoc;
if (printDialog.ShowDialog() == DialogResult.OK)
{
printDoc.Print();
}
}
private void PrintDoc_PrintPage(object sender, PrintPageEventArgs e)
{
// Calculate the rectangle where the image will be drawn.
// This example centers the image and scales it to fit within margins.
RectangleF marginBounds = e.MarginBounds;
float imageWidth = imageToPrint.Width;
float imageHeight = imageToPrint.Height;
float ratioX = marginBounds.Width / imageWidth;
float ratioY = marginBounds.Height / imageHeight;
float ratio = Math.Min(ratioX, ratioY); // Use the smaller ratio to fit both dimensions
float newWidth = imageWidth * ratio;
float newHeight = imageHeight * ratio;
float x = marginBounds.Left + (marginBounds.Width - newWidth) / 2;
float y = marginBounds.Top + (marginBounds.Height - newHeight) / 2;
e.Graphics.DrawImage(imageToPrint, x, y, newWidth, newHeight);
// For a single image, there are no more pages.
e.HasMorePages = false;
}
// Example usage (e.g., from a button click event in a WinForms app)
/*
private void btnPrintImage_Click(object sender, EventArgs e)
{
// Assuming 'myImage' is an Image object loaded from a file or resource
Image myImage = Image.FromFile("path/to/your/image.png");
ImagePrinter printer = new ImagePrinter(myImage);
printer.PrintImage();
myImage.Dispose(); // Dispose the image after printing
}
*/
}
C# code for printing an image, scaled and centered on the page.
Graphics
objects, Font
objects, Brush
objects, and Image
objects when you are finished with them to prevent memory leaks. The PrintPageEventArgs.Graphics
object is managed by the system, but any Graphics
objects you create yourself should be disposed.Adding Print Preview Functionality
A print preview is crucial for user experience, allowing users to see how their document will look before committing to printing, saving paper and ink. The PrintPreviewDialog
control makes this very easy to implement.
using System.Drawing.Printing;
using System.Windows.Forms;
public class PreviewPrinter
{
private PrintDocument printDoc;
private string contentToPrint = "This is content for print preview.";
public PreviewPrinter()
{
printDoc = new PrintDocument();
printDoc.PrintPage += new PrintPageEventHandler(PrintDoc_PrintPage);
}
public void ShowPrintPreview()
{
PrintPreviewDialog previewDialog = new PrintPreviewDialog();
previewDialog.Document = printDoc;
previewDialog.ShowDialog();
}
private void PrintDoc_PrintPage(object sender, PrintPageEventArgs e)
{
// This is the same PrintPage logic as before, drawing content onto e.Graphics
// For simplicity, we'll just draw the contentToPrint string.
e.Graphics.DrawString(contentToPrint, new Font("Times New Roman", 14), Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top);
e.HasMorePages = false;
}
// Example usage
/*
private void btnPreview_Click(object sender, EventArgs e)
{
PreviewPrinter printer = new PreviewPrinter();
printer.ShowPrintPreview();
}
*/
}
C# code to integrate a Print Preview Dialog.