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

跨浏览器 RDLC 打印

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2014年6月15日

CPOL

5分钟阅读

viewsIcon

20428

如何在 RDLC 查看器中为非 IE 浏览器创建打印按钮

引言

我一直在使用 Report Viewer,并遇到了一个与现代非 IE 浏览器中打印功能选项相关的问题。本文演示了如何解决此问题。

摘要

由于现代浏览器无法在 RDLC ReportViewer 工具栏上显示打印图标,因此我们需要首先使用 JavaScript 和 Jquery 将打印图标添加到工具栏。

此图标将指向负责打印方法的实际服务器按钮。当 ASP 按钮被间接点击时,它会转到服务器,创建一个报告的 PDF 版本,并将文件名返回到页面。然后,我们可以简单地将生成的 PDF 嵌入到 HTML 弹出窗口中。

这是我们将在此处展示内容的摘要。

添加打印图标按钮

首先,我们需要找出 RDLC 工具栏中是否存在打印按钮。如果我们确实找到了该按钮,那么我们很可能正在使用 Internet Explorer,因此无需执行任何操作,因为报表查看器已按预期呈现。

我们可以使用 jQuery 使用此选择器来选择该按钮

var $print = $('table[title="Print"]');

如果没有,我们应该动态创建一个客户端打印图标按钮。

如何创建一个与原始打印按钮外观完全相同的按钮?

答案非常简单,通过复制原始按钮的标记。

这是 RDLC 用于创建打印图标的内容

