【问题标题】:Print RDLC Report without showing ReportViewer Control打印 RDLC 报告而不显示 ReportViewer 控件
【发布时间】:2016-04-16 02:04:57
【问题描述】:

我想知道是否可以将来自DataGridView 的数据直接发送/打印到rdlc 报告而不将其绑定到ReportViewercontrol。

有很多关于将 dgv 数据绑定到报表查看器控件的线程。 我不想使用报表查看器控件创建另一个表单,而是使用现有表单和DataGridView 上的数据和打印按钮将数据发送到RDLC 报表并打印。

有可能吗?
谢谢

【问题讨论】:

  • 那是文件打印而不是.rdlc。谢谢,但我不需要那个!
  • 我需要这样的东西:stackoverflow.com/questions/3360326/…,但不使用报表查看器控件。有可能吗?
  • 您似乎没有阅读文章和代码。 本演练展示了如何使用 LocalReport 对象和 CreateStreamCallback 回调函数以编程方式打印报表而不查看它。
  • 作为另一个选项,您可以将ReportViewer 控件的Visibleproperty 设置为false,然后将其设置为加载报告,当报告完全加载时(在报告查看器中)不可见,调用报表查看器的PrintDialog()方法。

标签: c# winforms report rdlc


【解决方案1】:

您可以使用LocalReport 对象和CreateStreamCallback 回调函数以编程方式打印RDLC 报告。这是一个完整的 Microsoft 文档演练,您可能会发现它很有用:

为了使其更易于使用,我创建了一个Print extension method,您可以通过这种方式轻松使用它:

this.reportViewer1.LocalReport.Print();

扩展方法如下:

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();
        }
    }
}

打印并显示打印对话框

以防万一有人想通过显示“打印”对话框进行打印,您可以在表单上放置 ReportViewer 并将控件的 Visible 属性设置为 false,然后将数据传递给报表,并在 RenderingComplete 事件触发时, 拨打PrintDialog:

【讨论】:

  • 我在表单中添加了不可见的 CrystalReportViewer,并调用了 PrintReport() 方法来打开打印对话框。这就是我需要的。非常感谢礼萨!!
  • 未来的读者可能会发现这篇文章很有用:Loading .rdlc report in Reportviewer manually
  • 谢谢礼萨。隐形的把戏真的很巧妙。另一方面,扩展方法完全是另外一回事。
  • 这很好用。谢谢!任务栏中会出现一个窗口一秒钟。有谁知道我该如何避免这种情况?
  • 嘿,Rezan 先生,FoxLearn 从你那里偷了这个解决方案 youtube.com/watch?v=uiTTgwoticY&t=152s