最近在项目中需要Excel导出,有多个Sheet页,每个Sheet页的内容比较多,且不是规整的表格,绑定值是个比较麻烦的事,便考虑直接将HTML转换为Excel文件进行导出。

一、使用JS方法将HTML导出为Excel

原理就是获取需要导出到Excel的HTML代码,然后利用JS方法进行导出。此代码可以兼容IE8及主流浏览器,但是不支持多个Sheet页的导出,在IE8下也不能自定义Sheet页的名字。

<li>
<button id="btnExport" class="btn btn-primary" onclick="javascript:HtmlExportToExcel('mainContent')">
导出
</button>
<a id="dlink" style="display: none;"></a>
</li>
//jQuery HTML导出Excel文件(兼容IE及所有浏览器)
function HtmlExportToExcel(tableid) {
var filename = $('#divTitle').text();
var sheetName = "已开展工作情况";
if (getExplorer() == 'ie' || getExplorer() == undefined) {
HtmlExportToExcelForIE(tableid, filename,sheetName);
}
else {
HtmlExportToExcelForEntire(tableid, filename,sheetName)
}
} //IE浏览器导出Excel
function HtmlExportToExcelForIE(tableid, filename,sheetName) {
try {
var winname = window.open('', '_blank', 'top=10000');
var strHTML = $("#" + tableid).html(); winname.document.open('application/vnd.ms-excel', 'export excel');
winname.document.writeln(strHTML);
winname.document.execCommand('saveas', '', filename + '.xls');
winname.close(); } catch (e) {
alert(e.description);
}
} //非IE浏览器导出Excel
var HtmlExportToExcelForEntire = (function () {
var uri = 'data:application/vnd.ms-excel;base64,',
template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>',
base64 = function (s) { return window.btoa(unescape(encodeURIComponent(s))) },
format = function (s, c) { return s.replace(/{(\w+)}/g, function (m, p) { return c[p]; }) }
return function (table, name,sheetName) {
if (!table.nodeType) { table = $("#" + table); }
var ctx = { worksheet: sheetName || 'Worksheet', table: table.html() };
document.getElementById("dlink").href = uri + base64(format(template, ctx));
document.getElementById("dlink").download = name + ".xls";
document.getElementById("dlink").click();
}
})()
function getExplorer() {
var explorer = window.navigator.userAgent;
//ie
if (explorer.indexOf("MSIE") >= ) {
return 'ie';
}
//firefox
else if (explorer.indexOf("Firefox") >= ) {
return 'Firefox';
}
//Chrome
else if (explorer.indexOf("Chrome") >= ) {
return 'Chrome';
}
//Opera
else if (explorer.indexOf("Opera") >= ) {
return 'Opera';
}
//Safari
else if (explorer.indexOf("Safari") >= ) {
return 'Safari';
}
}

另外,由于生成的不是真正的Excel文件,只是把HTML转换为Excel的文件,会出现如下提示,用户体验不好。

二、利用后台方法将HTML导出为Excel

原理与第一种方法类似,也是将HTML代码导出为Excel,只是改用后台文件流方式,避免了浏览器兼容性问题。

由于也是HTML导出为Excel文件,也会出现文件扩展名不一致的提示。

思路是:点击导出按钮时,获取要导出内容的HTML代码,并放到Hidden控件中,利用Form Post提交方式传送到后台Action方法,在Action方法中构建Sheet页的Dictionary,key是SheetName,Value是Sheet的HTML代码,然后循环Dictionary生成多个Sheet页,并导出。

<form id="form1" method="post">
        @Html.Hidden("tbBMXXHTML")
        @Html.Hidden("tbBMXXTitle")
        @Html.Hidden("FileTitle")
    </form>
