现在的位置: 首页 > 综合 > 正文

用反射简化 asp.net 报表的一点总结

2013年05月31日 ⁄ 综合 ⁄ 共 6056字 ⁄ 字号 评论关闭

有几个报表, 查询条件都一样,仅仅里面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的程序数量, 方便了以后系统的维护.

 

抱歉!评论已关闭.