How to print a document using C# code?

Learn how to print a document using c# code? with practical examples, diagrams, and best practices. Covers c#, winforms, printing development techniques with visual explanations.

Printing Documents Programmatically in C#

Hero image for How to print a document using C# code?

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:

  1. BeginPrint: Occurs once before the first page is printed. Useful for initialization.
  2. PrintPage: Occurs for each page that needs to be printed. This is where you draw your content onto the Graphics object provided by the event arguments.
  3. 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.

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.

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.