-------------
<li>
<button id="btnExport" class="btn btn-primary" type="submit" onclick="ExportExcel()" >
导出
</button>
</li>
//导出Excel
function ExportExcel() {
var URL = '@Url.Action("GreenCarSummaryExport", "GreenCar", new { area = "GreenCar" })';
var FileTitle = $("#divTitle").text();
$("#FileTitle").val(FileTitle); $("#tbBMXXHTML").val(encodeURI($("#tbBMXX").html()));
$("#tbBMXXTitle").val("已开展工作情况"); window.form1.action = URL;
window.form1.submit();
}
        public void GreenCarSummaryExport(FormCollection collection)
{
string tbBMXXHTML = HttpUtility.UrlDecode(collection["tbBMXXHTML"]);
string tbBMXXTitle = collection["tbBMXXTitle"];
string FileTitle = collection["FileTitle"]; Dictionary<string, string> dicSheet = new Dictionary<string, string>();
dicSheet.Add(tbBMXXTitle, tbBMXXHTML); //把HTML转换为Excel
HTMLToExcelHelper.ExportHTMLToExcel(dicSheet, FileTitle);
}
/// <summary>
/// 导出HTML为Excel文件
/// </summary>
/// <param name="dicSheet">导出内容:key是SheetName,Value是HTML代码</param>
/// <param name="fileTitle">文件名</param>
public static void ExportHTMLToExcel(Dictionary<string, string> dicSheet, string fileTitle)
{
StringBuilder sbBody = new StringBuilder();
StringBuilder sbSheet = new StringBuilder(); //定义Excel头部
sbBody.AppendFormat(
"MIME-Version: 1.0\r\n" +
"X-Document-Type: Workbook\r\n" +
"Content-Type: multipart/related; boundary=\"-=BOUNDARY_EXCEL\"\r\n\r\n" +
"---=BOUNDARY_EXCEL\r\n" +
"Content-Type: text/html; charset=\"gb2312\"\r\n\r\n" +
"<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n" +
"xmlns:x=\"urn:schemas-microsoft-com:office:excel\">\r\n\r\n" +
"<head>\r\n" +
"<xml>\r\n" +
"<x:ExcelWorkbook>\r\n" +
"<x:ExcelWorksheets>\r\n"); //定义Sheet
foreach (KeyValuePair<string, string> kv in dicSheet)
{
string gid = Guid.NewGuid().ToString();
sbBody.AppendFormat("<x:ExcelWorksheet>\r\n" +
"<x:Name>{0}</x:Name>\r\n" +
"<x:WorksheetSource HRef=\"cid:{1}\"/>\r\n" +
"</x:ExcelWorksheet>\r\n"
, kv.Key
, gid); sbSheet.AppendFormat(
"---=BOUNDARY_EXCEL\r\n" +
"Content-ID: {0}\r\n" +
"Content-Type: text/html; charset=\"gb2312\"\r\n\r\n" +
"<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n" +
"xmlns:x=\"urn:schemas-microsoft-com:office:excel\">\r\n\r\n" +
"<head>\r\n" +
"<xml>\r\n" +
"<x:WorksheetOptions>\r\n" +
"<x:ProtectContents>False</x:ProtectContents>\r\n" +
"<x:ProtectObjects>False</x:ProtectObjects>\r\n" +
"<x:ProtectScenarios>False</x:ProtectScenarios>\r\n" +
"</x:WorksheetOptions>\r\n" +
"</xml>\r\n" +
"</head>\r\n" +
"<body>\r\n"
, gid); sbSheet.Append("<table border='1'>");
sbSheet.Append(kv.Value);
sbSheet.Append("</table>");
sbSheet.Append("</body>\r\n" +
"</html>\r\n\r\n");
} //定义Excel尾部
StringBuilder sb = new StringBuilder(sbBody.ToString());
sb.Append("</x:ExcelWorksheets>\r\n" +
"</x:ExcelWorkbook>\r\n" +
"</xml>\r\n" +
"</head>\r\n" +
"</html>\r\n\r\n");
sb.Append(sbSheet.ToString());
sb.Append("---=BOUNDARY_EXCEL--"); //导出文件
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.ClearContent();
HttpContext.Current.Response.ClearHeaders();
HttpContext.Current.Response.Buffer = true;
bool isFireFox = false;
if (HttpContext.Current.Request.ServerVariables["http_user_agent"].ToLower().IndexOf("firefox") != -)
{
isFireFox = true;
}
if (isFireFox)
{
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + fileTitle + ".xls");
}
else
{
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(System.Text.Encoding.UTF8.GetBytes(fileTitle)) + ".xls");
}
HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("gb2312");
HttpContext.Current.Response.Write(sb.ToString());
HttpContext.Current.Response.End();
}

三、利用第三方插件导出

比如利用NPOI,Aspose,ExcelReport等,需要从数据库重新获取数据并绑定

