You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET手动设置数据源,无需Report Viewer控件直接打印RDLC报表

问题描述

我正尝试在VB.NET中从列表手动设置数据源,无需使用Report Viewer控件直接打印RDLC报表。以下是我编写的代码(可能存在不足),请各位给予指导,谢谢。

主窗体及实体类代码

Public Class Form1
    Private bindingSource As BindingSource = Nothing
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles BTNPRINT.Click
        Dim order = OrderBusiness.GetOrder()
        Dim localReport As New LocalReport()
        localReport.ReportPath = Application.StartupPath & "\Report1.rdlc"
        localReport.Print("Microsoft Print To PDF")
    End Sub
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        bindingSource = New BindingSource With {.DataSource = OrderBusiness.GetOrder.OrderDetails()}
        TextBox1.Text = OrderBusiness.GetOrder.CustomerName()
        DATAGRIDVIEW1.DataSource = bindingSource
    End Sub
End Class
Public Class Order
    Public Property CustomerName As String
    Public Property OrderDetails As List(Of OrderDetail)
End Class
Public Class OrderDetail
    Public Property ProductName As String
    Public Property UnitPrice As Integer
    Public Property Quantity As Integer
    Public Property Discount As Integer
End Class
Public Class OrderBusiness
    Public Shared Function GetOrder() As Order
        Return New Order() With {
                .CustomerName = "John Doe",
                .OrderDetails = New List(Of OrderDetail)() From {
                    New OrderDetail() With {
                        .ProductName = "Foo",
                        .UnitPrice = 100,
                        .Quantity = 1,
                        .Discount = 0
                    },
                    New OrderDetail() With {
                        .ProductName = "Bar",
                        .UnitPrice = 200,
                        .Quantity = 2,
                        .Discount = 50
                    },
                    New OrderDetail() With {
                        .ProductName = "Baz",
                        .UnitPrice = 50,
                        .Quantity = 3,
                        .Discount = 0
                    }
                }
            }
    End Function
End Class

报表数据集结果

报表数据集结果

LocalReport打印扩展模块代码

Public Module LocalReportExtensions
    <Extension()>
    Sub Print(ByVal report As LocalReport, ByVal printerName As String)
        Dim pageSettings = New PageSettings()
        pageSettings.PaperSize = report.GetDefaultPageSettings().PaperSize
        pageSettings.Landscape = report.GetDefaultPageSettings().IsLandscape
        pageSettings.Margins = report.GetDefaultPageSettings().Margins
        Print(report, pageSettings, printerName)
    End Sub
    <Extension()>
    Sub Print(ByVal report As LocalReport, ByVal pageSettings As PageSettings, ByVal printerName As String)
        Dim deviceInfo As String = $"<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>"


    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.PrintController = New StandardPrintController()
        printDocument.PrinterSettings.PrinterName = printerName
        printDocument.Print()
    End If
End Sub
End Module

内容的提问来源于stack exchange,提问作者user22579796

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 06:50:55