最近,为了完成公司的业务要求,除了使用ReportService开发普通的rdl报表,和使用VS2010自带的报表开发工具开发rdlc报表外,还需要使用OWC+AnalysisService来满足一些客户的特殊需求,特别是需要使用OWC的PivotTable和ChartSpace开发,于是我在最近查阅了很多的网上的资料,整理出了一套基于:OWC+AnalysisService+Asp.net4.0构建OLAP应用解决方案,希望Share在这里与有这方面兴趣的程序猿们共享。(其中还有不足之处,希望多多指教)。
要想正确的使用该解决方案,需要处理好以下几方面。
一、AnalysisServices的配置
首先先说一下我是用的开发工具:Asp.net的开发使用的是VS2010,数据库使用的是SqlServer2008 R2,AnalysisServices使用的是SqlServer2008 R2自带的BI开发工具:SQL Server Bussiness Intelligence Development Studio。
1.配置步骤如下:打开SQL Server Bussiness Intelligence Development Studio:
2.选择文件->新建->新建项目:选择Analysis Services项目:
这时就会在解决方案资源管理器里边出现以下文件:
3.然后依次:新建数据源,新建视图,新建多维数据集……(此处不再详细介绍)关于Analysis Services的相关使用知识,请参阅MSDN:Analysis Services 向导。
好了,现在就把Analysis Services 建好了 :
接下来,右键点击AnalysisServicesTestProject,点击部署即可,部署成功后,就可以做接下来的步骤了。
二、VS2010中开发Asp.net代码
打开VS2010,新建我们的OLAP的Web部分了,在VS2010下新建如下的解决方案:AnalysisServices,解决方案下边依次有Application,Common,Service等几个项目文件,当然,这里不一定必要这样子,你可以根据自己的实际需要创建项目,我这里只是一个简单的Demo。
其中Model层主要创建的是一些实体类,ServiceImp层主要实现的数据的访问,这里边又分为数据访问层Persistence和业务逻辑层Provider:
其中Config文件夹里边是一个连接字符串的实体类。Analysis Services的连接字符串如下:
public static readonly string AnalysisServicesConn = "Datasource=localhost;Initial Catalog=AnalysisServicesTestProject";//注意是多维数据集
好了,现在就可以进行Analysis Services的数据访问了,在这里我要讲述一下AnalysisServices的一个专用的数据访问动态链接库ADOMD.NET,参考(
ADOMD.NET 客户端编程)你可以添加引用到你的VS项目。
应用文件位置:C:\Program Files (x86)\Microsoft.NET\ADOMD.NET\100\Microsoft.AnalysisServices.AdomdClient.dll。
现在就可以编写你的数据访问程序了,为了做一个示例,下面我简单的写了一个,写的很粗糙,仅供参考:
///
/// 获取AdminUser信息
///
///
public static CellSet GetAdminUserCellSetMsg()
{
string sql = @"select [BI Admin User].[User Name].children on columns,{[BI Admin User].[User Real Name].children} on rows from [BI Report Center]";
AdomdConnection conn = new AdomdConnection(AnalysisServicesConfig.AnalysisServicesHttpConn2);
try
{
conn.Open();
AdomdCommand comm = new AdomdCommand(sql, conn);
CellSet cs = comm.ExecuteCellSet();
return cs;
}
catch (Exception e)
{
throw e;
}
finally
{
conn.Close();
}
}
三、前端PivotTable的开发介绍:
PivotTable是一个客户端数据钻取控件。你需要在你的前端页面里边写上这样的一段代码:
客户端代码实现:
Asp.net后台代码:首先需要引用OWC11
引用:Microsoft Office Web Components 11.0
DLL文件(引用文件)位置:C:\Windows\assembly\GAC\Microsoft.Office.Interop.Owc11\11.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Owc11.dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Beisen.BIReportCenter.Model;
using System.Data;
using Beisen.AnalysisServices.Utility;
using System.IO;
using System.Xml;
using System.Text;
using System.Text.RegularExpressions;
using Microsoft.Office.Interop;
using AnalysisServices.Model.CustomEntity;
namespace AnalysisServices.UI.Admin
{
public partial class PivotTableExample : System.Web.UI.Page
{
private string _xml;
public string xml
{
get{return _xml;}
set{_xml = value;}
}
private string _title;
public string title
{
get { return _title; }
set { _title = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
SetXmlValueByAnalysisServices();
}
private void SetXmlValueByAnalysisServices()
{
CellSet cs = Beisen.AnalysisServices.ServiceImp.Provider.BIAdminUserProvider.Instance.GetAdminUserCellSetMsg();
DataTable dt = CellSetToDataTable.ToDataTable(cs);
dt.TableName = "AdminUser";
this._xml = ConvertToXML.ConvertDataTableToXML(dt);
this._title = "数据报表";
}
}
}
其中还需要注意的是,我们从AnalysisServices 里边查询出来的数据,只是一个CellSet,不是我们传统的数据表DataTable,我们需呀进行CellSet到数据表之间的转换:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Text.RegularExpressions;
namespace AnalysisServices.Utility
{
public class ConvertToXML
{
///
/// 将DataTable转换成RecordXML函数
///
/// 要转换的DataTable
/// 转换好的XML字符串
public static string ConvertDataTableToXML(DataTable dt)
{
/*DataTable支持的数据类型
system.int64
system.byte[]
system.boolean
system.string
system.datetime
system.decimal
system.double
system.int32
system.single
system.int16
system.object
system.byte
system.guid
*/
string TempValue;
for (int i = 0; i < dt.Columns.Count; i++)
{
TempValue = dt.Columns[i].ColumnName;
Regex rex = new Regex("\\W");
TempValue = rex.Replace(TempValue, "");
rex = new Regex("^\\d");
if (rex.Replace(TempValue, "").Length != TempValue.Length)
{
TempValue = "N" + TempValue;
}
dt.Columns[i].ColumnName = TempValue;
}
StringBuilder sb = new StringBuilder();
sb.Append(" ");
sb.Append(" ");
sb.Append(" ");
for (int i = 0; i < dt.Columns.Count; i++)
{
string DataType;
switch (dt.Columns[i].DataType.ToString().ToLower())
{
case "system.boolean":
DataType = "string";
break;
case "system.byte":
case "system.int16":
case "system.int32":
case "system.int64":
DataType = "int";
break;
case "system.decimal":
case "system.double":
case "system.single":
DataType = "float";
break;
case "system.string":
DataType = "string";
break;
case "system.datetime":
DataType = "datetime";
break;
default:
throw new ArgumentException();
}
sb.Append(" ");
sb.Append(" ");
sb.Append(" ");
}
sb.Append(" ");
sb.Append(" ");
sb.Append(" ");
sb.Append(" ");
for (int i = 0; i < dt.Rows.Count; i++)
{
sb.Append("", "").Replace("'", "").Replace("\"", "");
if (dt.Columns[j].DataType.ToString().ToLower() == "system.datetime" && TempValue == string.Empty)
{
//TempValue = INVALIDDATE.ToString(DATEMASK);
TempValue = "";
}
sb.Append(dt.Columns[j].ColumnName + "='" + TempValue + "' ");
}
sb.Append("/> ");
}
sb.Append(" ");
sb.Append(" ");
return sb.ToString();
}
}
}