webabcd - 专注于asp.net, html5, silverlight

ASP.NET
从现在开始 一切都不晚
posts - 287, comments - 7866, trackbacks - 594, articles - 0
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理
原文地址:http://www.codeproject.com/KB/reporting-services/WebAndReportingServices.aspx
[原文源码下载]


[翻译]如何使用webservice作为数据源去生成Microsoft Reporting Services 2005的报表


原文发布日期:2006.05.18
作者:Dimitar Madjarov
翻译:webabcd




介绍
好几个月的时间了,我一直在学习Microsoft Reporting Services 2005的一些新的功能。其中之一就是如何使用webservice作数据源。但是很不幸,我无法在MSDN和SQL Server 2005的相关书籍中找到详细的帮助信息。所以我花了好长时间来搞定这个问题。希望通过分享我的Microsoft Reporting Services 2005的相关知识能够节省你的开发时间。


新建一个webservice
第一步是新建一个webservice,稍后我将用这个webservice作为我的报表的数据源。这是非常重要的一步,因为我们要将数据转换成一个XmlDataDocument。如果没有这步转换,我们将不能得到使用webservice的web方法取得数据的结果。实现这个转换的C#代码如下:
[WebMethod]
public XmlDataDocument GetPersonAddress(string cityNameID)
{
   
//
   
// 定义一些变量
   
//   
   StringBuilder   myQuery           = new StringBuilder();
   XmlDataDocument resultXMLDocument 
= new XmlDataDocument();
   SqlConnection   myConnection      
= new SqlConnection();
   SqlCommand      myCommand         
= new SqlCommand();
   SqlDataAdapter  myDA              
= new SqlDataAdapter();
   DataSet         myDS              
= new DataSet();

   
   
//
   
// 根据参数的不同准备不同的查询语句
   
//   
   if ((cityNameID != null&& (cityNameID.Trim() != ""))
   
{
    myQuery.Append(
"Select City as City, " + 
                   
"AddressLine1 as Address, " + 
                   
"PostalCode From Address ");
    myQuery.Append(
"Where City Like '" + 
                   cityNameID.Trim().Replace(
"%"""+ 
                   
"%' Order By City");
   }

   
else
   
{
    myQuery.Append(
"Select City as City, AddressLine1" + 
                   
" as Address, PostalCode From Address" + 
                   
" Order By City");
   }


   
   
//
   
// 得到连接字符串并建立到服务器的连接
   
//   
   myConnection.ConnectionString = ReadSetting("ConnectionString""");
   myCommand.Connection          
= myConnection;
   myCommand.CommandText         
= myQuery.ToString();
   myCommand.CommandType         
= CommandType.Text;
   myDA.SelectCommand            
= myCommand;

   
   
//
   
// 返回一个DataSet数据
   
//   
   try
   
{
      myDA.Fill(myDS, 
"Address");
      
      
//
      
// 转换我们的DataSet到XmlDataDocument
      
//
      XmlDataDocument temporaryXMLDoc = new XmlDataDocument(myDS);
      resultXMLDocument 
= temporaryXMLDoc;
      temporaryXMLDoc 
= null;
    }

    
catch
    
{
       resultXMLDocument 
= null;
    }

    
finally
    
{
       myDS.Dispose();
       myDA.Dispose();
       myCommand.Dispose();
       myConnection.Dispose();
       myQuery 
= null;
    }


   
return resultXMLDocument;
}

最后我们在IIS中发布这个webservice,因为我们是使用VS2005开发的,如果你的电脑里还装了VS2003,那么你应该检查一下你的虚拟目录关联的服务是否是.net 2.0


使用这个webservice作为数据源创建和部署报表
我们的下一步就是用Microsoft Reporting Services 2005创建一个报表,其使用的数据源就是我们第一步所创建的那个webservice。要完成这个任务,你的电脑里需要安装Microsoft SQL Server 2005的Microsoft Reporting Services。我们先新建一个名为“TestReport”的报表服务器项目。之后,我们添加一个共享数据源,将其类型设置为XML,连接字符串就是我们的webservice的地址。然后添加一个新报表,本例中webservice的命名空间是“http://madjarov_d_n_demo.org”,方法是“GetPersonAddress”
图1


图2


最后,你选择下一步并生成报表。这样报表就可以在SQL Server 2005和VS2005 Studio中设计了,图例如下:
图3


我们如何给webservice中的方法GetPersonAddress(string cityNameID)传参数呢?微软为开发人员提供了一个强大的报表引擎。我们可在Microsoft Reporting Services 2005中非常容易的设置它。首先我们要在设计模式中选择报表参数,然后增加一个数据类型为“string”,名为“cityNameID”的参数,图例如下:
图4


最后一步就是把这个报表参数和DataSet关联起来。为了达到这个目的,我们需要在设计模式中编辑数据源,首先新建一个DataSet,参数名为“cityNameID”,它的值为“Parameters!cityNameID.Value”,图例如下:
图5


现在我们就可以在报表服务器中部署报表了。在部署之前你要确保你的“TargetReport Folder”和“TargetReport Server”被设置成了正确的值。你可以在报表属性中设置它们,图例如下:
图6


现在你就可以把它部署到报表服务器了。


给我们的报表创建一个简单的视图
我们最后的任务就是创建一个视图程序,它负责从报表中获取结果然后展现给我们。为了在这里传送一个参数到报表里,我们在VS2005(C#)中创建了一个名为“TestReportWebViewer”的web站点,并把“Default.aspx”做我们web站点的默认页,然后从工具箱里把“ReportView”控件拖拽到我们的页上。最后给它设置一个合适的大小并如下图设置该控件其它的属性。
图7


请注意一定要把“ReportPath”和“ReportServerUrl”设置成我们之前部署报表时的相同的值,否则我们的“ReportView”控件将不会显示我们的报表。下面是“ReportView”控件的“Init”事件的源代码:
protected void rptViewer_Init(object sender, EventArgs e)

 
//
 
// 创建一个报表参数,并初始化它的值为“Al”
 
//   
 ReportParameter cityID   = new ReportParameter();
 cityID.Name              
= "cityNameID";
 cityID.Values.Add(
"Al"); 
 
 
//
 
// 设置“ReportView”控件的处理模式为“Remote”
 
//   
 rptViewer.ProcessingMode = ProcessingMode.Remote;
    
 
//
 
// 传送参数并初始化“ReportView”控件
 
//   
 rptViewer.ServerReport.SetParameters(new ReportParameter[] { cityID });
}

最后,谢谢你能看到这里。希望当你尝试在Microsoft Reporting Services 2005项目中使用webservice作数据源的时候本文能给你带来一些帮助。你可以下载本文提供的源码仔细看其实现的过程。

感谢我的同事Mr. Svilen Donev给我提供了很多有价值的信息。

Feedback

#1楼  回复 引用 查看   

2007-03-26 21:36 by Justin      
good work~

#2楼[楼主]  回复 引用 查看   

2007-03-27 08:40 by webabcd      
@Justin
:)
一定要把翻译坚持下去

#3楼  回复 引用   

2007-03-27 19:10 by ivw[未注册用户]
呵呵,好久没上了,今天早上blog好像上不了。
VS本身的报表没有试过,一直在用水晶报表,觉得它的功能比较强,使用也不难。
想问问楼主,SQL里除了用作业定时清除库的日志文件外还有什么办法可以定时自动清除日志呢?维护计划里好像不行吧?

#4楼[楼主]  回复 引用 查看   

2007-03-28 08:30 by webabcd      
@ivw
我一般就用DUMP TRANSACTION database WITH NO_LOG

嫌麻烦了就在属性里限制日志的大小

#5楼  回复 引用   

2007-03-28 16:39 by ivw[未注册用户]
若你在对数据库的修改发生时使用dump transaction with no_log,你就会冒整个数据库崩溃的风险。
用backup log DB with no_log这个会不会好些呢?

#6楼[楼主]  回复 引用 查看   

2007-03-28 17:59 by webabcd      
@ivw
这两个应该是一样的

#7楼  回复 引用   

2007-03-28 19:08 by ivw[未注册用户]
不过我一直在用backup,如果限制日志文件大小,是不是日志到了指定大小后不会再写入日志还是把原来的删除后再重新写入呢 ?

#8楼[楼主]  回复 引用 查看   

2007-03-28 21:58 by webabcd      
@ivw
没研究过,不过我估计是到了指定大小就不再写入了

其实,如果不需要日志功能的话就设置不写日志就好了

#9楼  回复 引用   

2007-03-29 10:29 by ivw[未注册用户]
嗯 ,想请教你,在.net里生成html文件有什么好处啊?

#10楼[楼主]  回复 引用 查看   

2007-03-29 17:34 by webabcd      
@ivw
呵,这个我熟
对于访问量大的页面要做成静态文件的方式啊,减少数据库负担

一般是用shtml的方式实现

#11楼  回复 引用   

2007-03-29 18:16 by ivw[未注册用户]
呵呵,有这方面的例子学习学习吗?

#12楼[楼主]  回复 引用 查看   

2007-03-29 22:39 by webabcd      
@ivw
你可以google一下

我原来的实现过程是这样的
先要读模板
StringBuilder sb = new StringBuilder();
StreamReader sr = new StreamReader(templatePath, Encoding.GetEncoding("GB2312"));
while ((strLine = sr.ReadLine()) != null)
{
sb.Append(strLine);
}
sr.Close();

模板中有一些占位符如[$xxx$],读数据库相关记录替换xxx。如果有这样的占位符[$]xxx[/$]就用正则表达式去替换

替换完后输出html如下
System.IO.StreamWriter sw;
sw = new System.IO.StreamWriter(htmlPath, false, Encoding.GetEncoding("GB2312"));
sw.Write(sb.ToString());
sw.Flush();
sw.Close();

#13楼  回复 引用   

2007-03-30 00:39 by ivw[未注册用户]
好的,有个问题想请教你。调用osql.exe去执行sql文件,怎样可以捕捉它执行时的错误信息啊?

#14楼[楼主]  回复 引用 查看   

2007-03-30 12:35 by webabcd      
@ivw
osql.exe啊,从来没接触过

#15楼  回复 引用   

2007-03-30 15:36 by ivw[未注册用户]
啊............,这是SQL提供给外界调用sql脚本文件的程序。就是不知道怎样可以捕捉到它调用脚本时出现的错误。

#16楼[楼主]  回复 引用 查看   

2007-03-30 21:32 by webabcd      
@ivw
没用过呀

#17楼  回复 引用   

2007-03-30 21:47 by ivw[未注册用户]
哦,,

#18楼  回复 引用   

2007-03-31 00:10 by ivw[未注册用户]
在自定义控件那里怎样可以定义一个集合属性啊?
用这种方法可以吗?
private List<string> _list = new List<string>
[Browsable(true), Category("杂项")]
public List<string> Item
{
get
{
return _list;
}
set
{
_list = value;
}
}

#19楼[楼主]  回复 引用 查看   

2007-03-31 23:11 by webabcd      
@ivw
应该是不行的
需要定义一个继承自CollectionBase的类

#20楼  回复 引用   

2007-04-01 14:40 by ivw[未注册用户]
winform里一样的吗?

#21楼  回复 引用   

2007-04-01 14:42 by ivw[未注册用户]
我在winform里用上面的试过,能做出那个效果,但他只有一个属性,就是value还是整形的,我改了字符串就出错,也不知道怎样定义多个属性。

#22楼[楼主]  回复 引用 查看   

2007-04-01 16:35 by webabcd      
@ivw
没做过winform,不清楚啊

#23楼  回复 引用 查看   

2007-05-15 17:50 by Jerry Hong      
hi,能请教一下,我用的是2005 reporting service Express版的。有没有办法不用2005 sql做数据库,而是用sql 2000的呢?谢教了。

#24楼[楼主]  回复 引用 查看   

2007-05-15 22:18 by webabcd      
@Jerry Hong
不可以
如果只想用Express版的话
请另外下载
http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&FamilyID=4C6BA9FD-319A-4887-BC75-3B02B5E48A40

#25楼  回复 引用   

2009-02-05 10:37 by zly123[未注册用户]
很不错,非常有用,帮我解决了一个问题,非常感谢!
报表中传递的参数名称需要和代码接收的参数名称保持一致,传递多个参数时报表中参数的顺序无关。

#26楼[楼主]  回复 引用 查看   

2009-02-05 12:08 by webabcd      
@zly123
:)
不谢

#27楼  回复 引用   

2009-04-17 14:09 by 清凉的风/2.0[未注册用户]
您好 咨询您个问题 您着个报表生成的是 .rdl格式的 但是导入到ReportViewer1格式应该是.rdlc格式的!

我的defualt.aspx页面的cs代码是这样的求您指点秘境 谢谢
protected void ReportViewer1_Init(object sender, EventArgs e)
{
//创建一个报表
ReportParameter rp = new ReportParameter();
rp.Values.Add("AI");

// 设置“ReportView”控件的处理模式为“Remote”
ReportViewer1.ProcessingMode = ProcessingMode.Remote;

// 传送参数并初始化“ReportView”控件
ReportViewer1.ServerReport.SetParameters(new ReportParameter[] { rp });
}
小弟感激不尽了!~~

#28楼[楼主]  回复 引用 查看   

2009-04-17 17:00 by webabcd      
@清凉的风/2.0
嗯。。。
参考一下这一篇文章吧
http://msdn.microsoft.com/zh-cn/library/ms252109.aspx
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 687841 7ZpJ5rEYSpk=