ExtAspNet应用技巧(十) - Grid导出为Excel文件(续)

原创|其它|编辑:郝浩|2009-08-26 11:33:58.000|阅读 1463 次

概述:这个其实是开发中经常遇到的问题,大家也都知道其实所谓导出到Excel文件,最简单的做法就是把一个table的HTML片段输出,下面通过一个简单的例子来说明这个问题。

# 界面/图表报表/文档/IDE等千款热门软控件火热销售中 >>

轻车熟路
书接上文,如何在使用ExtAspNet控件库的页面将Grid内容导出为Excel文件?

1. 页面声明

01.<ext:PageManager ID="PageManager1" runat="server" />
02.Grid Control in ExtAspNet:
03.<ext:Grid ID="Grid1" Title="表格" ShowBorder="true" ShowHeader="true" Width="900px"
04.    AutoHeight="true" runat="server" EnableCheckBoxSelect="true" DataKeyNames="Id,Year,MyText"
05.    EnableRowNumber="True">
06.    <Columns>
07.        <ext:BoundField DataTooltipField="MyText" Width="200px" DataField="MyText" DataFormatString="{0}"
08.            HeaderText="MyText" ExpandUnusedSpace="True" />
09.        <ext:BoundField ColumnId="column1" Width="100px" DataField="MyValue" HeaderText="MyValue" />
10.        <ext:BoundField Width="60px" DataField="Year" HeaderText="Year" />
11.        <ext:CheckBoxField DataTooltipField="MyText" Width="60px" RenderAsStaticField="true"
12.            DataField="MyCheckBox" HeaderText="CheckBox" />
13.        <ext:HyperLinkField DataTooltipField="MyText" Width="200px" HeaderText="HyperLink"
14.            DataTextField="MyText" DataTextFormatString="{0}" DataNavigateUrlFields="Id,MyValue"
15.            DataNavigateUrlFormatString="http://www.google.com/?id={0}&page={1}" Target="_blank"
16.            NavigateUrl="~/alert.aspx" Text="链接" />
17.        <ext:TemplateField HeaderText="TemplateField">
18.            <ItemTemplate>
19.                <%# GetMyValue(DataBinder.Eval(Container.DataItem, "[MyValue]")) %>
20.            </ItemTemplate>
21.        </ext:TemplateField>
22.        <ext:ImageField DataTooltipField="MyText" Width="60px" DataImageUrlField="MyValue"
23.            DataImageUrlFormatString="~/images/16/{0}.gif" HeaderText="Image"></ext:ImageField>
24.    </Columns>
25.</ext:Grid>
26.<br />
27.<ext:Button ID="Button1" EnableAjax="false" 
28.    runat="server" Text="导出ExtAspNet控件Grid到Excel文件" OnClick="Button1_Click">
29.</ext:Button>


这里需要说明一点:因为点击“导出”按钮会改变响应消息头,使用AJAX就不合适了。所以我们设置Button的EnableAjax="false",当然你也可以设置PageManager的这个属性,那会影响整个页面。

2. 后台数据绑定。这个同样省略,无非是从数据库读出一个DataTable或者List绑定到Grid控件。

3. 生成的页面: 


4. 点击导出按钮的事件处理

01.protected void Button1_Click(object sender, EventArgs e)
02.{
03.    Response.ClearContent();
04.    Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");
05.    Response.ContentType = "application/excel";
06.    StringWriter sw = new StringWriter();
07.    HtmlTextWriter htw = new HtmlTextWriter(sw);
08.    Grid1.RenderControl(htw);
09.    Response.Write(sw.ToString());
10.    Response.End();
11.}



5. 生成的MyExcelFile.xls文件(用记事本打开):

1.<div id="Grid1_wrapper" style="display:inline;"></div>





问题出现

如果你理解Extjs的工作原理的话,这个结果并不奇怪。
Grid渲染到页面中的只有一个简单的DIV标签,至于内部的所有的内容都是通过JavaScript来生成的,这个JavaScript就隐藏在页面的底部,如果你观察过ExtAspNet生成的页面的话,你能看到类似的Grid初始化代码: 


看来对于使用extjs的ExtAspNet控件而言,我们不能照搬Asp.Net中的GridView的模式,我们需要...



另辟蹊径

仔细观察Button1_Click事件处理函数,它做的事情很简单 - 向输出流写入一个字符串,这个字符串就是一个HTML的表格。那我们何不手工来生成这个表格?

