Web程序,使用ReportSerivce报表对象模型编程发布报表

来源:互联网 发布:ubuntu登录界面更改 编辑:程序博客网 时间:2024/05/17 08:40

Web程序,使用ReportSerivce报表对象模型编程发布报表

前一段时间在公司做了一个需要用到sql server2005 reportserivce服务的项目,我主要负责reportserivce的报表模块部分.为了方便报表的发布,所以做了报表的添加,删除管理页面.下面就记录一下我的做的添加表报功能页面:


下面最终做的添加管理页面:

报表管理页面截图


接着,说说具体的步骤:

首先定义一个报表项目ReportItem.cs类,用主要是方便后面好操作,方便修改导航树报表的url地址:

ReportItem.cs代码

/// <summary>
    
/// 报表项目类
    
/// </summary>

    public class ReportItem
    
{
        
private string _chname;
        
private string _enname;
        
private bool _isSubReport;
        
public ReportItem(string ChineseName, string EnglishName)
        
{
            _chname 
= ChineseName;
            _enname 
= EnglishName;
            _isSubReport 
= false;
        }

        
public ReportItem(string ChineseName, string EnglishName, bool IsSubReport)
        
{
            _chname 
= ChineseName;
            _enname 
= EnglishName;
            _isSubReport 
= IsSubReport;
        }

        
/// <summary>
        
/// 获取或设置中文报表名称
        
/// </summary>

        public string ChineseName
        
{
            
get return _chname; }
            
set { _chname = value; }
        }

        
/// <summary>
        
/// 获取或设置英文报表名称
        
/// </summary>

        public string EnglishName
        
{
            
get return _enname; }
            
set { _enname = value; }
        }

        
public bool IsSubReport
        
{
            
get return _isSubReport; }
            
set { _isSubReport = value; }
        }


同时,我在待添加报表的目录中,写了Reports.xml文件,由于描述报表的一些属性,和上面的reportitem.cs类是对应的.
说明以下:
ChineseName主要用于显示在导航树中的名字
Englishname是用来保存报表的英文名字,因为在开发的时候,以及后面的url访问的时候,都是用的这个名字,所以我决定英文名字,以避免将来可能遇到的编码问题.
IsSubReport是否是子报表,主要是以为我有嵌套子报表的情况.
上面的ReportItem.cs的各个属性说明也和这个一样.
<?xml version="1.0" encoding="gb2312" ?>
<ReportItems>
<Item>
 
<ChineseName>商品基本信息</ChineseName>
 
<EnglishName>ReportGoods.rdl</EnglishName>
 
<IsSubReport>true</IsSubReport>
</Item>
</ReportItems>


以下是C#源代码:

 


