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或无穷大,具体也看应用的框架需要返回值。

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

  • 相关阅读:
    Flex AIR应用GPS定位功能(Android和IOS)
    Flex AIR应用拍照功能(Android和IOS版本)
    读取Flex AIR应用程序设置
    查看本机开放的端口号,查看某个端口号是否被占用,查看被占用的端口号被哪个进程所占用,如何结束该进程
    Eclipse设置默认编码为UTF-8
    Eclipse使用教程之精华篇
    hdu 1829 分组并查集
    hdu 1316高精度
    hdu 4287 字典树问题
    hdu 1867 kmp共工前后缀串问题
  • 原文地址:https://www.cnblogs.com/cyq1162/p/1940836.html
Copyright © 2011-2022 走看看