不用怕,问题没有你想的那么复杂:

01.protected void Button1_Click(object sender, EventArgs e)
02.{
03.    Response.ClearContent();
04.    Response.AddHeader("content-disposition", "attachment; filename=MyExcelFile.xls");
05.    Response.ContentType = "application/excel";
06.    Response.Write(GetGridTableHtml(Grid1));
07.    Response.End();
08.}
09.private string GetGridTableHtml(Grid grid)
10.{
11.    StringBuilder sb = new StringBuilder();
12.    sb.Append("<table cellspacing=\"0\" rules=\"all\" border=\"1\" style=\"border-collapse:collapse;\">");
13.    sb.Append("<tr>");
14.    foreach (GridColumn column in grid.Columns)
15.    {
16.        sb.AppendFormat("<td>{0}</td>", column.HeaderText);
17.    }
18.    sb.Append("</tr>");
19.    foreach (GridRow row in grid.Rows)
20.    {
21.        sb.Append("<tr>");
22.        foreach (object value in row.Values)
23.        {
24.            string html = value.ToString();
25.            sb.AppendFormat("<td>{0}</td>", html);
26.        }
27.        sb.Append("</tr>");
28.    }
29.    sb.Append("</table>");
30.    return sb.ToString();
31.}



不就是生成一个HTML的表格嘛,这个事情我做过无数次了,拍拍手来看下成果: 




继续优化

还是两个地方不满意,我们看下CheckBox的那个地方生成的HTML代码:

1.<!-- 选中的CheckBox -->
2.<div ext:qtip="item2" class="box-grid-static-checkbox">
3.</div>
4.<!-- 没有选中的CheckBox -->
5.<div ext:qtip="item3,我是一个很厉害的程序员。" class="box-grid-static-checkbox box-grid-static-checkbox-uncheck">
6.</div>


可见这里并没有像Asp.Net的GridView那样生成 input type="checkbox" 的标签,而是通过CSS样式来控制是否选中(说白了就是不同的背景图片)。

有了这些认识后,优化也很简单:

01.private string GetGridTableHtml(Grid grid)
02.{
03.    StringBuilder sb = new StringBuilder();
04.    sb.Append("<table cellspacing=\"0\" rules=\"all\" border=\"1\" style=\"border-collapse:collapse;\">");
05.    sb.Append("<tr>");
06.    foreach (GridColumn column in grid.Columns)
07.    {
08.        sb.AppendFormat("<td>{0}</td>", column.HeaderText);
09.    }
10.    sb.Append("</tr>");
11.    foreach (GridRow row in grid.Rows)
12.    {
13.        sb.Append("<tr>");
14.        foreach (object value in row.Values)
15.        {
16.            string html = value.ToString();
17.            // 处理CheckBox
18.            if (html.Contains("box-grid-static-checkbox"))
19.            {
20.                if (html.Contains("box-grid-static-checkbox-uncheck"))
21.                {
22.                    html = "×";
23.                }
24.                else
25.                {
26.                    html = "√";
27.                }
28.            }
29.            // 处理图片
30.            if (html.Contains("<img"))
31.            {
32.                html = html.Replace("src=\"/extaspnet/", "src=\"http://localhost/extaspnet/");
33.            }
34.            sb.AppendFormat("<td>{0}</td>", html);
35.        }
36.        sb.Append("</tr>");
37.    }
38.    sb.Append("</table>");
39.    return sb.ToString();
40.}



再来看下生成的XLS文件,这已经是我们想要的结果了。 



修正一个小BUG

还有一个小问题,就是在导出文件之后,按钮不可点击了,如下所示: 


其实这是ExtAspNet的一个内置特性,是为了防止重复点击同一个按钮两次。一般情况下在AJAX之后系统会自动让此按钮可点击(非AJAX页面会刷新)。

但是这里有点特殊,导出Excel文件并没有导致页面刷新,所以我们需要给Button设置一个属性,使其在点击时不要变灰。

1.<ext:Button ID="Button1" EnableAjax="false" DisableControlBeforePostBack="false"
2.    runat="server" Text="导出ExtAspNet控件Grid到Excel文件" OnClick="Button1_Click">
3.</ext:Button>




全部源代码可以从这里下载,在文件夹data\grid_excel_run.aspx中。
注意:如果想运行本章中提到的程序,ExtAspNet版本需大于v2.0.6。


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@evget.com

文章转载自:博客园

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP