SharePoint 报表查看器页面技巧






4.93/5 (10投票s)
在 SharePoint 中查看 Microsoft 报表服务报表的另一种方法。
引言
本文介绍了一种在 SharePoint 中查看 Microsoft 报表服务报表的替代方法。它实际上包含了我为实现客户的几项请求而对 SharePoint 原生报表查看器页面进行的一系列技巧。这适用于 SharePoint Server 2007 和 SQL Reporting Services 2005(当然是在 SharePoint 集成模式下)。以下是它们列表:
- 它接受报表参数的 URL 参数。
- 报表本身作为 URL 参数传递。
- 它使用
default.master
页面。 - 钻取报表在新窗口中打开,而不是在同一浏览器窗口中。
- 为报表项的编辑下拉菜单添加了一个新条目,以便在新页面中打开报表。
为什么?
您可能会想,为什么我们需要这个,为什么原生的 SharePoint 报表查看器页面 RSViewerPage.aspx 不够用。
我将逐一介绍新技巧/功能。
- 接受报表的 URL 参数 - 当您想创建一个包含参数的报表链接时,此功能非常有用。您可能希望此链接位于快速启动导航中,或者位于文档中。没有此技巧,您将不得不构建一个特定于此报表的页面,并添加一堆 URL 字符串筛选器 Web 部件,然后需要将它们连接到报表。
- 报表本身作为参数传递 - 这是为了实现与第一个技巧相同的目标。如果无法将报表作为参数传递,我们将不得不为此构建一个页面。
- 它使用
default.master
- 这是为了在不为我要创建链接的每个报表构建页面即可在带有左侧和顶部导航的合适页面中显示报表。这并不是一个很大的增强功能。您实际上可以创建自己的母版页并使用它。 - 钻取报表在新窗口中打开,而不是在同一浏览器窗口中 - 我的客户一直要求这样做。如果我为他们实现了至少两个报表,他们就会要求我将钻取报表在新窗口中打开。
- 为报表项的编辑下拉菜单添加了一个新条目,以便在新页面中打开报表 - 这并非真正的技巧。我只是添加了一个选项,可以在此项目中看到包含新页面的报表。
要使其正常工作,基本要求是已安装报表服务并与您的 SharePoint 站点正常配合。报表服务需要处于集成模式。
我知道大多数人都渴望尝试一下,而不是关心我在代码后台做了什么聪明的操作。所以,这里是。
如何安装
这将作为 SharePoint 包解决方案安装。以下是命令行:
stsadm -o addSolution -filename DataQ.SharePoint.RSViewer.wsp
stsadm -o deploySolution -name DataQ.SharePoint.RSViewer.wsp
-immediate -allowgacdeployment
stsadm -o execadmsvcjobs
stsadm -o activatefeature -name DataQ.RS -url http://yoursite
将 yoursite
替换为您的站点。您会在 ../DeploymentFiles/ 文件夹中找到 WSP 包。或者,您可以转到中央管理 -> 操作并在此处上传解决方案。安装后,您应该会有一个名为 DataQ: Reporting Services Viewer Page 的新功能,位于网站集级别。

如何使用它
该程序包安装了一个报表查看器页面:~site/_layouts/DataQ.RS/RSViewer.aspx。它可用于网站集中的所有网站。
如您在此屏幕截图中看到的,可以通过报表项下拉菜单(编辑控件按钮或 RCB)访问此页面。

