Reporting Services系列五:WebService接口
(1)使用ReportingServices的WebService接口实现报表导出
(2)使用ReportingServices的WebService接口实现报表订阅
ReportingServices提供WebService接口,基本上所有报表的操作都可以利用它们完成,以下在代码演示如何使用它们进行报表的导出、报表的订阅等。其中报表订阅中的“邮件订阅”未经过实际测试,其它代码都经过测试,没有发现什么问题。当然方法只是给出个原理,没有什么真正实用价值,有兴趣的人可以根据自己的需求对接口进行包装。
在动手写代码之前,你要添加对此WebService的引用,如图:
//
代码如下:
public class RsWebServiceHelper
{
private ReportingService mRService;
public RsWebServiceHelper()
{
this.mRService=new ReportingService();
//Web Service认证可以使用Windows认证和基本认证。
//如报表服务器上reportserver目录直接使用具备admin权限的用户匿名访问
//则二者都可,且用户名密码可随意,否则,请指定OS中具有权限的用户名密码
//Windows 认证:(默认采用NETWORK SERVICE用户(win2003),权限不足)
//this.mRService.Credentials =System.Net.CredentialCache.DefaultCredentials;
//基本认证:
this.mRService.Credentials =new System.Net.NetworkCredential("myhuang","123");
}
/**//// <summary>
/// 获取报表项目列表
/// </summary>
/// <returns></returns>
public DataTable ListFolders()
{
DataTable dt=new DataTable();
dt.Columns.Add("ReportName",typeof(System.String));
dt.Columns.Add("ReportPath",typeof(System.String));
foreach(CatalogItem ci in this.mRService.ListChildren("/",false))
{
if(ci.Type ==ItemTypeEnum.Folder)
{
dt.Rows.Add(new object[]{ci.Name,ci.Path});
}
}
return dt;
}
/**//// <summary>
/// 获取报表列表
/// </summary>
/// <param name="pTargetName">报表项目名称</param>
/// <returns></returns>
public DataTable ListReports(string pTargetName)
{
DataTable dt=new DataTable();
dt.Columns.Add("ReportName",typeof(System.String));
dt.Columns.Add("ReportPath",typeof(System.String));
foreach(CatalogItem ci in this.mRService.ListChildren("/"+pTargetName,false))
{
if(ci.Type ==ItemTypeEnum.Report)
{
dt.Rows.Add(new object[]{ci.Name,ci.Path});
}
}
return dt;
}
/**//// <summary>
/// 报表导出
/// </summary>
/// <param name="pReportPath">报表全路径</param>
/// <param name="pParams">报表参数</param>
/// <param name="pFormat">导出格式</param>
/// <param name="pExpPath">导出路径</param>
/// <returns></returns>
public bool ExportReport(string pReportPath,string[][] pParams,string pFormat,string pExpPath)
{
string encoding;
string mimetype;
ParameterValue[] pvout;
Warning[] warmings;
string[] streamid;
ParameterValue[] pv = null;
if(pParams!=null)
{
pv=new ParameterValue[pParams.Length];
for(int i=0;i<pParams.Length;i++)
{
pv[i]=new ParameterValue();
pv[i].Name=pParams[i][0];
pv[i].Value=pParams[i][1];
}
}
try
{
byte[] bytes=this.mRService.Render(pReportPath,pFormat,null,null,pv,null,null,out encoding,out mimetype,out pvout,out warmings,out streamid);
using(FileStream fs=File.Create(pExpPath,bytes.Length))
{
fs.Write(bytes,0,bytes.Length);
}
return true;
}
catch
{
return false;
}
}
/**//// <summary>
/// 报表导出
/// </summary>
/// <param name="pReportPath">报表全路径</param>
/// <param name="pFormat">导出格式</param>
/// <param name="pExpPath">导出路径</param>
/// <returns></returns>
public bool ExportReport(string pReportPath,string pFormat,string pExpPath)
{
bool rt=ExportReport(pReportPath,null,pFormat,pExpPath);
return rt;
}
/**//// <summary>
/// 以共享文件方式订阅报表
/// </summary>
/// <param name="pReport">报表全路径</param>
/// <param name="pParams">报表参数</param>
/// <param name="pStartTime">订阅开始时间</param>
/// <param name="pFileName">产生的文件名称</param>
/// <param name="pShareFolderPath">共享文件夹路径</param>
/// <param name="pFormat">生成文件格式</param>
/// <param name="pUser">用户名</param>
/// <param name="pPwd">密码</param>
/// <param name="pResult">订阅结果</param>
/// <returns></returns>
public bool SubscriptionFileShare(string pReport,string[][] pParams,DateTime pStartTime,string pFileName,string pShareFolderPath,string pFormat,string pUser,string pPwd,out string pResult)
{
RecurrencePattern,用于指定schedule的周期类型#region RecurrencePattern,用于指定schedule的周期类型
//继承于“RecurrencePattern”类:
/**//*MinuteRecurrence
Represents the interval, in minutes, on which a scheduled report runs.
//属性:MinutesInterval The interval, in minutes, at which a scheduled report runs
DailyRecurrence
Represents the interval, in days, on which a scheduled report runs.
//属性:DaysInterval The intervals at which a scheduled report runs. Intervals are specified in days
WeeklyRecurrence
Represents the weeks interval and the days of the week on which a scheduled report runs.
//属性:DaysOfWeek The days of the week (DaysOfWeekSelector object) on which a scheduled report runs.
//WeeksInterval The intervals at which a scheduled report runs. Intervals are measured in weeks.
//WeeksIntervalSpecified Indicates whether the WeeksInterval value is specified.
MonthlyRecurrence
Represents the days of the month on which a scheduled report runs.
//属性:Days Gets or sets the days of the month on which a scheduled report runs.
//MonthsOfYear Gets or sets the months of the year (MonthsOfYearSelector object) in which a scheduled report runs.
MonthlyDOWRecurrence
Represents the day of week, the week number in the month, and the month on which a scheduled report runs.
//属性:*/
#endregion
//订阅的触发条件:时间周期完成时触发、快照方式(??)
string eventType = "TimedSubscription";
//string evetnType="SnapshotUpdated";
ExtensionSettings es=new ExtensionSettings();
//ReportingServices的两种订阅方式:共享文件方式、发送邮件方式
es.Extension ="Report Server FileShare";
//通过ScheduleDefinition类指定sd的起始执行时间
ScheduleDefinition sd = new ScheduleDefinition();
sd.StartDateTime = pStartTime;
//也可指定计划的结束时间:
//sd.EndDate=DateTime.Now.AddMonths(2);
//sd.EndDateSpecified = true;
//通过DailyRecurrence类指定sd的周期类型
DailyRecurrence dr=new DailyRecurrence();
dr.DaysInterval =1;
sd.Item =dr;
一个比较复杂的周期类型#region 一个比较复杂的周期类型
/**//*
MonthlyDOWRecurrence pattern = new MonthlyDOWRecurrence();
pattern.WhichWeekSpecified = true;
pattern.WhichWeek = WeekNumberEnum.LastWeek;
MonthsOfYearSelector months = new MonthsOfYearSelector();
months.March = true;
months.June = true;
months.September = true;
months.December = true;
pattern.MonthsOfYear = months;
DaysOfWeekSelector days = new DaysOfWeekSelector();
days.Friday = true;
pattern.DaysOfWeek = days;*/
#endregion
XmlDocument doc = this.GetScheduleAsXml(sd);
string matchData = doc.OuterXml;
可手写sd的xml定义#region 可手写sd的xml定义
/**//*
string scheduleXml=@"<ScheduleDefinition>";
scheduleXml+="<StartDateTime>2006-12-25T16:40:00</StartDateTime>";//时区不用
scheduleXml+="<DailyRecurrence>";
scheduleXml+="<DaysInterval>1</DaysInterval>";
//matchdate+="<DaysOfWeek><Monday>True</Monday></DaysOfWeek>";
scheduleXml+="</DailyRecurrence>";
scheduleXml+="</ScheduleDefinition>";*/
#endregion
共享文件订阅所需“扩展参数”#region 共享文件订阅所需“扩展参数”
ParameterValue[] pv = new ParameterValue[7];
//文件名
pv[0] = new ParameterValue();
pv[0].Name = "FILENAME";
pv[0].Value = pFileName;
//是否自动添加扩展名,"True"或"False"
pv[1] = new ParameterValue();
pv[1].Name = "FILEEXTN";
pv[1].Value = "True";
//共享文件夹路径
pv[2] = new ParameterValue();
pv[2].Name = "PATH";
pv[2].Value = pShareFolderPath;
//文件类型,"MHTML" "HTML3.2" "PDF","CSV","EXCEL","HTML4.0" "MHTML" "IMAGE" "XML"
pv[3] = new ParameterValue();
pv[3].Name = "RENDER_FORMAT";
pv[3].Value = pFormat;
//须提供OS中具备对该文件夹写权限的用户、密码
pv[4] = new ParameterValue();
pv[4].Name = "USERNAME";
pv[4].Value = pUser;
pv[5] = new ParameterValue();
pv[5].Name = "PASSWORD";
pv[5].Value = pPwd;
//方式:"None","AutoIncrement"(文件名自增),"Overwrite"(覆盖原文件)
pv[6] = new ParameterValue();
pv[6].Name = "WRITEMODE";
pv[6].Value = "AutoIncrement";
#endregion
报表自身参数#region 报表自身参数
ParameterValue[] pv2 = null;
if(pParams!=null)
{
pv2=new ParameterValue[pParams.Length];
for(int i=0;i<pParams.Length;i++)
{
pv2[i]=new ParameterValue();
pv2[i].Name=pParams[i][0];
pv2[i].Value=pParams[i][1];
}
}
#endregion
es.ParameterValues =pv;
try
{
string result=this.mRService.CreateSubscription(pReport, es, null, eventType, matchData, pv2);
pResult =result;//订阅的ID
return true;
}
catch (System.Web.Services.Protocols.SoapException ex)
{
pResult=ex.Detail.InnerXml.ToString();
return false;
}
}
/**//// <summary>
/// 以邮件方式订阅报表
/// </summary>
/// <param name="pReport">报表全路径</param>
/// <param name="pParams">报表参数</param>
/// <param name="pStartTime">订阅开始时间</param>
/// <param name="pSendTo">发送人</param>
/// <param name="pReplyTo">抄送人</param>
/// <param name="pFormat">发送文件格式</param>
/// <param name="pResult">订阅结果</param>
/// <returns></returns>
public bool SubscriptionEmail(string pReport,string[][] pParams,DateTime pStartTime,string pSendTo,string pReplyTo,string pFormat,out string pResult)
{
//订阅的触发条件:时间周期完成时触发、快照方式(??)
string eventType = "TimedSubscription";
//string evetnType="SnapshotUpdated";
ExtensionSettings es=new ExtensionSettings();
//ReportingServices的两种订阅方式:共享文件方式、发送邮件方式
es.Extension="Report Server Email";
//通过ScheduleDefinition类指定sd的起始执行时间
ScheduleDefinition sd = new ScheduleDefinition();
sd.StartDateTime = pStartTime;
//通过DailyRecurrence类指定sd的周期类型
DailyRecurrence dr=new DailyRecurrence();
dr.DaysInterval =1;
sd.Item =dr;
XmlDocument doc = this.GetScheduleAsXml(sd);
string matchData = doc.OuterXml;
邮件订阅所需“扩展参数”#region 邮件订阅所需“扩展参数”
ParameterValue[] pv = new ParameterValue[8];
pv[0] = new ParameterValue();//收件人邮件地址
pv[0].Name = "TO";
pv[0].Value = pSendTo;
pv[1] = new ParameterValue();//抄送邮件地址
pv[1].Name = "ReplyTo";
pv[1].Value = pReplyTo;
pv[2] = new ParameterValue();
pv[2].Name = "IncludeReport";
pv[2].Value = "True";
pv[3] = new ParameterValue();
pv[3].Name = "RenderFormat";
pv[3].Value = pFormat;
pv[4] = new ParameterValue();
pv[4].Name = "Subject";
pv[4].Value = "@ReportName was executed at @ExecutionTime";
pv[5] = new ParameterValue();
pv[5].Name = "Comment";
pv[5].Value = "Here is your daily sales report for Michael.";
pv[6] = new ParameterValue();
pv[6].Name = "IncludeLink";
pv[6].Value = "True";
pv[7] = new ParameterValue();
pv[7].Name = "Priority";
pv[7].Value = "NORMAL";
#endregion
报表自身参数#region 报表自身参数
ParameterValue[] pv2 = null;
if(pParams!=null)
{
pv2=new ParameterValue[pParams.Length];
for(int i=0;i<pParams.Length;i++)
{
pv2[i]=new ParameterValue();
pv2[i].Name=pParams[i][0];
pv2[i].Value=pParams[i][1];
}
}
#endregion
es.ParameterValues =pv;
try
{
string result=this.mRService.CreateSubscription(pReport, es, null, eventType, matchData, pv2);
pResult =result;//订阅的ID
return true;
}
catch (System.Web.Services.Protocols.SoapException ex)
{
pResult=ex.Detail.InnerXml.ToString();
return false;
}
}
/**//// <summary>
/// 目前Reporting Services2000 SP2
/// 序列化任务计划的XML存在与Reporing Services API的WhichWeek定义不一致的情况,
/// 所以当schedule中涉及whichweek时,需要进行如下处理:
/// </summary>
/// <param name="schedule"></param>
/// <returns></returns>
private XmlDocument GetScheduleAsXml(ScheduleDefinition pSchedule)
{
MemoryStream buffer = new MemoryStream();
XmlSerializer xmlSerializer = new XmlSerializer(typeof(ScheduleDefinition));
xmlSerializer.Serialize(buffer, pSchedule);
buffer.Seek(0, SeekOrigin.Begin);
XmlDocument doc = new XmlDocument();
doc.Load(buffer);
//patch up WhichWeek
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("rs", "http://schemas.microsoft.com/sqlserver/2003/12/reporting/reportingservices");
XmlNode node = doc.SelectSingleNode("/ScheduleDefinition/rs:MonthlyDOWRecurrence/rs:WhichWeek", ns);
if(node != null)
{
switch (node.InnerXml)
{
case "FirstWeek":
node.InnerXml = "FIRST_WEEK"; break;
case "SecondWeek":
node.InnerXml = "SECOND_WEEK"; break;
case "ThirdWeek":
node.InnerXml = "THIRD_WEEK"; break;
case "FourthWeek":
node.InnerXml = "FOURTH_WEEK"; break;
case "LastWeek":
node.InnerXml = "LAST_WEEK"; break;
}
}
return doc;
}
}
测试代码:
private void btExp_Click(object sender, System.EventArgs e)
{
RsWebServiceHelper h=new RsWebServiceHelper();
string[][] pv=new string[4][];
pv[0]=new string[2]{"start_time","2007-02-01"};
pv[1]=new string[2]{"end_time","2007-03-01"};
pv[2]=new string[2]{"note","20"};
pv[3]=new string[2]{"RsName","Alarm"};
bool rt=h.ExportReport("/pReports/AlarmLevel",pv,"Excel",@"e:\myhuang\rs.xls");
if(rt)
{
Response.Write("<script language=javascript>window.alert('ok');</script>");
}
else
{
Response.Write("<script language=javascript>window.alert('failed');</script>");
}
}
private void btSubs_Click(object sender, System.EventArgs e)
{
string[][] pv=new string[4][];
pv[0]=new string[2]{"start_time","2007-02-01"};
pv[1]=new string[2]{"end_time","2007-03-01"};
pv[2]=new string[2]{"note","20"};
pv[3]=new string[2]{"RsName","Alarm"};
RsWebServiceHelper h=new RsWebServiceHelper();
string rtout;
bool rt=h.SubscriptionFileShare("/pReports/AlarmLevel",pv,DateTime.Now.AddMinutes(1),"subsnew",@"e:\myhuang\RsShareFolder","EXCEL","myhuang","123",out rtout);
if(rt)
{
Response.Write("<script language=javascript>window.alert('succeed:"+rtout+"');</script>");
}
else
{
Response.Write("<script language=javascript>window.alert('error:"+rtout+"');</script>");
}
}
关注作者:欢迎扫码关注公众号「后厂村思维导图馆」,获取本人自建的免费ChatGPT跳板地址,长期有效。 原文链接:https://www.cnblogs.com/morvenhuang/archive/2007/08/01/839548.html 版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。 |