Print RDLC Report without showing ReportViewer Control

后端 未结 1 1635
余生分开走
余生分开走 2020-12-04 02:36

I was wondering if is possible to send/print data from DataGridView directly to rdlc report without binding it to ReportViewercontrol.

Ther

相关标签:
1条回答
  • 2020-12-04 03:23

    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:

    this.reportViewer1.LocalReport.Print();
    

    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 =
                $@"<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 currentPageIndex = 0;
    
            report.Render("Image", deviceInfo, 
                (name, fileNameExtension, encoding, mimeType, willSeek) => 
                {
                    var 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("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.");
            else
            {
                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.PageBounds.Width,
                        e.PageBounds.Height);
                    e.Graphics.FillRectangle(Brushes.White, adjustedRect);
                    e.Graphics.DrawImage(pageImage, adjustedRect);
                    currentPageIndex++;
                    e.HasMorePages = (currentPageIndex < 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();
            }
        }
    }
    

    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
    0 讨论(0)
提交回复
热议问题