C# 导出HTML为Excel的更多相关文章

  1. 1.ASP.NET MVC使用EPPlus,导出数据到Excel中

    好久没写博客了,今天特地来更新一下,今天我们要学习的是如何导出数据到Excel文件中,这里我使用的是免费开源的Epplus组件. 源代码下载:https://github.com/caofangshe ...

  2. 导出数据到Excel --使用ExcelReport有感

    先看图,这是几个月前用NPOI写的导出数据到Excel,用了上百行代码,而且难控制,导出来也比较难看 excel打开的效果 下面是我用ExcelReport类库导出到Excel的操作 1.首先引用Ex ...

  3. 使用Open xml 操作Excel系列之二--从data table导出数据到Excel

    由于Excel中提供了透视表PivotTable,许多项目都使用它来作为数据分析报表. 在有些情况下,我们需要在Excel中设计好模板,包括数据源表,透视表等, 当数据导入到数据源表时,自动更新透视表 ...

  4. Dynamics CRM导出数据到Excel

    原创地址:http://www.cnblogs.com/jfzhu/p/4276212.html 转载请注明出处 Pivot Table是微软BI的一个重要工具,所以这里讲一下Dynamics CRM ...

  5. MVC导出数据到EXCEL新方法:将视图或分部视图转换为HTML后再直接返回FileResult

    导出EXCEL方法总结 MVC导出数据到EXCEL的方法有很多种,常见的是: 1.采用EXCEL COM组件来动态生成XLS文件并保存到服务器上,然后转到该文件存放路径即可: 优点:可设置丰富的EXC ...

  6. C#实现Excel模板导出和从Excel导入数据

    午休时间写了一个Demo关于Excel导入导出的简单练习 1.窗体 2.引用office命名空间 添加引用-程序集-扩展-Microsoft.Office.Interop.Excel 3.封装的Exc ...

  7. php导出数据到excel,防止身份证等数字字符格式变成科学计数的方法

    而关于php的也有,但是大多都是用phpExcel导出的方法或者spreadsheet等类或者控件之类的导出方法,而我所在维护的系统却用很简单的方法,如下,网上很少有讲如何设置要导出数据的EXcel格 ...

  8. NPOI导出数据到Excel

    NPOI导出数据到Excel   前言 Asp.net操作Excel已经是老生长谈的事情了,可下面我说的这个NPOI操作Excel,应该是最好的方案了,没有之一,使用NPOI能够帮助开发者在没有安装微 ...

  9. 【转】c# winform DataGridView导出数据到Excel中,可以导出当前页和全部数据

    准备工作就是可以分页的DataGridView,和两个按钮,一个用来导出当前页数据到Excel,一个用来导出全部数据到Excel 没有使用SaveFileDialog,但却可以弹出保存对话框来 先做导 ...

  10. ASP.NET导出数据到Excel 实例介绍

    ASP.NET导出数据到Excel  该方法只是把asp.net页面保存成html页面只是把后缀改为xlc不过excel可以读取,接下连我看看还有别的方式能导出数据,并利用模版生成. 下面是代码 新建 ...

随机推荐

  1. linux常用命令:Linux 文件类型与扩展名

    Linux文件类型和Linux文件的文件名所代表的意义是两个不同的概念.我们通过一般应用程序而创建的比如file.txt.file.tar.gz ,这些文件虽然要用不同的程序来打开,但放在Linux文 ...

  2. Oracle提示错误消息ORA-28001: the password has expired

    首先,以SYS DBA身份进入sqlpuls 打开sqlpuls SQL->请输入用户名:sys as sysdba SQL->密码: 登录成功以后查询DBA用户状态 SQL->se ...

  3. CentOS 7 安装OpenCV

    CentOS 7 安装OpenCV步骤如下: 1.在CentOS 7命令行中直接在线安装: yum  install  numpy  opencv* 2.安装完成后进行全盘搜索:find  /  -n ...

  4. HTML 和 JavaScript 编写简单的 404 界面

    编写简单的 404 界面,也可以用来做 500 报错界面,还会飘东西,特别好,蛮漂亮的! <!DOCTYPE html> <html> <head> <met ...

  5. 函数对象与仿函数(function object and functor)

    part 1. 仿函数在STL组件中的关系 如下图: # 仿函数配合算法完成不同的策略变化. # 适配器套接仿函数. part 2. 仿函数介绍 传递给算法的“函数型实参”不一定得是函数,可以是行为类 ...

  6. 《网络攻防》实验五:MSF基础应用

    IE浏览器渗透攻击--MS11050安全漏洞 实验准备 1.两台虚拟机,其中一台为kali,一台为Windows Xp Professional(两台虚拟机可以相互间ping通). 2.亚军同学的指导 ...

  7. Android实践项目汇报总结(下)

    微博客户端的设计与实现(下) 第四章 系统详细功能实现 本应用实现了如下主要模块:程序启动模块.登录授权模块.主界面显示模块撰写发表微博模块.用户发布信息模块.软件设置模块. 4.1程序启动模块实现 ...

  8. Android实践项目汇报总结(上)修改

    微博客户端的设计与实现(上) 第一章 绪论 1.1课题背景 微博可以说是时下最受人们所喜爱的一种社交方式,它是一种通过关注机制分享简短实时信息的广播式的社交网络平台.通过微博我们可以了解最新的时事新闻 ...

  9. python常见模块属性与方法

    sys模块的变量 变量 描述 sys.path 模块搜索路径 path[0] 是当前脚本程序的路径名,否则为 '' sys.modules 已加载模块的字典 sys.version 版本信息字符串 s ...

  10. Python3基础 file for+list 读取txt文本 并 一行一行的输出(低效率)

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...