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:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM