有几个报表, 查询条件都一样,仅仅里面GridView中有几个列区别,以前图快,就把原来Report.aspx文件拷贝一份,改名为Report1.aspx,然后,修改里面的column,然后再由后台库查出数据,填充到这个report中来。
今天终于不耐烦了,这个方法确实太笨了,改一改,方案如下:
1.创建一个IReport的接口,所有的report都实现这个接口。
    public interface IReport
    {
        // 该report所有可用列集合(每一次查询不一定全部显示)
        Dictionary<string, string> DictColMapping { get; }        
// (本次查询)该report显示的列KeyField和HeaderText集合
Dictionary<string, int> DictColIndexMapping { get; }
        /// (本次查询)该report显示的列SortExpressField和所在位置Index集合
List<ReportColumn> ReportColumnCollection { get; }
        // 导出excel的文件名
        string ToExcelName { get; }
        // 该report的唯一编号,用于安全验证
        string ReportResourceID { get; }
        // 产生report,输入条件为一个参数数组
        DataSet ProccessReport(params object[] ParamList);
    }
2.创建一个ReportColumn类。
    public class ReportColumn
    {
        public string ColumnDataField { set; get; }
        public string ColumnHeaderText { set; get; }
        public string ColumnSortExpression { set; get; }
        public int ColumnIndex { set; get; }
        public ReportColumn(string _ColumnDataField, string _ColumnHeaderText, string _ColumnSortExpression, int _ColumnIndex)
        {
            this.ColumnDataField = _ColumnDataField;
            this.ColumnHeaderText = _ColumnHeaderText;
            this.ColumnSortExpression = _ColumnSortExpression;
            this.ColumnIndex = _ColumnIndex;
        }
    }
3.创建报表的抽象基类,里面放些处理类似报表的通用方法。
  public abstract class clsReportBase
  {}
4.创建实际的报表类
   public class clsReport_SalesOrder : clsReportBase, IReport
    {
        private List<ReportColumn> _ReportColumnCollection; //该report所有可用列集合(每一次查询不一定全部显示)
        private Dictionary<string, string> _DictColMapping; //(本次查询)该report显示的列KeyField和HeaderText集合 
        private Dictionary<string, int> _DictColIndexMapping; //(本次查询)该report显示的列SortExpressField和所在位置Index集合        
        public clsReport_SalesOrder()
        {
            _ReportColumnCollection = new List<ReportColumn>();
            _DictColMapping = new Dictionary<string, string>();
            _DictColIndexMapping = new Dictionary<string, int>();            
            FillReportColumnCollection();
        }
        /// <summary>
        /// 填充该report所有可用列集合
        /// </summary>
        private void FillReportColumnCollection()
        {
            AddColumnToCollection(new ReportColumn("Province", "省", "省", 0));
            AddColumnToCollection(new ReportColumn("Vertical", "行业", "行业", 1));
            AddColumnToCollection(new ReportColumn("ProductLine", "产品", "产品", 2));
            AddColumnToCollection(new ReportColumn("Subtotal", "订单额($)", "订单额($)", 3));
        }
        /// <summary>
        /// 该report所有可用列集合(每一次查询不一定全部显示)
        /// </summary>
        public List<ReportColumn> ReportColumnCollection
        {
            get
            {
                return _ReportColumnCollection;
            }
        }
        /// <summary>
        /// (本次查询)该report显示的列KeyField和HeaderText集合 
        /// </summary>
        public Dictionary<string, string> DictColMapping
        {
            get
            {
                return _DictColMapping;
            }
        }
        /// <summary>
        /// (本次查询)该report显示的列SortExpressField和所在位置Index集合
        /// </summary>
        public Dictionary<string, int> DictColIndexMapping
        {
            get
            {
                return _DictColIndexMapping;
            }
        }        
        /// <summary>
        /// (本次查询)该report需要格式化为货币的列集合
        /// </summary>
        public List<string> MoneyFormatColumnCollection
        {
            get
            {
                return _MoneyFormatColumnCollection;
            }
        }
        /// <summary>
        /// report名称
        /// </summary>
        public string ToExcelName
        {
            get
            {
                return "订单统计.xls";
            }
        }
        /// <summary>
        /// report唯一编码
        /// </summary>
        public string ReportResourceID 
        { 
            get 
            {
                return "12345";
            } 
        }
        private void AddColumnToCollection(ReportColumn column)
        {
            _ReportColumnCollection.Add(column);
            _DictColMapping.Add(column.ColumnDataField, column.ColumnHeaderText);
            _DictColIndexMapping.Add(column.ColumnSortExpression, column.ColumnIndex);
        }
        /// <summary>
        /// 产生report,输入条件为一个参数数组
        /// </summary>
        /// <param name="ParamList"></param>
        /// <returns></returns>
        public DataSet ProccessReport(params object[] ParamList)
        {
             ...从ParamList参数列表里解析出查询条件,然后从数据库取数据。
        }
}
5.前台aspx页面里的GridView
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false"  CellPadding="2" CssClass="autoTable" AllowSorting="false">
 <Columns>
 </Columns>
</asp:GridView>
6.在前台aspx.cs页面里,通过url传来的报表类名,反射出报表的实例。
   protected void Page_Load(object sender, EventArgs e)
    {
        _InitReport(this.Request.QueryString["Report"]);
}
    private void _InitReport(string QueryString)
    {
        string reportClassName = QueryString;
        string reportAssemblyName = "Test";
        string reportFullClassName = reportAssemblyName + "." + reportClassName;
        report = (IReport)Assembly.Load(reportAssemblyName).CreateInstance(reportFullClassName);    
        _DictColMapping = new Dictionary<string, string>();
        _DictColMapping = report.DictColMapping;
        _DictColIndexMapping = new Dictionary<string, int>();
        _DictColIndexMapping = report.DictColIndexMapping;
        GridView1.Columns.Clear();
        foreach (ReportColumn column in report.ReportColumnCollection)
        {
            BoundField bf = new BoundField();
            bf.DataField = column.ColumnDataField;
            bf.HeaderText = column.ColumnHeaderText;
            bf.SortExpression = column.ColumnSortExpression;
            bf.HeaderStyle.Wrap = false;
            bf.ItemStyle.Wrap = false;
            GridView1.Columns.Add(bf);
        }
    }
    protected void btn_Search_Click(object sender, EventArgs e)
    {
        object[] arr = new object[] { UserObject, ConditionObject ... };
        DataSet m_Data = report.ProccessReport(arr); 
HideSomeColumns(m_Data); //如果需要,可以在此屏蔽不显示的列,设置列visiable=false.
        this.GridView_SalesOrderSummarization.DataSource = m_Data.Tables[0];
        this.GridView_SalesOrderSummarization.DataBind();
    }
 
7.这样, 就只用一个aspx文件文成多个报表了, 只要把类型当作参数传过来即可.
Report.aspx?Report=clsReport_SalesOrder 
Report.aspx?Report=clsReport_SalesOrder2
这样就精简了前台aspx的程序数量, 方便了以后系统的维护.