Dynamics CRM 2011编程系列(38):调用表格的神器(GhostHook)
Dynamics CRM 2011编程系列(38):调用报表的神器(GhostHook)
本文分享一个工具“GhostHook”,该工具可以彻底解决调用报表的问题。在使用它加载报表的时候,我们传递给报表的参数可以以Get的方式进行传递,“GhostHook”接受到参数后将模拟用户的输入和提交操作。
来看看“GhostHook”的用法吧:
操作步骤
图1
图2
图3
图4
图5
图6
图7
使用到的代码
GhostHook.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="GhostHook.aspx.cs" Inherits="GhostHook" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head id="Head1" runat="server"> <title>GhostHook</title> </head> <script language="javascript" type="text/javascript"> /* 作者:GhostBear 制作日期:2012年8月25日 博客地址:Http://blog.csdn.net/ghostbear 简介:接收服务器端传递过来的参数并模拟用户对报表进行输入提交操作。 */ document.onreadystatechange = oncomplete; function oncomplete() { if (document.readyState == "complete") { Go(); } } function Go() { var tmp = document.getElementById("report").contentWindow.document.getElementById("resultFrame").contentWindow.document.getElementsByTagName("input").length; if (tmp == 0) { setTimeout("Go()", 1000); } else { var paramPnl = document.getElementById("report").contentWindow.document.getElementById("resultFrame").contentWindow; var paramElements = new Array(); var inputElements = paramPnl.document.getElementsByTagName("input"); var ddlElements = paramPnl.document.getElementsByTagName("select"); var boolElements = paramPnl.document.getElementsByTagName("label"); var submitButton = paramPnl.document.getElementById("reportViewer_ctl04_ctl00"); var paramExp = /^reportViewer_ctl04_ctl(\d{2})_(txtValue|rbTrue|rbFalse|ddValue)$/; var paramValueString = "<%=ParameterValueString%>"; var paramValueArray = paramValueString.split(';'); var ddlButtonExp = /^reportViewer_ctl04_ctl\d{2}_ddDropDownButton$/; var ddlItemExp = "^reportViewer_ctl04_ctl($NUM$)_divDropDown_ctl\\d{2}$"; Parameter = function (pType, pDom, pNo) { this.ParameterType = pType; this.InputDom = pDom; this.ParameterNo = pNo; } //筛选输入类型为文本框的参数 for (var i in inputElements) { if (inputElements[i].id != undefined) { if (paramExp.test(inputElements[i].id)) { if (inputElements[i].nextSibling != null && ddlButtonExp.test(inputElements[i].nextSibling.id)) {//筛选下拉列表类型输入参数 var pNo = inputElements[i].id.match(paramExp)[1]; var curChkExp = new RegExp(ddlItemExp.replace("($NUM$)", pNo)); var curParams = new Array(); for (var j = 0; j < inputElements.length; j++) { if (inputElements[j].id != undefined && curChkExp.test(inputElements[j].id)) { curParams.push(inputElements[j]); } } var p = new Parameter("ddl", curParams, pNo); paramElements.push(p); } else {//筛选文本框类型输入参数 var pNo = inputElements[i].id.match(paramExp)[1]; var p = new Parameter("textbox", inputElements[i], pNo); paramElements.push(p); } } } } //筛选输入类型为布尔的参数 var tmpBoolArray = new Array(); for (var i = 0; i < boolElements.length; i++) { if (boolElements[i].htmlFor != undefined) { if (paramExp.test(boolElements[i].htmlFor)) { tmpBoolArray.push(boolElements[i].previousSibling); } } } tmpBoolArray.sort(function (n1, n2) { var no1 = parseInt(n1.id.match(paramExp)[1]); var no2 = parseInt(n2.id.match(paramExp)[1]); return no1 < no2; }); for (var i = 0; i < tmpBoolArray.length; i = i + 2) { var pNo = tmpBoolArray[i].id.match(paramExp)[1]; var p = new Parameter("bool", [tmpBoolArray[i], tmpBoolArray[i + 1]], pNo); paramElements.push(p); } //筛选输入类型为下拉列表的参数 for (var i = 0; i < ddlElements.length; i++) { if (ddlElements[i].id != undefined) { if (paramExp.test(ddlElements[i].id)) { var pNo = ddlElements[i].id.match(paramExp)[1]; var p = new Parameter("select", ddlElements[i], pNo) paramElements.push(p); } } } //为参数排序 var tmpElement; var tmpIndex for (var i = 0; i < paramElements.length; i++) { tmpIndex = i; for (var j = i + 1; j < paramElements.length; j++) { var n1 = paramElements[tmpIndex].ParameterNo; var n2 = paramElements[j].ParameterNo; if (n1 > n2) { tmpIndex = j; } } if (tmpIndex != i) { tmpElement = paramElements[i]; paramElements[i] = paramElements[tmpIndex]; paramElements[tmpIndex] = tmpElement; } } //模拟用户录入参数 for (var i = 0; i < paramElements.length; i++) { switch (paramElements[i].ParameterType) { case "textbox": paramElements[i].InputDom.value = paramValueArray[i]; break; case "bool": var selectedValue = eval(paramValueArray[i]); if (selectedValue) { if (paramElements[i].InputDom[0].id.match(/rbTrue/)) { paramElements[i].InputDom[0].checked = "checked"; } else { paramElements[i].InputDom[1].checked = "checked"; } } else { if (paramElements[i].InputDom[0].id.match(/rbFalse/)) { paramElements[i].InputDom[0].checked = "checked"; } else { paramElements[i].InputDom[1].checked = "checked"; } } break; case "select": var options = paramElements[i].InputDom.getElementsByTagName("option"); var selectedValue = paramValueArray[i]; for (var j = 0; j < options.length; j++) { if (options[j].innerText == selectedValue) { options[j].selected = "selected"; break; } } break; case "ddl": var chkItems = paramElements[i].InputDom; var selectedValue = paramValueArray[i].split(','); for (var k = 0; k < chkItems.length; k++) { for (var m = 0; m < selectedValue.length; m++) { if (chkItems[k].nextSibling.innerText == selectedValue[m]) { chkItems[k].checked = "checked"; chkItems[k].onclick(this); break; } } } break; default: break; } } //模拟用户提交操作 submitButton.click(); } } </script> <frameset> <frame rows="100%" cols="100%" name="report" id="report" src="../../test/crmreports/viewer/viewer.aspx?action=filter&helpID=<%=RDL_Name%>&id=<%=RDL_Id%>" ></frame> </frameset> </html>
GhostHook.aspx.cs
using System; using System.Collections; using System.Collections.Specialized; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Text.RegularExpressions; public partial class GhostHook : System.Web.UI.Page { protected string ParameterValueString; protected string RDL_Id = string.Empty; protected string RDL_Name = string.Empty; protected void Page_Load(object sender, EventArgs e) { Dictionary<string, string> paramTbl = new Dictionary<string, string>(); //参数的格式:ReportView.aspx?p1=123&p2=5678 foreach (string p in Request.QueryString.AllKeys) { if (p == "RDL_Id") { RDL_Id = Request.QueryString[p]; continue; } if (p == "RDL_Name") { RDL_Name = Request.QueryString[p]; continue; } paramTbl.Add(p, Request.QueryString[p]); } if (string.IsNullOrEmpty(RDL_Id) || string.IsNullOrEmpty(RDL_Name)) { Response.Clear(); Response.Write("需要提供参数“RDL_Id”和“RDL_Name”。"); } for (int i = 1; i <= paramTbl.Count; i++) { ParameterValueString += string.Format("{1}", "p" + i.ToString(), paramTbl["p" + i.ToString()]); if (i != paramTbl.Count) { ParameterValueString += ";"; } } } }
小结
GhostHook虽然比较强大,但还是有些小弊端:
1.受Get传参的影响,传递参数的大小有限制。(好像是2048个字符,不知道是不是?)
2.JavaScript脚本中的GO()函数是通过轮询的方式来运行的(setTimeout)。如果能将它挂在GhostHook.aspx中嵌入的frame页面的onreadystatechange中就完美了。(大家有没好的建议?)
资源下载
本章使用的报表
- 1楼orapple20113天前 09:53
- 真是太强悍了,没有做不到,只有想不到啊