跨浏览器 RDLC 打印





5.00/5 (2投票s)
如何在 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。如果要将其用于其他版本,请根据您选择的特定版本所使用的标记代码来更改标记代码,以创建工具栏按钮。