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

根据SP的返回Table替换DefaultReportTemplate.rdlc的字段定义区
None.gif public   void  CreateRDLC( string  sp, string  filename)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                DataSet ds 
= GetSPStructure(sp);
InBlock.gif                XmlDocument sourceDoc 
= new XmlDocument();
InBlock.gif                XPathNavigator navigator;
InBlock.gif                XmlNamespaceManager manager;
InBlock.gif                
string tempdir =AppDomain.CurrentDomain.BaseDirectory;
InBlock.gif                
string tempfilepath =Path.Combine(tempdir,@"Templates/ReportDefaulte.rdlc");
InBlock.gif
InBlock.gif                
string objfilepath =Path.Combine(tempdir,@"Templates/"+filename);
InBlock.gif
InBlock.gif                sourceDoc.Load(tempfilepath);
InBlock.gif
InBlock.gif                navigator 
= sourceDoc.CreateNavigator();
InBlock.gif                manager 
= new XmlNamespaceManager(navigator.NameTable);
InBlock.gif                manager.AddNamespace(
"a""http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition");
InBlock.gif                manager.AddNamespace(
"rd""http://schemas.microsoft.com/SQLServer/reporting/reportdesigner");
InBlock.gif
InBlock.gif                XmlNode xnFieldTemp 
= sourceDoc.SelectSingleNode("/a:Report/a:DataSets/a:DataSet/a:Fields/a:Field",manager);
InBlock.gif                XmlNode xnDataSet 
= xnFieldTemp.ParentNode;
InBlock.gif
InBlock.gif                
int fieldCount = ds.Tables["ReportFields"].Columns.Count;
InBlock.gif                
InBlock.gif                xnFieldTemp.Attributes[
"Name"].Value = ds.Tables["DataTableReport"].Columns[0].ColumnName;
InBlock.gif                xnFieldTemp[
"DataField"].InnerText = ds.Tables["DataTableReport"].Columns[0].ColumnName;
InBlock.gif                xnFieldTemp[
"rd:TypeName"].InnerText = ds.Tables["DataTableReport"].Columns[0].DataType.ToString();
InBlock.gif
InBlock.gif                
for (int i =1 ; i<fieldCount;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    XmlNode xnNewField 
= xnFieldTemp.Clone();
InBlock.gif                    xnNewField.Attributes[
"Name"].Value = ds.Tables["DataTableReport"].Columns[i].ColumnName;
InBlock.gif                    xnNewField[
"DataField"].InnerText = ds.Tables["DataTableReport"].Columns[i].ColumnName;
InBlock.gif                    xnNewField[
"rd:TypeName"].InnerText = ds.Tables["DataTableReport"].Columns[i].DataType.ToString();
InBlock.gif                    xnDataSet.AppendChild(xnNewField);
ExpandedSubBlockEnd.gif                }

InBlock.gif                
InBlock.gif                sourceDoc.Save(objfilepath);
InBlock.gif                
ExpandedSubBlockEnd.gif            }

InBlock.gif            
catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                System.Console.WriteLine(e.ToString());
InBlock.gif                
throw;
ExpandedSubBlockEnd.gif            }

InBlock.gif
ExpandedBlockEnd.gif        }

None.gif
None.gif        
None.gif        
private  DataSet GetSPStructure( string  sp)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {                        
InBlock.gif            DataSet tempData 
= new DataSet();
InBlock.gif            System.Data.SqlClient.SqlCommand sqlSelectCommand1 
= new System.Data.SqlClient.SqlCommand();
InBlock.gif            System.Data.SqlClient.SqlDataAdapter sqlQuery 
= new System.Data.SqlClient.SqlDataAdapter() ;
InBlock.gif            sqlSelectCommand1.CommandText 
= "[sp_sproc_columns]";
InBlock.gif            sqlSelectCommand1.CommandType 
= System.Data.CommandType.StoredProcedure;
InBlock.gif            sqlSelectCommand1.Connection 
= this.conn;
InBlock.gif            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));
InBlock.gif            sqlSelectCommand1.Parameters.Add(
new System.Data.SqlClient.SqlParameter("@procedure_name", System.Data.SqlDbType.NVarChar, 390));
InBlock.gif            sqlQuery.SelectCommand 
= sqlSelectCommand1;
InBlock.gif            sqlSelectCommand1.Parameters[
"@procedure_name"].Value = sp;
InBlock.gif            sqlQuery.Fill(tempData,
"Parameters");
InBlock.gif
InBlock.gif            
string sql="exec " + sp + " @EditionIDs='-2'";
InBlock.gif            
for (int i=1;i<tempData.Tables[0].Rows.Count-1;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
string Type_Name = tempData.Tables[0].Rows[i]["TYPE_NAME"].ToString();
InBlock.gif                
string Para_Name = tempData.Tables[0].Rows[i]["COLUMN_NAME"].ToString();
InBlock.gif                
if (Type_Name=="int")
InBlock.gif                    sql
=sql + "," + Para_Name + "=0";
InBlock.gif                
if (Type_Name=="nvarchar" || Type_Name=="varchar" || Type_Name=="nchar" || Type_Name=="char")
InBlock.gif                    sql
=sql + "," + Para_Name + "=''";
InBlock.gif                
if (Type_Name=="datetime")
InBlock.gif                    sql
=sql + "," + Para_Name + "='1900-01-01'";
ExpandedSubBlockEnd.gif            }

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


对原系统的改造应该不会有多大,Reprot Template Main Window 提供一个选择rdlc文件的combobox。在ReportOutpot window,砍掉以前的代码,放个ReportViewer上去,加上以下代码:这了copy了一点别人的代码,望事主见谅。
None.gif private   void  ViewReport(DataSet dsReport, string  templatfullpath)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif
InBlock.gif            XmlDocument sourceDoc 
= new XmlDocument();
InBlock.gif            sourceDoc.Load(templatfullpath);
InBlock.gif            MemoryStream ms 
= new MemoryStream();
InBlock.gif            XmlSerializer serializer 
= new XmlSerializer(typeof(XmlDocument));
InBlock.gif            serializer.Serialize(ms, sourceDoc);
InBlock.gif            ms.Position 
= 0;
InBlock.gif
InBlock.gif            
this.reportViewer1.LocalReport.LoadReportDefinition(ms);
InBlock.gif            
this.reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSetReport", dsReport.Tables[0]));
InBlock.gif            
this.reportViewer1.LocalReport.Refresh();
InBlock.gif            
this.reportViewer1.RefreshReport();
InBlock.gif 
ExpandedBlockEnd.gif        }

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

posted on 2006-10-24 01:05  Gun 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/Gun/archive/2006/10/24/537810.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值