VB.NET - 打印 RDLC 报告而不显示 ReportViewer 控件

Posted

技术标签:

【中文标题】VB.NET - 打印 RDLC 报告而不显示 ReportViewer 控件【英文标题】:VB.NET - Print RDLC Report without showing ReportViewer control 【发布时间】:2021-05-17 15:16:34 【问题描述】:

我在 Reza Aghaei 的帮助下创建了一个 DLL

这是 C# 代码(我从Print RDLC Report without showing ReportViewer Control 获得):

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 * 100in</PageWidth>
                <PageHeight>pageSettings.PaperSize.Height * 100in</PageHeight>
                <MarginTop>pageSettings.Margins.Top * 100in</MarginTop>
                <MarginLeft>pageSettings.Margins.Left * 100in</MarginLeft>
                <MarginRight>pageSettings.Margins.Right * 100in</MarginRight>
                <MarginBottom>pageSettings.Margins.Bottom * 100in</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();
        
    

在 Reza Aghaei 提到的 C# 中,函数被调用

this.reportViewer1.LocalReport.Print();

我参考并尝试在 vb.net 中调用它

如果我尝试

this.reportViewer1.LocalReport.Print()

LocalReport.Print()

它给出了错误。

我缺少什么请提供帮助,或者如果专家可以在 Vb.net 中转换它,那将不胜感激。

我做的收据是这样的。

如果有专家帮助我解决这个问题,我将不胜感激,因为我主要在 VB.net 中工作。

【问题讨论】:

错误是什么?这是哪个版本的 C#? VB.NET 还是 C#?您的项目使用哪种语言? 先生,我正在为我的项目使用 Vb.net。如果我能得到它的 Dll 或 vb.net 转换代码来使用,那就太好了。 在 C# 中发现错误是因为“@”之前的“$”,所以我删除了它。我已经编辑了这个问题,如果它得到解决,将会有很大帮助。 我认为你应该导入 LocalReportExtensions 的命名空间。 This is 扩展方法在 c# 中的工作原理 【参考方案1】:

注意:我尝试的所有转换器都无法将链接帖子的 C# 代码转换为正确的 VB.NET 版本。您可以在链接的帖子中找到原始 C# 版本:Print RDLC Report without showing ReportViewer Control。

VB.NET - 打印 RDLC 报告而不显示 ReportViewer 控件

这是LocalReport的Print扩展方法的VB版:

Imports Microsoft.Reporting.WinForms
Imports System.Drawing.Imaging
Imports System.Drawing.Printing
Imports System.IO
Imports System.Runtime.CompilerServices

Public Module LocalReportExtensions
    <Extension()>
    Sub Print(ByVal report As LocalReport)
        Dim pageSettings = New PageSettings()
        pageSettings.PaperSize = report.GetDefaultPageSettings().PaperSize
        pageSettings.Landscape = report.GetDefaultPageSettings().IsLandscape
        pageSettings.Margins = report.GetDefaultPageSettings().Margins
        Print(report, pageSettings)
    End Sub

    <Extension()>
    Sub Print(ByVal report As LocalReport, ByVal pageSettings As PageSettings)
        Dim deviceInfo As String = $"<DeviceInfo>
                <OutputFormat>EMF</OutputFormat>
                <PageWidth>pageSettings.PaperSize.Width * 100in</PageWidth>
                <PageHeight>pageSettings.PaperSize.Height * 100in</PageHeight>
                <MarginTop>pageSettings.Margins.Top * 100in</MarginTop>
                <MarginLeft>pageSettings.Margins.Left * 100in</MarginLeft>
                <MarginRight>pageSettings.Margins.Right * 100in</MarginRight>
                <MarginBottom>pageSettings.Margins.Bottom * 100in</MarginBottom>
            </DeviceInfo>"
        Dim warnings() As Warning
        Dim streams = New List(Of Stream)()
        Dim currentPageIndex = 0
        report.Render("Image", deviceInfo,
                      Function(name, fileNameExtension, encoding, mimeType, willSeek)
                          Dim stream = New MemoryStream()
                          streams.Add(stream)
                          Return stream
                      End Function, warnings)

        For Each stream As Stream In streams
            stream.Position = 0
        Next

        If streams Is Nothing OrElse streams.Count = 0 Then
            Throw New Exception("Error: no stream to print.")
        End If

        Dim printDocument = New PrintDocument()
        printDocument.DefaultPageSettings = pageSettings

        If Not printDocument.PrinterSettings.IsValid Then
            Throw New Exception("Error: cannot find the default printer.")
        Else
            AddHandler printDocument.PrintPage,
                Sub(sender, e)
                    Dim pageImage As Metafile = New Metafile(streams(currentPageIndex))
                    Dim adjustedRect As Rectangle = New Rectangle(
                        e.PageBounds.Left - CInt(e.PageSettings.HardMarginX),
                        e.PageBounds.Top - CInt(e.PageSettings.HardMarginY),
                        e.PageBounds.Width,
                        e.PageBounds.Height)
                    e.Graphics.FillRectangle(Brushes.White, adjustedRect)
                    e.Graphics.DrawImage(pageImage, adjustedRect)
                    currentPageIndex += 1
                    e.HasMorePages = (currentPageIndex < streams.Count)
                    e.Graphics.DrawRectangle(Pens.Red, adjustedRect)
                End Sub

            AddHandler printDocument.EndPrint,
                Sub(Sender, e)
                    If streams IsNot Nothing Then
                        For Each stream As Stream In streams
                            stream.Close()
                        Next
                        streams = Nothing
                    End If
                End Sub

            printDocument.Print()
        End If
    End Sub
End Module

要使用上面的代码,在LocalReport 上调用Print 扩展方法就足够了。例如,如果您有一个(可见或不可见的 ReportViewer):

Me.ReportViewer1.LocalReport.Print()

如果你想通过打印机设置:

Me.ReportViewer1.LocalReport.Print(ReportViewer1.GetPageSettings())

【讨论】:

首先非常感谢您的帮助,我再次更新了问题,请检查。 我看到了您的更新,由于您是 C# 新手,我决定与您分享 VB.NET 版本。使用VB.NET版本代码,只需将模块复制到项目中的文件中并按照答案中的说明使用即可。 dll 方法(您尝试过的也可以),只需确保导入类的命名空间即可。扩展方法将在您导入其命名空间后对您的代码可见。 感谢所有帮助解决问题的人。事实证明,制作 Dll 并不是一个好的选择。只需上课并调用 me.reportviewer1.localreport.print()。

以上是关于VB.NET - 打印 RDLC 报告而不显示 ReportViewer 控件的主要内容,如果未能解决你的问题,请参考以下文章

在 Visual Studio 2010 的 vb.net 中创建钻取 rdlc 报告

VB.NET ReportViewer 动态绑RDLC

如何从 SQL Server Express 中的动态查询创建 RDLC 报告

使用 VB.NET 打印 MS Access 报告

在 RDLC 报告中隐藏一行而不禁用代码执行

在 C# winforms 中将 RDLC 报告适合 A4 页面