zoukankan      html  css  js  c++  java
  • 实战篇通用的页面列表导出Excel控件

    首先,先上下图片,好理解一下今天要讲内容:

    第一张图:

    第二张图:

    说明:

    在很多系统中,或者是一些网站的后台,包括秋色园的后台,通过都会有一些相同的工具栏目,比如上面的“导出”按钮,由于分布在系统大量的列表中,

    因此,如何以最简洁快速的方式实现这种功能,节省开发时间,就是今天以下要介绍的内容了。

    接着我们再看一下点击“导出”按钮时出现的导出功能:

    打开导出的Excel:

    说明:

    从以上四张图片中,所要说明的问题是:

    “导出”功能在N个界面中重复出现,如何实现“导出”功能的代码只写一次,就能在任意的界面中,实现导出当前页面列表的功能。

    下面正文讲解如何实现:

    一:实现思路

     

    对于列表的导出,有以下两种方式:

    1:从客户端取数据导出:

    在我的同事负责的一个基于ExtJs开发的系统中,是在客户端进行导出形成报表的,

    当然,使用这种方式,他有他的系统使用场景前提,

    即是:每次查询都显示所有信息,不进行分页,所以不需要再提交到服务端再次查询,直接从客户端取数据即可以导出。

    当然缺点就是:对于分页显示的数据,只能导出当前页,因此只适用于一次显示所有数据的场景下。

    2:从服务端取数据导出:

    由于相当多的时候,列表总是分页的,因此,需要重新提交到服务端查询所有数据,然后进行输出,如果只针对一个页面进行处理,通常写代码考虑的可以少一点,

    不过今天要实现的功能,只需要把控件往里一拖,即可自动实现导出功能,无需在页面写任何代码,因此,需要有一些标准的约定出来配合一下。

    那具体实现的思路方式如何?

    其实思路很简单,只要约定绑定列表的方法名称和列表控件默认的ID即可。

    简单的说,点击“导出”按钮时,可以通过反射,进行重新绑定,然后通过重新绑定后的控件ID,取得内部生成的html,进行Excel导出即可。

    二:实现步骤

     

    具体的实现步骤如下:

    1:新建用户控件,往里拉一个“导出”按钮。

    2:在“导出”按钮点击事件中:寻找约定的列表控件如"rptList",找到后反射调用约定的方法如“BindList",调用后rptList将被填充完内容。

    3:读取rptList控件的内部html,进行导出。

    三:完整示例实现代码

     

    1:新建示例网站项目如:ExcelExportDemo

     

    2:往里新建用户控件:Export.ascx 示例中只放一个“导出”按钮

     

    html如下:

    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="Export.ascx.cs" Inherits="Export" %>
    <asp:Button ID="btnExportToXLS" runat="server" Text="导出" OnClick="btnExportToXLS_Click" />

    点击时的后台代码如下:

        protected void btnExportToXLS_Click(object sender, EventArgs e)
        {
            Control ct 
    = this.Page.FindControl("rptList");
            
    if (ct != null)
            {
                MethodInfo mi 
    = this.Page.GetType().GetMethod("BindList", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                
    if (mi != null)
                {
                    mi.Invoke(
    this.Page, null);
                }
                Toolkit.ExcelHelper.ExportToXLS(ct);
            }
        }

    代码相当简洁,有两个约定的名称分别为:"rptList"与"BindList"

     

    接下来是分解的导出Excel的代码:

        public class ExcelHelper
        {
            
    public static void ExportToXLS(params Control[] ctList)
            {
                HttpContext.Current.Response.Clear();
                HttpContext.Current.Response.ContentEncoding 
    = System.Text.Encoding.GetEncoding("gb2312");
                HttpContext.Current.Response.Write(
    "<meta http-equiv=Content-Type content=text/html;charset=gb2312>");
                HttpContext.Current.Response.AppendHeader(
    "content-disposition""attachment;filename=report.xls");
                HttpContext.Current.Response.ContentType 
    = "application/vnd.ms-excel";
                StringBuilder sb 
    = new StringBuilder();
                sb.Append(
    "<head><style>table td,th{vnd.ms-excel.numberformat:@;text-align: center;} table th{color:red}</style></head>");//先增加格式化td为文本格式
                System.IO.StringWriter sw = new System.IO.StringWriter();
                HtmlTextWriter htw 
    = new HtmlTextWriter(sw);
                ctList[0].RenderControl(htw);
                sb.Append(sw.ToString());
                sw.Close();
                HttpContext.Current.Response.Write(sb.ToString());
                HttpContext.Current.Response.End();
            }
        }

    注意下编码,以防乱码即可。

    OK,以上的代码就已完成了一个通用的导出列表按钮了,接下来我们继续完善这个示例,增加列表展示并把列表导出来。

     

    3:直接拿了上节 带线的无限级下拉树列表-完整示例篇 中的数据库,用来展示数据

     

    为方便示例,仍用Access数据库,还是上次的Product表,并为之添加了几行数据,如图:

     

    接着项目添加引用 CYQ.Data 数据框架 来实现数据库操作列表展示:

    由于只是示例展示列表应用,就不生成枚举了。

    引用后项目结构如下图所示:

     

    4:在Default.aspx页面中,添加一个GridView控件,同时将导出的用户控件拉进去:

    html如下:

    <body>
        
    <form id="form1" runat="server">
        
    <div>
            
    <asp:GridView ID="rptList" runat="server"></asp:GridView>
            
    <br />
            
    <uc1:Export ID="Export1" runat="server" />
        
    </div>
        
    </form>
    </body>

    后台实现列表绑定代码:

        protected void Page_Load(object sender, EventArgs e)
        {
            
    if (!IsPostBack)
            {
                BindList();
            }
        }
        
    protected void BindList()
        {
            
    using (MAction action = new MAction("Product"))
            {
                action.Select().Bind(rptList);
            }
        }
        
    public override void VerifyRenderingInServerForm(Control control)
        {
            
    //不引发"控件必须放在具有 runat=server 的窗体标记内“验证
            
    //---------这个可以放在PageBase中处理
        }

    至此,整个示例就结束了,我们浏览看一下结果,如下图:

    点击导出按钮,出来Excel文件:

    打开Excel文件,就是当前列表的数据了。

    四:总结

    从以上的整体示例中,具体页面并没有导出按钮相关的后台代码,而只要按约定将列表控件的ID写成rptList,同时负责绑定数据所方法名称为BindList。

    即可以实现导出功能。

    五:扩展与其它说明

     

    1:也许要导出一个页面中并不止一个列表,可能是多个列表,这个的扩展,其实并不难:

    思路:只要在BindList里绑定N个列表控件,同时把约定控件名称设为多个,加个循环而已。

    2:当前示例中没有分页,那分页如何处理?其实也不难:

    思路:只要在分页控件中,通过判断是否“导出”事件,来定位分页的索引即可。

    比如用下面常见的带分页的代码:

        protected void BindList()
        {
            
    using (MAction action = new MAction("Product"))
            {
                
    int count;
                action.Select(Pager1.PageIndex,Pager1.PageSize,
    string.Empty,out count).Bind(rptList);
            }
        }

    页面中没有任何代码变化,只要在Pager1这个分页控件中,通过判断来定位PageIndex和PageSize即可。

    比如在获取PageIndex时,判断是否“导出”事件,然后将索引返回1或0,具体看应用的框架需要返回值。

    同样在获取PageSize时,判断是否“导出”事件,然后将索引返回0或无穷大,具体也看应用的框架需要返回值。

    最后是示例下载:点击进入下载页面

  • 相关阅读:
    HDU 5818 Joint Stacks
    HDU 5816 Hearthstone
    HDU 5812 Distance
    HDU 5807 Keep In Touch
    HDU 5798 Stabilization
    HDU 5543 Pick The Sticks
    Light OJ 1393 Crazy Calendar (尼姆博弈)
    NEFU 2016省赛演练一 I题 (模拟题)
    NEFU 2016省赛演练一 F题 (高精度加法)
    NEFU 2016省赛演练一 B题(递推)
  • 原文地址:https://www.cnblogs.com/cyq1162/p/1940836.html
Copyright © 2011-2022 走看看