$print = $('<div class=" " style="display:inline-block;
font-family:Verdana;font-size:8pt;vertical-align:top;"><table title="Print">
<tbody><tr><td><input name="ReportViewer1$ctl05$ctl06$ctl00$ctl00$ctl00" 
title="Print" style="width: 16px; height: 16px;" type="image" 
alt="Print" src="/Reserved.ReportViewerWebControl.axd?
OpType=Resource&Version=11.0.3366.16&
Name=Microsoft.Reporting.WebForms.Icons.Print.gif"></td></tr></tbody>
</table></div>');

* 请注意,我们创建了一个 JavaScript 对象来表示标记。

必须将此图标添加到 RDLC 查看器工具栏,以下是如何在客户端找到工具栏对象

    var findtoolbar = function () {
        var $all = $('table div');
        for (var i = 0, len = $all.length; i < len; i++) {
            if ($($all[i]).css('background-image').toLowerCase().indexOf('toolbar_bk.png') != -1)
                return $($all[i]);
        }
        return null;
    }

如您所见,没有可靠的识别工具栏的方法,因此我们结合使用了某些属性(如背景图像)以及 DOM 中对象的顺序。

如果您碰巧找到了更具体地访问工具栏的方法,请随意使用它。

现在我们有了一个按钮,但它有什么作用?点击事件中我们可以说什么?

基本上,应该有一个服务器端方法可以处理打印操作,而这个方法正是我们将要分配给客户端按钮的点击事件的。

因此,下一步是创建一个服务器方法或其等效项,作为一个服务器按钮。

添加服务器端辅助按钮并将其附加到客户端图标按钮

在这里,我们在页面上添加了一个服务器端按钮。它的位置或外观无关紧要,因为它对最终用户是不可见的。

我们应该考虑的是如何区分我们的按钮与其他页面上的按钮或控件。

有几种方法可以做到这一点。最简单的方法是为按钮分配一个唯一的 ID,但这并不是一个非常简洁的方法,因为不能保证我们 Web 应用程序中的所有打印按钮都具有相同的 ID,并且通常为此类目的使用 ID 并非最佳实践。

更好的方法是使用特定的 data-attribute。您可以随意命名它,但请记住,该名称在整个项目中不应更改。

我们在其中使用的将是这个属性

data-report-action="chrome"

ASP.NET 按钮的标记将类似于这样

<asp:button data-report-action="chrome" runat="server" 
ID="btnChromePrint" text="Button" OnClick="ChromePrint_Click" />

在点击事件中,我们生成报告的 PDF 版本,但为什么是 PDF?

因为现代浏览器可以向最终用户显示嵌入式 PDF,并且可以轻松打印 PDF。

这是从 RDLC 报表对象生成 PDF 的典型代码

    protected void ChromePrint_Click(object sender, EventArgs e)
    {
        Warning[] warnings;
        string[] streamids;
        string mimeType;
        string encoding;
        string filenameExtension;

        byte[] bytes = ReportViewer1.LocalReport.Render(
            "PDF", null, out mimeType, out encoding, out filenameExtension,
            out streamids, out warnings);

        string filename = Guid.NewGuid().ToString() + ".pdf";

        string Path = Server.MapPath("~/Repository/");

        using (FileStream fs = new FileStream(Path + filename, FileMode.Create))
        {
            fs.Write(bytes, 0, bytes.Length);
        }
        btnChromePrint.Attributes.Add("data-report-filename", filename);
    }

上面的代码首先创建一个报表对象的 PDF 版本的字节流,然后实际将物理 PDF 文件保存在服务器上的某个路径中,最后将文件名存储在另一个名为 "data-report-filename" 的特定属性中。

现在,我们将把这个辅助按钮附加到我们之前创建的客户端图标按钮。

    var r = $('input[data-report-action=chrome]');//server-side button

        $print = $('<div class=" " style="display:inline-block;
        font-family:Verdana;font-size:8pt;vertical-align:top;">
        <table title="Print"><tbody><tr><td>
        <input name="ReportViewer1$ctl05$ctl06$ctl00$ctl00$ctl00" 
        title="Print" style="width: 16px; height: 16px;" 
        type="image" alt="Print" src="/Reserved.ReportViewerWebControl.axd?
        OpType=Resource&Version=11.0.3366.16&
        Name=Microsoft.Reporting.WebForms.Icons.Print.gif"></td></tr>
        </tbody></table></div>');//client-side print icon button
        $print.on('click', function () {
            r.show();
            r[0].click();
            r.hide();
        }); 

现在一切都已连接起来,准备工作了。

准备打印报表

在客户端页面加载时,我们检查 "data-report-filename" 属性,如果存在并且具有有效值,那么我们将查找 PDF 文件并将其嵌入到我们的 HTML 弹出模态框中。

因此,我们需要一个包含显示嵌入式 PDF 的所有内容的页面,以及一些代码来打开此页面,并在其中传递报表文件路径信息。

这几乎是模态页面的所有必要代码

<%@ Page Language="C#" AutoEventWireup="true" 
CodeFile="PrintForChrome.aspx.cs" Inherits="Reports_PrintForChrome" %>

<html >
<head id="Head1" runat="server">
    <title></title>
</head>
<body marginwidth="0" marginheight="0" style="background-color: rgb(38,38,38)">
    
    <embed width="100%" height="100%" name="plugin" 
    src="<%=thefilename %>" type="application/pdf" >

</body>
</html>

后台代码如下:

public partial class Reports_PrintForChrome : System.Web.UI.Page

{
    public string thefilename = "";
    protected void Page_Load(object sender, EventArgs e)
    {
        thefilename = "/repository/" + HttpUtility.HtmlDecode(Request["filename"].ToString());

    }
}

现在我们有了显示 PDF 的页面,让我们来看看如何以及何时调用它。

当页面在客户端浏览器中加载时,服务器按钮有两种可能的状态。它要么具有 "data-report-filename" 属性,要么不具有。

如果它具有该属性,那么我们有一个要显示的报表,我们需要加载模态页面以显示属性中记录的文件。

打开模态页面的代码如下

    if (r.attr('data-report-filename')) {
        window.open('/Reports/PrintForChrome.aspx?filename=' + escape
        (r.attr('data-report-filename')), "_blank", "width=650, height=400");
        r.removeAttr('data-report-filename');
    }

如果属性不存在,那么我们就按照上面章节所述构建一切。

搞定!报表无需引用 activex 对象或被迫使用 Internet Explorer 作为默认浏览器即可正常显示。

特别说明

此提示适用于 RDLC 报表版本 11.0。如果要将其用于其他版本,请根据您选择的特定版本所使用的标记代码来更改标记代码,以创建工具栏按钮。

© . All rights reserved.