Print RDLC Report without showing ReportViewer Control

You can print an RDLC report programmatically by using LocalReport object and CreateStreamCallback callback function. Here is a complete Microsoft docs walkthrough which you may find useful:

  • Walkthrough: Printing a Local Report without Preview

To make it easier to use, I’ve created a Print extension method which you can easily use it this way:


Here is the extension method:

using Microsoft.Reporting.WinForms;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;

public static class LocalReportExtensions
    public static void Print(this LocalReport report)
        var 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 =
                <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>

        Warning[] warnings;
        var streams = new List<Stream>();
        var currentPageIndex = 0;

        report.Render("Image", deviceInfo, 
            (name, fileNameExtension, encoding, mimeType, willSeek) => 
                var stream = new MemoryStream();
                return stream;
            }, out warnings);

        foreach (Stream stream in streams)
            stream.Position = 0;

        if (streams == null || streams.Count == 0)
            throw new Exception("Error: no stream to print.");

        var printDocument = new PrintDocument();
        printDocument.DefaultPageSettings = pageSettings;
        if (!printDocument.PrinterSettings.IsValid)
            throw new Exception("Error: cannot find the default printer.");
            printDocument.PrintPage += (sender, e) =>
                Metafile pageImage = new Metafile(streams[currentPageIndex]);
                Rectangle adjustedRect = new Rectangle(
                    e.PageBounds.Left - (int)e.PageSettings.HardMarginX,
                    e.PageBounds.Top - (int)e.PageSettings.HardMarginY,
                e.Graphics.FillRectangle(Brushes.White, adjustedRect);
                e.Graphics.DrawImage(pageImage, adjustedRect);
                e.HasMorePages = (currentPageIndex < streams.Count);
                e.Graphics.DrawRectangle(Pens.Red, adjustedRect);
            printDocument.EndPrint += (Sender, e) =>
                if (streams != null)
                    foreach (Stream stream in streams)
                    streams = null;

Print with showing Print dialog

Just in case someone wants to print with showing Print dialog, you can put a ReportViewer on form and set the Visible property of the control to false then pass data to the report and when the RenderingComplete event fired, call PrintDialog:

  • ReportViewer.PrintDialog Method

Leave a Comment