总结以下需要主要的几个地方:
1.创建报表资源的时候,需要注意的是CreateResource方法的第一个参数,资源名称是要包含后缀的(如:picture.png"),否则,浏览的时候资源出来不,因为我的资源是png图片所以是"image/png".
2.因为我做的时候,在添加报表的时候,可以修改数据源,所以写了ChangeDataSource方法把每个报表的数据源设置成一样的
3.修改导航树的时候(如果有导航菜单xml文件),要注意的是:&符号在xml文件的表示,之前我把&换成&amp;结果修改xml文件保存后,发现报表的url地址还是不对.后面,换成@"&rs.."就可以了.
4.如果有嵌套子报表的话,那么还修改母报表和子报表的rdl文件,否则嵌套的子报表出来.子报表也返回不到母报表了.

觉得有几个地方不是很好:
1,维护报表目录下的xml文件比较麻烦点,以后每添加报表都要有个相应的xml文件
2,“获取报表”按钮如果能做成,文件夹打开对话框那种形式,那操作性更好一些。

以上问题,我还没想到怎么做才好?

 (本文章:同时发表在我的博客园上,http://xray2005.cnblogs.com)

using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Web.Services;
using myWebReport.Web.rs;
using System.Xml;
using System.Collections.Generic;
namespace myWebReport
{
    
public partial class AddReport : System.Web.UI.Page
    
{
        
protected void Page_Load(object sender, EventArgs e)
        
{

        }


        
protected void btnAddReport_Click(object sender, EventArgs e)
        
{
            
if (GetCheckReport().Count > 0)
            
{
                
try
                
{

                    
this.lberror.Text = "";
                    
this.lberror.Visible = false;
                    ReportingService rs 
= new ReportingService();
                    rs.Url 
= this.txtWebSevice.Text.Trim() + "/ReportServer/ReportService.asmx";
                    rs.Credentials 
= System.Net.CredentialCache.DefaultCredentials;
                    rs.CreateFolder(
this.txtServerPath.Text, "/"null);
                    DataSourceDefinition dsd 
= new DataSourceDefinition();
                    dsd.CredentialRetrieval 
= CredentialRetrievalEnum.Store;
                    dsd.ConnectString 
= this.txtSQLConnectionString.Text.Trim();
                    dsd.Enabled 
= true;
                    dsd.EnabledSpecified 
= true;
                    dsd.Extension 
= "SQL";
                    dsd.ImpersonateUser 
= false;
                    dsd.ImpersonateUserSpecified 
= true;
                    dsd.Prompt 
= null;
                    dsd.UserName 
= this.txtUserName.Text;
                    dsd.Password 
= this.txtPassword.Text;
                    dsd.WindowsCredentials 
= false;
                     
//创建数据源
                    rs.CreateDataSource(this.txtDataSourceName.Text, "/" + this.txtServerPath.Text, true, dsd, null);
                    
//创建报表资源文件
                     CreateReportResource(this.txtLocalPath.Text, "/" + this.txtServerPath.Text, rs);
                    IList
<ReportItem> rsfiles = GetCheckReport();
                    IList
<ReportItem> sReports = new List<ReportItem>();
                    Warning[] w 
= null;
                    
byte[] def = null;
                    
string p = this.txtLocalPath.Text.Trim();
                    
if (!p.EndsWith("//"))
                        p 
+= "//";
                    
foreach (ReportItem f in rsfiles)
                    
{
                        
if (System.IO.File.Exists(p + f.EnglishName))
                        
{
                            
string strPath = p + f.EnglishName;
                            System.IO.FileStream st 
= System.IO.File.OpenRead(strPath);
                            def 
= new byte[st.Length];
                            st.Read(def, 
0, (int)st.Length);
                            st.Close();
                            
//创建报表
                            w = rs.CreateReport(f.EnglishName, "/" + this.txtServerPath.Text, true, def, null);
                            sReports.Add(f);
                        }

                    }

                    ChangeDataSource(
"/" + txtServerPath.Text, txtDataSourceName.Text, rs);
                    
if (sReports.Count > 0)
                    
{
                        
//修改导航树
                        ModifyNavigateTree(sReports, this.txtWebSevice.Text.Trim(), this.txtServerPath.Text.Trim());
                    }

                    
this.lberror.Text = "报表发布成功!";
                    
this.lberror.Visible = true;
                }

                
catch (Exception ex)
                
{
                    
this.lberror.Text += ex.Message;
                    
this.lberror.Visible = true;
                }

            }

        }


        
创建报表资源
        
        #region修改报表数据源
        
//因为在做报表的时候和添加报表的时候数据源可能会不一样,所以这里特意写了方法来修改之前的报表数据源.
        private void ChangeDataSource(string folderPath, string dataSourceName, ReportingService _rs)
        
{

            DataSourceReference dsr 
= new DataSourceReference();
            dsr.Reference 
= folderPath + "/" + dataSourceName;
            CatalogItem[] items 
= _rs.ListChildren(folderPath, false);
            
foreach (CatalogItem item in items)
            
{
                
if (item.Type == ItemTypeEnum.Report)
                
{
                    
//获取报表数据源
                    DataSource[] dss = _rs.GetReportDataSources(item.Path);
                    
foreach (DataSource d in dss)
                    
{
                        d.Item 
= dsr;
                    }

                    _rs.SetReportDataSources(item.Path, dss);
                }

            }


        }

        
#endregion
        
protected void btnCatelog_Click(object sender, EventArgs e)
        
{
            
if (!string.IsNullOrEmpty(this.txtLocalPath.Text))
            
{
                
string[] rptFiles = System.IO.Directory.GetFiles(this.txtLocalPath.Text, "*.xml");
                
if (rptFiles.Length > 0)
                
{
                    XmlDocument doc 
= new XmlDocument();
                    doc.Load(rptFiles[
0]);
                    XmlNodeList xlist 
= doc.DocumentElement.ChildNodes;
                    
this.rpterReports.DataSource = xlist;
                    
this.rpterReports.DataBind();
                }

            }

        }


        
获取选中的报表

        
修改导航树
    }

}