Windows Forms: How to Print RDLC Report without Report Viewer in C#

This post shows you How to Print RDLC Report without Report Viewer in C# .NET Windows Forms Application.

Creating a new Windows Forms Application project, then drag Button from the Visual Studio toolbox to your winform.

How to Print RDLC Report without Report Viewer in C#

You need to create the PrintToPrinter method allows you to print the local report directly to the printer.

Extension Methods

C# extension methods allow developers to extend the functionality of an existing type without creating a new derived type, recompiling or modifying the original type. The C# extension method is a special type of static method called as if it were a method expressed on the extension type.

The LocalReportExtensions class contains the PrintToPrinter extension method.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;

namespace Microsoft.Reporting.WinForms
{
    public static class LocalReportExtensions
    {
        public static void PrintToPrinter(this LocalReport report)
        {
            PageSettings pageSettings = new PageSettings();
            pageSettings.PaperSize = report.GetDefaultPageSettings().PaperSize;
            pageSettings.Landscape = report.GetDefaultPageSettings().IsLandscape;
            pageSettings.Margins = report.GetDefaultPageSettings().Margins;
            Print(report, pageSettings);
        }

        public static void Print(this LocalReport report, PageSettings pageSettings)
        {
            string deviceInfo =
                $@"<DeviceInfo>
                    <OutputFormat>EMF</OutputFormat>
                    <PageWidth>{pageSettings.PaperSize.Width * 100}in</PageWidth>
                    <PageHeight>{pageSettings.PaperSize.Height * 100}in</PageHeight>
                    <MarginTop>{pageSettings.Margins.Top * 100}in</MarginTop>
                    <MarginLeft>{pageSettings.Margins.Left * 100}in</MarginLeft>
                    <MarginRight>{pageSettings.Margins.Right * 100}in</MarginRight>
                    <MarginBottom>{pageSettings.Margins.Bottom * 100}in</MarginBottom>
                </DeviceInfo>";
            Warning[] warnings;
            var streams = new List<Stream>();
            var pageIndex = 0;
            report.Render("Image", deviceInfo,
                (name, fileNameExtension, encoding, mimeType, willSeek) =>
                {
                    MemoryStream stream = new MemoryStream();
                    streams.Add(stream);
                    return stream;
                }, out warnings);
            foreach (Stream stream in streams)
                stream.Position = 0;
            if (streams == null || streams.Count == 0)
                throw new Exception("No stream to print.");
            using (PrintDocument printDocument = new PrintDocument())
            {
                printDocument.DefaultPageSettings = pageSettings;
                if (!printDocument.PrinterSettings.IsValid)
                    throw new Exception("Can't find the default printer.");
                else
                {
                    printDocument.PrintPage += (sender, e) =>
                    {
                        Metafile pageImage = new Metafile(streams[pageIndex]);
                        Rectangle adjustedRect = new Rectangle(e.PageBounds.Left - (int)e.PageSettings.HardMarginX, e.PageBounds.Top - (int)e.PageSettings.HardMarginY, e.PageBounds.Width, e.PageBounds.Height);
                        e.Graphics.FillRectangle(Brushes.White, adjustedRect);
                        e.Graphics.DrawImage(pageImage, adjustedRect);
                        pageIndex++;
                        e.HasMorePages = (pageIndex < streams.Count);
                        e.Graphics.DrawRectangle(Pens.Red, adjustedRect);
                    };
                    printDocument.EndPrint += (Sender, e) =>
                    {
                        if (streams != null)
                        {
                            foreach (Stream stream in streams)
                                stream.Close();
                            streams = null;
                        }
                    };
                    printDocument.Print();
                }
            }
        }
    }
}

Adding a click event handler to the Print button allows you to print the rdlc report directly to the printer.

private void btnPrint_Click(object sender, EventArgs e)
{
    LocalReport localReport = new LocalReport();
    localReport.ReportPath = Application.StartupPath + "\\Report1.rdlc";
    localReport.PrintToPrinter();
}

To play the demo, you should create a simple rdlc report by right-clicking on your project->Add->New Item->Visual C# Items->Report

After finishing create a new report. You need to open your Report Designer, then drag a TextBox from the Report Toolbox into your local report. Finally, Enter some text to play the demo.

How to print rdlc report multiple copies in C#

If you want to print multiple copies or set your printer name, you can modify your code as shown below.

PageSettings pageSettings = new PageSettings();
pageSettings.PrinterSettings.Copies = 5;
pageSettings.PrinterSettings.PrinterName = "Your Printer Name";
//...

You can also change your report to Landscape.

PageSettings pageSettings = new PageSettings();
pageSettings.Landscape = true;
//...

Or set up duplex printing, page orientation, collation...etc

PageSettings pageSettings = new PageSettings();
pageSettings.PrinterSettings.Duplex = Duplex.Simplex;

VIDEO TUTORIAL