65.9K
CodeProject 正在变化。 阅读更多。
Home

为 Microsoft Report (RDLC) 直接打印

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (4投票s)

2014年7月16日

CPOL
viewsIcon

75391

为 Microsoft Report (RDLC) 直接打印,无需预览

引言

我过去使用 Crystal Report,当我转向 Microsoft Report 时,发现了一些我找不到的功能(比如“print_to_printer”函数)。在 Google 上搜索后,我在 MSDN 上找到了这个。它确实完成了任务(将 RDLC 渲染为图像,然后使用默认纸张设置发送到默认打印机),但不幸的是,没有打印选项 :(。

添加打印选项花了我一些时间,希望这能帮助你节省时间。

使用代码

这是一个 VB.NET 模块,主要的公共方法是 “print_microsoft_report”。

它有两个重载(都带有可选参数),第一个方法是使用自定义纸张宽度和高度打印报告,第二个方法是使用特定纸张类型打印 RDLC 报告。

(paper_kind、printer_name 和 paper_landscap) 都是可选参数。

最后要说明的是,我将所有页边距都设置为 0(可以根据需要轻松编辑)。

Imports System
Imports System.IO
Imports System.Data
Imports System.Text
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Drawing.Printing
Imports System.Collections.Generic
Imports System.Windows.Forms
Imports Microsoft.Reporting.WinForms
Module modul_print_reports
    Private m_currentPageIndex As Integer
    Private m_streams As IList(Of Stream)
    Private printdoc As PrintDocument

    ''' <summary>
    ''' Print rdlc report with custom page width and height
    ''' </summary>
    ''' <param name="report"></param>
    ''' <param name="page_width">the width of the papger, in hunderdths of an inch</param>
    ''' <param name="page_height">the height of the papger, in hunderdths of an inch</param>
    ''' <param name="islandscap"></param>
    ''' <param name="printer_name">Ignore this parameter to use default printer</param>
    ''' <remarks></remarks>
    Public Sub print_microsoft_report(ByRef report As LocalReport, ByVal page_width As Integer, ByVal page_height As Integer, _
                                      Optional ByVal islandscap As Boolean = False, _
                                      Optional ByVal printer_name As String = Nothing)
        printdoc = New PrintDocument()
        If printer_name <> Nothing Then printdoc.PrinterSettings.PrinterName = printer_name
        If Not printdoc.PrinterSettings.IsValid Then ' detecate is the printer is exist
            Throw New Exception("Cannot find the specified printer")
        Else
            Dim ps As New PaperSize("Custom", page_width, page_height)
            printdoc.DefaultPageSettings.PaperSize = ps
            printdoc.DefaultPageSettings.Landscape = islandscap
            Export(report)
            Print()
        End If
    End Sub
    ''' <summary>
    ''' Print rdlc report with specific paper kind
    ''' </summary>
    ''' <param name="report"></param>
    ''' <param name="paperkind">String paper Kind, ex:"letter"</param>
    ''' <param name="islandscap"></param>
    ''' <param name="printer_name">Ignore this parameter to use default printer</param>
    ''' <remarks></remarks>
    Public Sub print_microsoft_report(ByVal report As LocalReport, Optional ByVal paperkind As String = "A4", _
                                      Optional ByVal islandscap As Boolean = False, _
                                      Optional ByVal printer_name As String = Nothing)

        printdoc = New PrintDocument()
        If printer_name <> Nothing Then printdoc.PrinterSettings.PrinterName = printer_name
        If Not printdoc.PrinterSettings.IsValid Then ' detecate is the printer is exist
            Throw New Exception("Cannot find the specified printer")
        Else
            Dim ps As PaperSize
            Dim pagekind_found As Boolean = False
            For i = 0 To printdoc.PrinterSettings.PaperSizes.Count - 1
                If printdoc.PrinterSettings.PaperSizes.Item(i).Kind.ToString = paperkind Then
                    ps = printdoc.PrinterSettings.PaperSizes.Item(i)
                    printdoc.DefaultPageSettings.PaperSize = ps
                    pagekind_found = True
                End If
            Next
            If Not pagekind_found Then Throw New Exception("paper size is invalid")
            printdoc.DefaultPageSettings.Landscape = islandscap
            Export(report)
            Print()
        End If

    End Sub

    ' Routine to provide to the report renderer, in order to
    ' save an image for each page of the report.
    Private Function CreateStream(ByVal name As String, ByVal fileNameExtension As String, ByVal encoding As Encoding, ByVal mimeType As String, ByVal willSeek As Boolean) As Stream
        Dim stream As Stream = New MemoryStream()
        m_streams.Add(stream)
        Return stream
    End Function
    ' Export the given report as an EMF (Enhanced Metafile) file.
    Private Sub Export(ByVal report As LocalReport)
        Dim w As Integer
        Dim h As Integer
        If printdoc.DefaultPageSettings.Landscape = True Then
            w = printdoc.DefaultPageSettings.PaperSize.Height
            h = printdoc.DefaultPageSettings.PaperSize.Width
        Else
            w = printdoc.DefaultPageSettings.PaperSize.Width
            h = printdoc.DefaultPageSettings.PaperSize.Height
        End If
        Dim deviceInfo As String = "<DeviceInfo>" & _
            "<OutputFormat>EMF</OutputFormat>" & _
            "<PageWidth>" & w / 100 & "in</PageWidth>" & _
            "<PageHeight>" & h / 100 & "in</PageHeight>" & _
            "<MarginTop>0.0in</MarginTop>" & _
            "<MarginLeft>0.0in</MarginLeft>" & _
            "<MarginRight>0.0in</MarginRight>" & _
            "<MarginBottom>0.0in</MarginBottom>" & _
            "</DeviceInfo>"
        Dim warnings As Warning()
        m_streams = New List(Of Stream)()
        report.Render("Image", deviceInfo, AddressOf CreateStream, warnings)
        For Each stream As Stream In m_streams
            stream.Position = 0
        Next
    End Sub

    ' Handler for PrintPageEvents
    Private Sub PrintPage(ByVal sender As Object, ByVal ev As PrintPageEventArgs)
        Dim pageImage As New Metafile(m_streams(m_currentPageIndex))

        ' Adjust rectangular area with printer margins.
        Dim adjustedRect As New Rectangle(ev.PageBounds.Left - CInt(ev.PageSettings.HardMarginX),
                                          ev.PageBounds.Top - CInt(ev.PageSettings.HardMarginY), _
                                          ev.PageBounds.Width, _
                                          ev.PageBounds.Height)

        ' Draw a white background for the report
        ev.Graphics.FillRectangle(Brushes.White, adjustedRect)

        ' Draw the report content
        ev.Graphics.DrawImage(pageImage, adjustedRect)

        ' Prepare for the next page. Make sure we haven't hit the end.
        m_currentPageIndex += 1
        ev.HasMorePages = (m_currentPageIndex < m_streams.Count)
    End Sub
    Private Sub Print()
        If m_streams Is Nothing OrElse m_streams.Count = 0 Then
            Throw New Exception("Error: no stream to print.")
        End If
        AddHandler printdoc.PrintPage, AddressOf PrintPage
        m_currentPageIndex = 0
        printdoc.Print()
    End Sub
End Module
© . All rights reserved.