zoukankan      html  css  js  c++  java
  • 自定义Repor结构的开始

    是时候改造我原来的报表系统了,几天的工作总结下。

    在VS2005里面的Report功能好强,把我原来做得很多工作都枪毙了,痛并快乐的感觉。
    对现在的项目,要使用MS Repor有2个最烦人问题:
    1、没有提供RDLC的图形设计界面的运行时控件,在网上找了一下,也没有发现谁做好了;
    2、强结构作为数据源。

    虽然客户的报表模板都是我做,但是我还是不愿意在设计环境下来设计报表。要是有个RDLC的图形设计界面控件多好,理论上作一个实现一些基本功能,至少满足现在这个项目需要的,肯定没多大问题,但是需要时间,慢慢再说吧。

    好了,我暂时开VS设计报表,可是在VS的IDE里,设计报表时需要强结构的数据源,我做不到啊。这个项目的报表又多又乱,几乎天天有新报表,天天在改久报表。这个现象也怪不了谁,公司在急速发展,新业务和新作业方式不断地加入到系统中,各处对报表的需求量肯定会不断增加;还有一点,我没法对业务完全了解,自己出来的报表都不知道是不是客户想要得。所以,我不能把报表数据源的结构定下来,一定要方便我改动。定下一点总需求,改造后的Report系统保持添加修改任何报表不需要改代码的特性。


    对于简单报表现在有了一个思路。step by setp
    1、只返回一个Table作为数据源,在这个单表里面包含主-子-子----子的所有数据。其实我习惯称呼其为分层,有人叫分组。拿到要做的报表,就在SQL Server里建一个相应的SP,,返回值就一个Table就得了。
    2、做一个DefaultReportTemplate.rdlc, 全空;定义一个DataSet,里面一个Table, 里面一个Field。把这个DataSet添加到DefaultReportTemplate.rdlc。
    3、做一个asmx或者aspx,输入参数为SP_Name,ReportTemplateName。功能很简单,用XML打开DefaultReportTemplate.rdlc,查询到该SP得Fileds,替换XML里面数据表的字段定义部分, Saveas -->ReportTemplateName。再提供一个下载到本地的功能也行,自己从服务上下载也行。
    4、开个VS2005空项目,打开下载的rdlc. 很好,虽然没有图形化的数据源显示出来,用不上托拽字段的功能,但是在所有的属性页都能使用我替换上去的Field。
    5、设计好rdlc,上传到系统report template空间。


    DefaultReportTemplate.rdlc
    <?xml version="1.0" encoding="utf-8"?>
    <Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
      
    <DataSources>
        
    <DataSource Name="ReportDataSource">
          
    <ConnectionProperties>
            
    <ConnectString />
            
    <DataProvider>SQL</DataProvider>
          
    </ConnectionProperties>
          
    <rd:DataSourceID>a03e342a-c8ff-428e-87c7-8a5f9d36889b</rd:DataSourceID>
        
    </DataSource>
      
    </DataSources>
      
    <Width>6.5in</Width>
        
    <Body>
            
    <Height>2in</Height>
        
    </Body>
        
    <rd:InitialLanguage>true</rd:InitialLanguage>
        
    <rd:InitialDimensions>
            
    <rd:UnitType>Inch</rd:UnitType>
            
    <rd:LeftMargin>1in</rd:LeftMargin>
            
    <rd:RightMargin>1in</rd:RightMargin>
            
    <rd:TopMargin>1in</rd:TopMargin>
            
    <rd:BottomMargin>1in</rd:BottomMargin>
            
    <rd:PageWidth>8.5in</rd:PageWidth>
            
    <rd:PageHeight>11in</rd:PageHeight>
            
    <rd:ColumnSpacing>0.5in</rd:ColumnSpacing>
        
    </rd:InitialDimensions>
        
    <rd:InitialDimensions>
            
    <rd:UnitType>Cm</rd:UnitType>
            
    <rd:Width>16cm</rd:Width>
            
    <rd:Height>5cm</rd:Height>
            
    <rd:LeftMargin>2.5cm</rd:LeftMargin>
            
    <rd:RightMargin>2.5cm</rd:RightMargin>
            
    <rd:TopMargin>2.5cm</rd:TopMargin>
            
    <rd:BottomMargin>2.5cm</rd:BottomMargin>
            
    <rd:GridSpacing>0.25cm</rd:GridSpacing>
            
    <rd:PageWidth>21cm</rd:PageWidth>
            
    <rd:PageHeight>29.7cm</rd:PageHeight>
            
    <rd:ColumnSpacing>1cm</rd:ColumnSpacing>
        
    </rd:InitialDimensions>
      
    <DataSets>
        
    <DataSet Name="DataSetReport">
          
    <rd:DataSetInfo>
            
    <rd:DataSetName>DataSetReport</rd:DataSetName>
            
    <rd:TableName>DataTableReport</rd:TableName>
          
    </rd:DataSetInfo>
          
    <Query>
            
    <rd:UseGenericDesigner>true</rd:UseGenericDesigner>
            
    <CommandText />
            
    <DataSourceName>ReportDataSource</DataSourceName>
          
    </Query>
          
    <Fields>
            
    <Field Name="Filed1">
              
    <rd:TypeName>String</rd:TypeName>
              
    <DataField>Filed1</DataField>
            
    </Field>
          
    </Fields>
        
    </DataSet>
      
    </DataSets>
    </Report>

    根据SP的返回Table替换DefaultReportTemplate.rdlc的字段定义区
    public void CreateRDLC(string sp,string filename)
            
    {
                
    try
                
    {
                    DataSet ds 
    = GetSPStructure(sp);
                    XmlDocument sourceDoc 
    = new XmlDocument();
                    XPathNavigator navigator;
                    XmlNamespaceManager manager;
                    
    string tempdir =AppDomain.CurrentDomain.BaseDirectory;
                    
    string tempfilepath =Path.Combine(tempdir,@"Templates/ReportDefaulte.rdlc");

                    
    string objfilepath =Path.Combine(tempdir,@"Templates/"+filename);

                    sourceDoc.Load(tempfilepath);

                    navigator 
    = sourceDoc.CreateNavigator();
                    manager 
    = new XmlNamespaceManager(navigator.NameTable);
                    manager.AddNamespace(
    "a""http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
                    manager.AddNamespace(
    "rd""http://schemas.microsoft.com/SQLServer/reporting/reportdesigner");

                    XmlNode xnFieldTemp 
    = sourceDoc.SelectSingleNode("/a:Report/a:DataSets/a:DataSet/a:Fields/a:Field",manager);
                    XmlNode xnDataSet 
    = xnFieldTemp.ParentNode;

                    
    int fieldCount = ds.Tables["ReportFields"].Columns.Count;
                    
                    xnFieldTemp.Attributes[
    "Name"].Value = ds.Tables["DataTableReport"].Columns[0].ColumnName;
                    xnFieldTemp[
    "DataField"].InnerText = ds.Tables["DataTableReport"].Columns[0].ColumnName;
                    xnFieldTemp[
    "rd:TypeName"].InnerText = ds.Tables["DataTableReport"].Columns[0].DataType.ToString();

                    
    for (int i =1 ; i<fieldCount;i++)
                    
    {
                        XmlNode xnNewField 
    = xnFieldTemp.Clone();
                        xnNewField.Attributes[
    "Name"].Value = ds.Tables["DataTableReport"].Columns[i].ColumnName;
                        xnNewField[
    "DataField"].InnerText = ds.Tables["DataTableReport"].Columns[i].ColumnName;
                        xnNewField[
    "rd:TypeName"].InnerText = ds.Tables["DataTableReport"].Columns[i].DataType.ToString();
                        xnDataSet.AppendChild(xnNewField);
                    }

                    
                    sourceDoc.Save(objfilepath);
                    
                }

                
    catch (Exception e)
                
    {
                    System.Console.WriteLine(e.ToString());
                    
    throw;
                }


            }


            
            
    private DataSet GetSPStructure(string sp)
            
    {                        
                DataSet tempData 
    = new DataSet();
                System.Data.SqlClient.SqlCommand sqlSelectCommand1 
    = new System.Data.SqlClient.SqlCommand();
                System.Data.SqlClient.SqlDataAdapter sqlQuery 
    = new System.Data.SqlClient.SqlDataAdapter() ;
                sqlSelectCommand1.CommandText 
    = "[sp_sproc_columns]";
                sqlSelectCommand1.CommandType 
    = System.Data.CommandType.StoredProcedure;
                sqlSelectCommand1.Connection 
    = this.conn;
                sqlSelectCommand1.Parameters.Add(
    new System.Data.SqlClient.SqlParameter("@RETURN_VALUE", System.Data.SqlDbType.Int, 4, System.Data.ParameterDirection.ReturnValue, false, ((System.Byte)(0)), ((System.Byte)(0)), "", System.Data.DataRowVersion.Current, null));
                sqlSelectCommand1.Parameters.Add(
    new System.Data.SqlClient.SqlParameter("@procedure_name", System.Data.SqlDbType.NVarChar, 390));
                sqlQuery.SelectCommand 
    = sqlSelectCommand1;
                sqlSelectCommand1.Parameters[
    "@procedure_name"].Value = sp;
                sqlQuery.Fill(tempData,
    "Parameters");

                
    string sql="exec " + sp + " @EditionIDs='-2'";
                
    for (int i=1;i<tempData.Tables[0].Rows.Count-1;i++)
                
    {
                    
    string Type_Name = tempData.Tables[0].Rows[i]["TYPE_NAME"].ToString();
                    
    string Para_Name = tempData.Tables[0].Rows[i]["COLUMN_NAME"].ToString();
                    
    if (Type_Name=="int")
                        sql
    =sql + "," + Para_Name + "=0";
                    
    if (Type_Name=="nvarchar" || Type_Name=="varchar" || Type_Name=="nchar" || Type_Name=="char")
                        sql
    =sql + "," + Para_Name + "=''";
                    
    if (Type_Name=="datetime")
                        sql
    =sql + "," + Para_Name + "='1900-01-01'";
                }

                sqlQuery.SelectCommand.CommandType
    =System.Data.CommandType.Text;
                sqlQuery.SelectCommand.CommandText 
    = sql;
                sqlQuery.Fill(tempData,
    "ReportFields");
                
    return tempData;
                    
            }


    对原系统的改造应该不会有多大,Reprot Template Main Window 提供一个选择rdlc文件的combobox。在ReportOutpot window,砍掉以前的代码,放个ReportViewer上去,加上以下代码:这了copy了一点别人的代码,望事主见谅。
    private void ViewReport(DataSet dsReport,string templatfullpath)
            
    {

                XmlDocument sourceDoc 
    = new XmlDocument();
                sourceDoc.Load(templatfullpath);
                MemoryStream ms 
    = new MemoryStream();
                XmlSerializer serializer 
    = new XmlSerializer(typeof(XmlDocument));
                serializer.Serialize(ms, sourceDoc);
                ms.Position 
    = 0;

                
    this.reportViewer1.LocalReport.LoadReportDefinition(ms);
                
    this.reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSetReport", dsReport.Tables[0]));
                
    this.reportViewer1.LocalReport.Refresh();
                
    this.reportViewer1.RefreshReport();
     
            }

    直接打印和自动导出到Excel和PDF的部分还没去研究,应该不会出什么篓子吧。

  • 相关阅读:
    Uva673 Parentheses Balance
    cordforce Educational Codeforces Round 47 补题笔记 <未完>
    cordforce 495 补题 <未完>
    linux 基本命令笔记
    app审核相关
    CATransform3D
    UITableView点击切换状态分析
    iOS大转盘抽奖
    被忽视的控件UIToolbar
    AVPlayerViewController视频播放器
  • 原文地址:https://www.cnblogs.com/Gun/p/537810.html
Copyright © 2011-2022 走看看