ReportViewer控件功能扩展

最近在使用Report Service做报表,客户要求报表要以表格形式和图形形式显示,当时我想直接修改ReportViewer的工具栏。于是上网查了相关资料,发现这样方案不太可能,就算能够动态增加按钮,但是对于后台处理也比较麻烦,从通用性上考虑也不太乐观。

后来看到客户端的代码,如下:

ReportViewer发到客户端其实就是div加table。突然萌生了一种想法,就是通过js前台动态加按钮,然后回传给服务器处理。

实现效果图:

前台脚本使用的是jQuery,选择jQuery的原因有两个:一、使用起来简单;二、浏览器兼容性支持的好。

为了这段代码通用,开发人员用起来方便,利用了jQuery的($.extend())功能。

插件代码如下:

//ReportViewer控件增加工具按钮
(function() {
    $.extend($.fn,
            {
                methods: {
                    createButton: function(width, height, type, uri, controlId) {
                        var A = $("<a></a>");
                        A.attr("id", type + "_" + "graph");
                        A.attr("href", "###");
                        A.attr("uri", uri);
                        A.css("margin-left", "5px");
                        var img = $("<img />");
                        img.attr("src", "../img/" + type + ".png");
                        img.css("width", width);
                        img.css("height", height);
                        img.css("margin-top", "4px");
                        A.prepend(img);
                        A.click(function() {
                            $("input[id$='hid" + controlId + "']").val($(this).attr("uri"));
                            var lb = $("a[id$='lb" + controlId + "']");
                            __doPostBack(lb.attr("id").replace(/_/g, "$"),'');
                        });
                        return A;
                    }
                },
                ReportViewAddTool: function(options) {
                    options = $.extend({ width: 15, height: 15, url: { table: "###" }, controlId: "CallBack" }, options);
                    //按钮图片的宽度与高度
                    var width = options.width;
                    var height = options.height;
                    var url = options.url;
                    var controlId = options.controlId;
                    var toolbar = $(this).children("div").eq(0);
                    //创建图片按钮的div
                    var div = $("<div id='divRVT'></div>");
                    div.css({ "display": "inline", "font-family": "Verdana", "height": "30px", "font-size": "8pt" });
                    $.each(url, function(k, v) {
                        div.prepend($.fn.methods.createButton(width, height, k, v, controlId));
                    });
                    toolbar.children("div").eq(0).append(div);
                }

            }
    );
})(jQuery);

客户端实例代码:

<script type="text/javascript">
        $(function() {
            $(".reportTool").ReportViewAddTool({ url: { table: "SettleSheetRecycleStatistic", column: "SettleSheetRecycleStatisticGraph"} });
        });
</script>
<div class="divReportV">
        <rsweb:ReportViewer ID="rvPayPlan" runat="server" Width="1000px" Height="390px" Visible="true"
            CssClass="reportTool">
        </rsweb:ReportViewer>   
    <asp:HiddenField ID="hidCallBack" runat="server" />
        <asp:LinkButton ID="lbCallBack" runat="server" OnClick="lbCallBack_Click"></asp:LinkButton>     
</div>

报表实现的核心思想就是aspx页面通过ReportViewer控件去请求不同的rdl报表文件去显示不同的报表,这些报表可以是图形报表或表格报表。

见上代码核心的方法就两个ReportViewAddTool和createButton,ReportViewAddTool方法是提供给用户使用的接口,createButton是内部用来创建按钮的。

createButton: function(width, height, type, uri, controlId)

width:图片按钮的宽度

height:图片按钮的高度

type:报表类型(表格、柱状图、饼状图、线状态等等)

uri:每种报表类型对应的rdl文件名

controlId:回发控件的Id

这个方法实现细节主要是图片、A标签的构建。当时在实现的时候遇到了一个头疼的问题,就是A.Click事件回传服务器的时候,那个服务器端控件(LinkButton)触发不了,一般通过js提交是通过__doPostBack方法。因为在实际项目中,我们做的页面不是简单的页面,有可能是有模板页,有可能是用户控件等等。所以有些控件的ID发到客户端会改变。

A.click(function() {
                            $("input[id$='hid" + controlId + "']").val($(this).attr("uri"));
                            var lb = $("a[id$='lb" + controlId + "']");
                            __doPostBack(lb.attr("id").replace(/_/g, "$"),'');
});

上面代码就是解决父子控件问题的,解决的思想就是:不管它的id怎么变,它们都是以最初的id为结尾的。通过jQuery强大的选择器很容易就可以找到元素。

细心的朋友会发现lb.attr("id").replace(/_/g, "$")这段代码,功能是将客户端的id中的”_”符号替换成”$”字符。这段代码很重要,要不然服务器端方法触发不了(控件存在于父控件中)。

下面谈谈提供给用户的接口:

ReportViewAddTool: function(options) {
                    options = $.extend({ width: 15, height: 15, url: { table: "###" }, controlId: "CallBack" }, options);
}

调用方法

 $(".reportTool").ReportViewAddTool({ url: { table: "SettleSheetRecycleStatistic", column: "SettleSheetRecycleStatisticGraph"} });

这边为了简单起见只生成了表格类型的按钮(table)和状图案类型的按钮(column)。

引号里的内容是rdl文件名(回发时请求不同的报表内容)

 

 

在页面设计中,另外需要使用两个控件:隐藏域控件(用于保存rdl文件名,供服务器端处理使用)和LinkButton控件(担任Handler角色,处理用户请求)

<asp:HiddenField ID="hidCallBack" runat="server" />
        <asp:LinkButton ID="lbCallBack" runat="server" OnClick="lbCallBack_Click"></asp:LinkButton>  

隐藏控件为了保存rdl文件名,LinkButton用于触发后台方法。

实现效果图:

图1:

图2:

posted on 2012-09-20 11:38  Gates.Li  阅读(2393)  评论(3编辑  收藏  举报

导航