zoukankan      html  css  js  c++  java
  • 在ASP.NET Web Forms中使用页面导出伪xls Excel表格

    将数据导出为Excel表格是比较常见的需求,也有很多组件支持导出真正的Excel表格。由于Excel能打开HTML文件,并支持其中的table元素以及p之类的文本元素的显示,所以把.html扩展名改为.xls是比较常用的一种方式。当然这只是一种骗人的伎俩,所以我称之为伪xls表格。不过对于要求不高的需求,这种方法还是比较简单快捷的。

    在Web Forms项目中,除了用代码拼凑HTML元素标记外,还可以直接用窗体页面渲染HTML表格。Web Forms就是用来渲染动态HTML的,直接利用它,支持代码提示、智能感知,何乐而不为呢?

    现在就做一个用于导出表格的页面。为了实现代码复用,应该设计一个这样的类:它继承自Page基类,把它用作页面代码隐藏类的基类,只要执行这个页面,就能直接导出伪xls表格。实现代码如下:

    using System;
    using System.Web;
    using System.Web.UI;
    
    namespace FakeXlsExportWebForms
    {
        /// <summary>
        /// 导出伪xls文件的页面基类。
        /// 用于导出表格文件的页面应该继承此类,并在页面生成表格元素。
        /// 重定向到派生类页面即可导出表格。
        /// </summary>
        public class FakeXlsPage : Page
        {
            protected string FileName { get; set; } = Guid.NewGuid().ToString();
    
            public FakeXlsPage()
            {
                // 不能注册更早的页面事件,否则文件名设置无效
                PreRender += (s, e) =>
                {
                    Response.ContentType = "application/vnd.ms-excel";
                    // 调用UrlEncode方法以编码中文,防止浏览器显示文件名乱码
                    string fileName = HttpUtility.UrlEncode(FileName + ".xls");
                    Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName);
                };
            }
        }
    }

    有了这个类,只消新建页面,修改基类,然后在页面上生成table元素即可。下面看一个实际的例子,导出一些学生信息。

    首先建立一个表示表格数据模型的类:

    namespace FakeXlsExportWebForms
    {
        public class Student
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public char Gender { get; set; }
            public int Age { get; set; }
            public double ChineseScore { get; set; }
            public double MathScore { get; set; }
            public double EnglishScore { get; set; }
        }
    }

    然后新建一个用于生成表格的页面,其页面代码如下:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="XlsExport.aspx.cs" Inherits="FakeXlsExportWebForms.XlsExport" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title></title>
    </head>
    <body>
        <%-- 设置border="1"以显示表格框线 --%>
        <table border="1">
            <%-- caption元素可以生成表标题,其单元格列跨度为表格的列数 --%>
            <caption>学生成绩表</caption>
            <tr>
                <%-- 可以使用rowspan和colspan来合并单元格 --%>
                <th rowspan="2">编号</th>
                <th rowspan="2">学号</th>
                <th rowspan="2">姓名</th>
                <th rowspan="2">性别</th>
                <th rowspan="2">年龄</th>
                <th colspan="3">成绩</th>
            </tr>
            <tr>
                <th>语文</th>
                <th>数学</th>
                <th>英语</th>
            </tr>
            <asp:Repeater ID="rptStudents" ItemType="FakeXlsExportWebForms.Student" SelectMethod="GetStudents" runat="server">
                <ItemTemplate>
                    <tr>
                        <td><%# Container.ItemIndex + 1 %></td>
                        <td><%# Item.Id %></td>
                        <td><%# Item.Name %></td>
                        <td><%# Item.Gender %></td>
                        <td><%# Item.Age %></td>
                        <td><%# Item.ChineseScore %></td>
                        <td><%# Item.MathScore %></td>
                        <td><%# Item.EnglishScore %></td>
                    </tr>
                </ItemTemplate>
            </asp:Repeater>
        </table>
        <%-- 表格后面的文字可作为表注,不要把它包含在p元素中,否则表格与表注之间会有一行空行 --%>
        注:共计<%= rptStudents.Items.Count %>人。
    </body>
    </html>

    其后台代码如下,页面的基类已修改,并且其中包含页面中的Repeater控件使用的数据方法:

    using System;
    using System.Collections.Generic;
    
    namespace FakeXlsExportWebForms
    {
        public partial class XlsExport : FakeXlsPage
        {
            public void Page_Load(object sender, EventArgs e)
            {
                // 设置基类的文件名属性
                FileName = "学生成绩表";
            }
    
            public IEnumerable<Student> GetStudents()
            {
                // 简单生成一些测试数据
                for (int i = 0; i < 10; i++)
                {
                    yield return new Student
                    {
                        Id = 2016000 + i + 1,
                        Name = "学生" + (i + 1),
                        Gender = i % 2 == 0 ? '' : '',
                        Age = 10 + i,
                        ChineseScore = 90 + i,
                        MathScore = 80 + i,
                        EnglishScore = 70 + i
                    };
                }
            }
        }
    }

    现在直接打开这个页面,浏览器就会下载表格文件了。也可以定义一个普通页面,在其中定义一个用于导出表格的链接:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="FakeXlsExportWebForms.Default" %>
    
    <!DOCTYPE html>
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title></title>
    </head>
    <body>
        <asp:HyperLink NavigateUrl="~/XlsExport.aspx" runat="server">导出学生成绩表</asp:HyperLink>
    </body>
    </html>

    效果如图,点击链接,浏览器会下载表格文件:

    打开文件如图:

    不过话说回来,这种方式导出的表格还是有很多缺点的,比如:

    1. Excel 2003能直接打开,高版本的Excel会提示格式不正确,但点“是”之后也能打开;
    2. 包含数据的单元格以外的单元格不显示边框;
    3. 编辑导出的表格之后,直接保存会提示格式问题,如果确定保存,会生成另一个文件夹(如下图,伪xls文件现在需要此文件夹中的文件),导致表格文件不能通过一个单独的文件来维护。当然可以将其另存为真正的Excel文件,只要你的客户不会怨声载道。

  • 相关阅读:
    微信公众号对接配置
    ASP.NET MVC5+EF6+EasyUI 后台管理系统(89)-国际化,本地化,多语言应用
    Nacos安装教程
    IDEA 中创建SpringBoot 父子模块
    解决死锁之路(终结篇)
    CentOS安装node和npm
    CentOS安装RabbitMQ
    在LibreOffice中插入代码
    PowerShell查找程序路径
    使用命令行调用控制面板的选项
  • 原文地址:https://www.cnblogs.com/zhuxinghan/p/6012031.html
Copyright © 2011-2022 走看看