拥有此页面的真正好处是通过 URL 创建带有参数的报表链接。这是访问此类报表的语法。
http://yoursite/_layouts/DataQ.RS/RSViewer.aspx?
report=/reports/YourReport.rdl&p_Parameter=10
这些是规则:
- 您必须通过
report
参数指定报表。它应该是报表的绝对路径。 - 您必须通过一个带有
p_
前缀的 URL 参数来传递每个报表参数。我添加了这个p_
前缀,因为必须有一些东西表明我正在处理报表参数。稍后您将在代码注释中看到。
关于如何安装和使用它,您只需要知道这些。下一部分是为那些想知道代码内容或希望修改代码的人准备的。
代码解析
RSViewer.aspx 实际上是一个 SharePoint 应用程序页面,它使用 default.master
并将 sqlviewer Web 部件作为用户控件嵌入。原生的报表服务查看器页面实际上不使用母版页。是的,您可以使用 Web 部件作为用户控件。
报表可以通过 URL 参数作为 RDL 的相对路径传递,或者通过 ListID
、ItemID
参数对传递。这是代码顺序:
if (!Page.IsPostBack)
{
SPWeb web = SPContext.Current.Web;
SPList list;
SPListItem report = null;
if (Request["ItemId"] != null && Request["ListId"] != null)
{
list = web.Lists[new Guid(Request["ListId"].ToString())];
if (list != null)
{
report = list.Items.GetItemById(Convert.ToInt32(Request["ItemId"]));
}
}
else if (Request["report"] != null)
{
report = web.GetListItem(Request["report"].ToString());
}
if (report != null)
{
//set the window title
LiteralPageTitle.Text = report.Title;
//set the title in the page
LabelPageTitleInTitleArea.Text = report.Title;
//set the path to the report
m_sqlRsWebPart.ReportPath =
SPContext.Current.Site.MakeFullUrl(report.File.ServerRelativeUrl);
ReportParameterDefaultCollection
parameters; // = new ReportParameterDefaultCollection();
parameters = m_sqlRsWebPart.OverrideParameters;
foreach (string urlParam in Request.QueryString.AllKeys)
{
//we have to prefix report params with something so we know
//they are report parameters, and they are
//destined to be passed to the report
if (urlParam != null && urlParam.StartsWith("p_"))
{
string paramName = urlParam.Substring(2);
string paramValue = Request[urlParam].ToString();
Microsoft.Reporting.WebForms.ReportParameter p =
new Microsoft.Reporting.WebForms.ReportParameter(paramName, paramValue);
parameters.Add(p);
}
} //foreach (string urlParam in Request.QueryString.AllKeys)
} //if (report != null)
} //if (!Page.IsPostBack)
第一件重要的事情是正确设置 m_sqlRsWebPart.ReportPath
到报表文档。第二件事是覆盖 m_sqlRsWebPart.OverrideParameters
集合,以防您通过 URL 传递任何参数。我通过添加 p_
前缀来选择如何确定哪个 URL 参数是报表参数。另一种方法是查询报表服务的 Web 服务以获取此报表的可用参数,并检查它们是否存在于 URL 中。我在这里没有这样做。我希望保持简单。
此应用程序页面引入的另一项功能是将所有钻取报表在新窗口中打开。这不是一个微不足道的更改:它无法通过 HyperlinkTarget
来实现。原因是所有指向钻取报表的链接实际上都是 POST 调用。我的解决方案是使用一个 JavaScript 序列,该序列会更改 RSViewer.aspx 页面的 FORM
标签的 target
属性。
<script type="text/javascript" language="javascript">
function ChangeTarget() {
document.getElementById("aspnetForm").target = "_self";
try {
//this is first argument of function ControllerActionHandler
//(actionType, actionParam)
//if is Drillthrough then should make the target = _blank
var c = arguments.callee.caller.caller.arguments[0];
if (c == "Drillthrough") {
//needed for SP, see OWS.JS , definition of _spFormOnSubmitWrapper()
_spSuppressFormOnSubmitWrapper = true;
document.getElementById("aspnetForm").target = "_blank";
}
}
catch (err) {
};
return _spFormOnSubmitWrapper();
}
/*
...
*/
document.getElementById("aspnetForm").onsubmit = ChangeTarget;
/*
...
*/
</script>
这里的技巧是将表单提交的目标从 _self
更改为 _blank
,但仅当用户单击 drillthrough 类型的链接时。我通过检查 arguments.callee.caller.caller.arguments[0]
来做到这一点,它必须评估为 Drillthrough(我知道……这很复杂,经过了大量的试错)。最后,我用我的函数重写了 onsubmit
主体页面事件,这样它会在用户提交任何内容时执行,例如当他单击 drillthrough 时。我在这里重复了吗?请注意,我仍然调用 SharePoint 的原始函数 _spFormOnSubmitWrapper()
,该函数用于 onsubmit
事件,因此我不会干扰 SharePoint 本身执行的任何其他原生操作。
结论
结论是,如果我们等不及下一个版本,我们可以自由地破解 SharePoint。我在本文中包含了一些针对 SQL Reporting Services 报表查看器页面在 SharePoint 中发现的一些小问题的解决方案。希望这对您有帮助。
历史
- 2009 年 9 月 22 日:发布