【问题标题】:Printing ServerReport without Preview打印不带预览的 ServerReport
【发布时间】:2010-10-15 11:52:47
【问题描述】:

我通过 ReportViewer 控件部署了一个 SQLServer 2005 Reporting Services ServerReport,并经常被我的 Winforms 应用程序(Framework 2.0)使用。

我需要的是从应用程序的一种形式中提供一键式打印按钮,该按钮仅触发打印对话框,而不启动 ReportViewer。

我一直在尝试将报告呈现为字节数组,但无法通过。

此报告有多个页面,所以我不知道适用于本地报告的“图像”渲染是否也适用于服务器报告。

我一直在寻找抛出 MSDN,但仅参考本地报告:

http://msdn.microsoft.com/en-us/library/ms252091(VS.80).aspx

我可以在服务器端报告中获得的少量信息是使用对 ReportServer Web 服务的 Web 引用,我不希望这样。

http://blogs.msdn.com/bryanke/articles/71491.aspx

有没有办法使用打印对话框打印服务器报告,而不向用户显示报告查看器(我不介意它是否在幕后)?

【问题讨论】:

    标签: .net sql-server reporting-services printing


    【解决方案1】:

    好的,终于想通了。

    该博客文章几乎包含了我需要的所有内容,但我将在此处发布完整答案以供参考。

    我最终在幕后使用了报表查看器对象,但这只是为了方便,因为它不是必需的。

    第一步是询问用户打印机设置:

    Dim doc As New Printing.PrintDocument()
    AddHandler doc.PrintPage, AddressOf PrintPageHandler
    Dim dialog As New PrintDialog()
    dialog.Document = doc
    Dim print As DialogResult
    print = dialog.ShowDialog()
    doc.PrinterSettings = dialog.PrinterSettings
    

    有了这些,我们继续配置我们的报告调用: 修改此字符串,您可以在任何纸张大小和任何方向上进行打印(横向切换高度和宽度),但报表本身必须配置在相同的页面布局中。

    Dim deviceInfo As String = _
    "<DeviceInfo>" + _
    "<OutputFormat>emf</OutputFormat>" + _
    "  <PageWidth>8.5in</PageWidth>" + _
    "  <PageHeight>11in</PageHeight>" + _
    "  <MarginTop>0.25in</MarginTop>" + _
    "  <MarginLeft>0.25in</MarginLeft>" + _
    "  <MarginRight>0.25in</MarginRight>" + _
    "  <MarginBottom>0.25in</MarginBottom>" + _
    "</DeviceInfo>"
    
    Dim warnings() As Warning
    Dim streamids() As String
    Dim mimeType, encoding, filenameExtension, path As String
    mimeType = "" : encoding = "" : filenameExtension = ""
    

    最后,我们呈现报告及其所有页面。

    请注意,如果报表只有一页,则从不使用 renderStream 方法。

    rpt_control 是报表查看器控件,之前配置并针对服务器报表。

    请注意,在这段代码中,我们将页面添加到列表中。这个列表是一个全局变量,因为在 PrintPageHandler 方法中需要它。

    Dim data() As Byte
    rpt_control.ServerReport.SetParameters(_parametros)
    data = rpt_control.ServerReport.Render("Image", deviceInfo, mimeType, encoding, filenameExtension, streamids, warnings)
    pages.Add(New Metafile(New MemoryStream(data)))
    
    For Each pageName As String In streamids
        data = rpt_control.ServerReport.RenderStream("Image", pageName, deviceInfo, mimeType, encoding)
        pages.Add(New Metafile(New MemoryStream(data)))
    Next
    doc.Print()
    

    到目前为止,我们还没有进行任何打印,这实际上是由我们之前引用的 PrintPageHandler 方法处理的。

    Dim pages As New List(Of Metafile)
    Dim pageIndex As Integer = 0
    Private Sub PrintPageHandler(ByVal sender As Object, ByVal e As PrintPageEventArgs)
        Dim page As Metafile = pages(pageIndex)
        pageIndex += 1
        e.Graphics.DrawImage(page, 0, 0, page.Width, page.Height)
        e.HasMorePages = pageIndex < pages.Count
    End Sub
    

    【讨论】:

    • 这里的代码帮助我摆脱了我在尝试从 SSRS 设置批量打印时的常规。所以向你致敬。是的,我知道你发布这个帖子已经过去了一段时间!
    【解决方案2】:

    对上面大卫给出的答案的2个警告:-

    1) 在 SQL2005 上返回流标签的顺序通常是从第二页到最后一页,但是在负载很重的机器上(例如生产环境),它们很可能以任意顺序返回。

    流 id 采用 _nn 的形式,其中 nn 是一个数字。这使得排序有点棘手,因为报告名称将是字母并且数字只是简短的形式,因此页面“myreport_2”将在页面“myreport_10”之后排序。导致我的第二个警告

    2) 在 SQL 2005 上,报告后缀从 2 开始,在 SQL 2008 上,它们从 1 开始(对于第 2 页)

    【讨论】:

    • 哦,感谢您的洞察力。到目前为止,我还没有看到流以任意顺序出现的情况......但我将对此进行测试,因为这可能是一个问题。不是很大,因为所有页面都将在最后呈现,但谁知道会有什么影响。
    【解决方案3】:

    尝试将此代码用于 SQL Server 2008 R2 的人会发现它只打印多页报告的第一页。有一个新的“行为”,其中返回到 streamids 的数组是空的。请在此处让 Microsoft 知道您的关心:

    https://connect.microsoft.com/SQLServer/feedback/details/573997/with-ssrs-2008-r2-microsoft-reporting-winforms-serverreport-render-method-returns-no-stream-identifiers-for-image-format#

    【讨论】:

    • 我们上周末刚刚升级到 SQL 2008 R2,直到现在我才看到这个答案。在进一步阅读之前,我花了半天时间把头发扯下来。随后,我也让 MS 知道我在乎。
    【解决方案4】:

    我看到了这个示例,但不知道它是否适合您的需求:http://www.gotreportviewer.com/EMFPrint.zip

    【讨论】:

    • 是的,这几乎是我得到的第一个提示,但请注意,此示例适用于本地报告,而不是远程报告。在服务器报告中没有创建页面的回调,这是我的问题,整理如何发送所有页面。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多