Best way to print for Windows Clients (Not Web Apps)?

27,370

Solution 1

For reports, I use the RDLC control.

For everything else, I use the inherent printing objects within .NET.

Edit The inherent printing objects are all found in the System.Drawing.Printing namespace. When you use the PrintDialog or the PrintPreviewDialog in a WinForms (or WPF) application, it is to these objects that you're turning over control.

The fundamental concept is that you're drawing to the printer. The simplest form of this is:

Sub MyMethod()
     Dim x as New PrintDocument
     AddHandler x.PrintPage, AddressOf printDoc_PrintPage
     x.Print
End Sub
Sub printDoc_PrintPage( sender as Object,  e as PrintPageEventArgs)
      Dim textToPrint as String= ".NET Printing is easy"
      dim printFont as new Font("Courier New", 12)
      dim leftMargin as int= e.MarginBounds.Left
      dim topMargin as int = e.MarginBounds.Top
      e.Graphics.DrawString(textToPrint, printFont, Brushes.Black, leftMargin, topMargin)
End Sub

What's happening here is that when my object (x) is sent the print command, it raises the "PRINT PAGE" event (which is designed to print 1 page at a time). This event then uses the Graphics attribute of the PrintPageEventArgs to draw the relevant string directly to the print spooler.

Here's one tutorial, and a quick Google search for ".NET printing tutorial" returns a bit over 200K results.

Solution 2

We used a set of third party DLLs from PDFSharp who in turn use DLLs from MigraDoc. I'm not privy to all the reasons that we went that direction (the decision was made by a senior developer), but I can tell you that:

  • It seems to be in active development.
  • It had most of the features we needed.
  • The source code is available. Although it used some patterns and conventions that I hadn't seen before, once I got on to them, it was fairly easy to make the changes. I added support for using the System.Drawing.Image directly rather than as saving files.
  • It is not documented well either internally or externally.

Solution 3

» Sample Code to show basics of Printing in Windows Forms Applications:

    using System.Drawing.Printing;

    PrintDocument printDoc = new PrintDocument();
    printDoc.DefaultPageSettings.Landscape = true;
    printDoc.DefaultPageSettings.Margins.Left = 100; //100 = 1 inch = 2.54 cm
    printDoc.DocumentName = "My Document Name"; //this can affect name of output PDF file if printer is a PDF printer
    //printDoc.PrinterSettings.PrinterName = "CutePDF";
    printDoc.PrintPage += new PrintPageEventHandler(printDoc_PrintPage);

    PrintDialog printDialog = new PrintDialog();
    printDialog.Document = printDoc; //Document property must be set before ShowDialog()

    DialogResult dialogResult = printDialog.ShowDialog();
    if (dialogResult == DialogResult.OK)
    {
        printDoc.Print(); //start the print
    }   

    void printDoc_PrintPage(object sender, PrintPageEventArgs e)
    {
        Graphics g = e.Graphics;
        string textToPrint = ".NET Printing is easy";
        Font font = new Font("Courier New", 12);
        // e.PageBounds is total page size (does not consider margins)
        // e.MarginBounds is the portion of page inside margins
        int x1 = e.MarginBounds.Left;
        int y1 = e.MarginBounds.Top;
        int w = e.MarginBounds.Width;
        int h = e.MarginBounds.Height;

        g.DrawRectangle(Pens.Red, x1, y1, w, h); //draw a rectangle around the margins of the page, also we can use: g.DrawRectangle(Pens.Red, e.MarginBounds)
        g.DrawString(textToPrint, font, Brushes.Black, x1, y1);

        e.HasMorePages = false; //set to true to continue printing next page
    }

Solution 4

If you can build your output as a FlowDocument, you can turn it into XPS easily to get an "electronic" version, and the print the XPS.

Solution 5

Loads of stuff, you say. Hum, seems that you should use a solution with a designer, so you should look into Crystal Reports and RDLC. There's also the Reporting Services solution, but in that case you would need a server with SQL Server.

Crystal Reports seems to give you more choices, but needs a little more learning than RDLC.

I wouldn't recommend you create those in HTML + CSS, because of the limitations and the extra work you would have to throw at it.

Share:
27,370
Sam
Author by

Sam

Always in search for better answers.

Updated on July 25, 2020

Comments

  • Sam
    Sam almost 4 years

    What is the best way to print stuff from c#/.net?

    The question is in regard to single pages as well as to reports containing lots of pages.

    It would be great to get a list of the most common printing libs containing the main features and gotchas of each of them.

    [Update] for standard windows clients (or servers), not for web apps, please.

    • Joel Coehoorn
      Joel Coehoorn over 15 years
      How much have you already looked at the System.Drawing.Printing namespace?
    • Sam
      Sam over 15 years
      I've looked in a few ways of printing, but before delving deeply into one I'd like to know more - it's a great waste of time to choose the wrong way to learn more about.
  • Sam
    Sam over 15 years
    Oh well, I've got loads of printing stuff coming at me: single pages, long reports, sticky labels, name it, I'll have to print it (soon). So I'd like to get an overview about printing solutions pro and contra.