JavaScript导出Excel实例详解


Posted in Javascript onNovember 25, 2014

本文实例讲述了JavaScript导出Excel的方法。分享给大家供大家参考。具体实现方法如下:

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

<title>WEB页面导出为EXCEL文档的方法</title>

</head>

<body>

<table id="tableExcel" width="100%" border="1" cellspacing="0" cellpadding="0">

<tr>

<td colspan="5" align="center">WEB页面导出为EXCEL文档的方法</td>

</tr>

<tr>

<td>列标题1</td>

<td>列标题2</td>

<td>列标题3</td>

<td>列标题4</td>

<td>列标题5</td>

</tr>

<tr>

<td>aaa</td>

<td>bbb</td>

<td>ccc</td>

<td>ddd</td>

<td>eee</td>

</tr>

<tr>

<td>AAA</td>

<td>BBB</td>

<td>CCC</td>

<td>DDD</td>

<td>EEE</td>

</tr>

<tr>

<td>FFF</td>

<td>GGG</td>

<td>HHH</td>

<td>III</td>

<td>JJJ</td>

</tr>

</table>

<input type="button" onclick="javascript:method1('tableExcel');" value="第一种方法导入到EXCEL">

<input type="button" onclick="javascript:method2('tableExcel');" value="第二种方法导入到EXCEL">

<input type="button" onclick="javascript:getXlsFromTbl('tableExcel',null);" value="第三种方法导入到EXCEL">

<SCRIPT LANGUAGE="javascript">

function method1(tableid) {//整个表格拷贝到EXCEL中

var curTbl = document.getElementByIdx_x_x(tableid);

var oXL = new ActiveXObject("Excel.Application");

//创建AX对象excel

var oWB = oXL.Workbooks.Add();

//获取workbook对象

var oSheet = oWB.ActiveSheet;

//激活当前sheet

var sel = document.body.createTextRange();

sel.moveToElementText(curTbl);

//把表格中的内容移到TextRange中

sel.select();

//全选TextRange中内容

sel.execCommand("Copy");

//复制TextRange中内容

oSheet.Paste();

//粘贴到活动的EXCEL中

oXL.Visible = true;

//设置excel可见属性

}

function method2(tableid) //读取表格中每个单元到EXCEL中

{

var curTbl = document.getElementByIdx_x_x(tableid);

var oXL = new ActiveXObject("Excel.Application");

//创建AX对象excel

var oWB = oXL.Workbooks.Add();

//获取workbook对象

var oSheet = oWB.ActiveSheet;

//激活当前sheet

var Lenr = curTbl.rows.length;

//取得表格行数

for (i = 0; i < Lenr; i++)

{

var Lenc = curTbl.rows(i).cells.length;

//取得每行的列数

for (j = 0; j < Lenc; j++)

{

oSheet.Cells(i + 1, j + 1).value = curTbl.rows(i).cells(j).innerText;

//赋值

}

}

oXL.Visible = true;

//设置excel可见属性

}

function getXlsFromTbl(inTblId, inWindow) {

try {

var allStr = "";

var curStr = "";

//alert("getXlsFromTbl");

if (inTblId != null && inTblId != "" && inTblId != "null") {

curStr = getTblData(inTblId, inWindow);

}

if (curStr != null) {

allStr += curStr;

}

else {

alert("你要导出的表不存在!");

return;

}

var fileName = getExcelFileName();

doFileExport(fileName, allStr);

}

catch(e) {

alert("导出发生异常:" + e.name + "->" + e.description + "!");

}

}

function getTblData(inTbl, inWindow) {

var rows = 0;

//alert("getTblData is " + inWindow);

var tblDocument = document;

if (!!inWindow && inWindow != "") {

if (!document.all(inWindow)) {

return null;

}

else {

tblDocument = eval_r(inWindow).document;

}

}

var curTbl = tbldocument.getElementByIdx_x_x(inTbl);

var outStr = "";

if (curTbl != null) {

for (var j = 0; j < curTbl.rows.length; j++) {

//alert("j is " + j);

for (var i = 0; i < curTbl.rows[j].cells.length; i++) {

//alert("i is " + i);

if (i == 0 && rows > 0) {

outStr += "  ";

rows -= 1;

}

outStr += curTbl.rows[j].cells[i].innerText + " ";

if (curTbl.rows[j].cells[i].colSpan > 1) {

for (var k = 0; k < curTbl.rows[j].cells[i].colSpan - 1; k++) {

outStr += "  ";

}

}
if (i == 0) {

if (rows == 0 && curTbl.rows[j].cells[i].rowSpan > 1) {

rows = curTbl.rows[j].cells[i].rowSpan - 1;

}

}

}

outStr += " ";

}

}

else {

outStr = null;

alert(inTbl + "不存在!");

}

return outStr;

}
function getExcelFileName() {

var d = new Date();

var curYear = d.getYear();

var curMonth = "" + (d.getMonth() + 1);

var curDate = "" + d.getDate();

var curHour = "" + d.getHours();

var curMinute = "" + d.getMinutes();

var curSecond = "" + d.getSeconds();

if (curMonth.length == 1) {

curMonth = "0" + curMonth;

}
if (curDate.length == 1) {

curDate = "0" + curDate;

}
if (curHour.length == 1) {

curHour = "0" + curHour;

}
if (curMinute.length == 1) {

curMinute = "0" + curMinute;

}
if (curSecond.length == 1) {

curSecond = "0" + curSecond;

}
var fileName = "leo_zhang" + "_" + curYear + curMonth + curDate + "_"

+ curHour + curMinute + curSecond + ".csv";

//alert(fileName);

return fileName;

}
function doFileExport(inName, inStr) {

var xlsWin = null;

if (!!document.all("glbHideFrm")) {

xlsWin = glbHideFrm;

}
else {

var width = 6;

var height = 4;

var openPara = "left=" + (window.screen.width / 2 - width / 2)

+ ",top=" + (window.screen.height / 2 - height / 2)

+ ",scrollbars=no,width=" + width + ",height=" + height;

xlsWin = window.open("", "_blank", openPara);
}

xlsWin.document.write(inStr);

xlsWin.document.close();

xlsWin.document.execCommand('Saveas', true, inName);

xlsWin.close();

}

</SCRIPT>

</body>

</html>

下面是处理excel 进程关闭问题

// JavaScript中的析构问题(ActiveX Object示例)

//---------------------------------------------------------

<script>

var strSaveLocation = 'file:///E:/1.xls'

function createXLS() {

  var excel = new ActiveXObject("Excel.Application");

  var wk = excel.Workbooks.Add();

  wk.SaveAs(strSaveLocation);

  wk.Saved = true;
  excel.Quit();

}
function writeXLS() {

  var excel = new ActiveXObject("Excel.Application");

  var wk = excel.Workbooks.Open(strSaveLocation);

  var sheet = wk.Worksheets(1);

  sheet.Cells(1, 1).Value = '测试字符串';

  wk.SaveAs(strSaveLocation);

  wk.Saved = true;
  excel.Quit();

}

</script>
<body>

  <button onclick="createXLS()">创建</button>

  <button onclick="writeXLS()">重写</button>

</body>

在这个例子中,在本地文件操作时并不会出现异常。——最多只是有一些内存垃圾而已。然而,如果strSaveLocation是一个远程的URL,这时本地将会保存一个文件存取权限的凭证,而且同时只能一个(远程的)实例来开启该excel文档并存储。于是如果反复点击"重写"按钮,就会出现异常。

——注意,这是在SPS中操作共享文件时的一个实例的简化代码。因此,它并非“学术的”无聊讨论,而且工程中的实际问题。

解决这个问题的方法很复杂。它涉及到两个问题:
① 本地凭证的释放
② ActiveX Object实例的释放

下面我们先从JavaScript中对象的“失效”问题说起。简单的说:
① 一个对象在其生存的上下文环境之外,即会失效。
② 一个全局的对象在没有被执用(引用)的情况下,即会失效。

例如:

//---------------------------------------------------------

// JavaScript对象何时失效

//---------------------------------------------------------

function testObject() {

  var _obj1 = new Object();

}
function testObject2() {

  var _obj2 = new Object();

  return _obj2;

}
// 示例1

testObject();
// 示例2

testObject2()
// 示例3

var obj3 = testObject2();

obj3 = null;
// 示例4

var obj4 = testObject2();

var arr = [obj4];

obj3 = null;

arr = [];

在这四个示例中:
- “示例1”在函数testObject()中构造了_obj1,但是在函数退出时,它就已经离开了函数的上下文环境,因此_obj1失效了;
- “示例2”中,testObject2()中也构造了一个对象_obj2并传出,因此对象有了“函数外”的上下文环境(和生存周期),然而由于函数的返回值没有被其它变量“持有”,因此_obj2也立即失效了;
- “示例3”中,testObject2()构造的_obj2被外部的变量obj3持用了,这时,直到“obj3=null”这行代码生效时,_obj2才会因为引用关系消失而失效。
- 与示例3相同的原因,“示例4”中的_obj2会在“arr=[]”这行代码之后才会失效。

但是,对象的“失效”并不等会“释放”。在JavaScript运行环境的内部,没有任何方式来确切地告诉用户“对象什么时候会释放”。这依赖于JavaScript的内存回收机制。——这种策略与.NET中的回收机制是类同的。

在前面的Excel操作示例代码中,对象的所有者,也就是"EXCEL.EXE"这个进程只能在“ActiveX Object实例的释放”之后才会发生。而文件的锁,以及操作系统的权限凭证是与进程相关的。因此如果对象仅是“失效”而不是“释放”,那么其它进程处理文件和引用操作系统的权限凭据时就会出问题。

——有些人说这是JavaScript或者COM机制的BUG。其实不是,这是OS、IE和JavaScript之间的一种复杂关系所导致的,而非独立的问题。

Microsoft公开了解决这种问题的策略:主动调用内存回收过程。

在(微软的)JScript中提供了一个CollectGarbage()过程(通常简称GC过程),GC过程用于清理当前IE中的“失效的对象失例”,也就是调用对象的析构过程。

在上例中调用GC过程的代码是:

//---------------------------------------------------------

// 处理ActiveX Object时,GC过程的标准调用方式

//---------------------------------------------------------

function writeXLS() {

  //(略...)
  excel.Quit();

  excel = null;

  setTimeout(CollectGarbage, 1);

}

第一行代码调用excel.Quit()方法来使得excel进程中止并退出,这时由于JavaScript环境执有excel对象实例,因此excel进程并不实际中止。

第二行代码使excel为null,以清除对象引用,从而使对象“失效”。然而由于对象仍旧在函数上下文环境中,因此如果直接调用GC过程,对象仍然不会被清理。

第三行代码使用setTimeout()来调用CollectGarbage函数,时间间隔设为'1',只是使得GC过程发生在writeXLS()函数执行完之后。这样excel对象就满足了“能被GC清理”的两个条件:没有引用和离开上下文环境。

GC过程的使用,在使用了ActiveX Object的JS环境中很有效。一些潜在的ActiveX Object包括XML、VML、OWC(Office Web Componet)、flash,甚至包括在JS中的VBArray。

从这一点来看,ajax架构由于采用了XMLHTTP,并且同时要满足“不切换页面”的特性,因此在适当的时候主动调用GC过程,会得到更好的效率用UI体验。

事实上,即使使用GC过程,前面提到的excel问题仍然不会被完全解决。因为IE还缓存了权限凭据。使页的权限凭据被更新的唯一方法,只能是“切换到新的页面”,因此事实上在前面提到的那个SPS项目中,我采用的方法并不是GC,而是下面这一段代码:

//---------------------------------------------------------

// 处理ActiveX Object时采用的页面切换代码

//---------------------------------------------------------

function writeXLS() {

  //(略...)
  excel.Quit();

  excel = null;

 

  // 下面代码用于解决IE call Excel的一个BUG, MSDN中提供的方法:

  //   setTimeout(CollectGarbage, 1);

  // 由于不能清除(或同步)网页的受信任状态, 所以将导致SaveAs()等方法在

  // 下次调用时无效.

  location.reload();

}

最后之最后,关于GC的一个补充说明:在IE窗体被最小化时,IE将会主动调用一次
CollectGarbage()函数。这使得IE窗口在最小化之后,内存占用会有明显改善。

希望本文所述对大家基于javascript的web程序设计有所帮助。

Javascript 相关文章推荐
尽可能写&quot;友好&quot;的&quot;Javascript&quot;代码
Jan 09 Javascript
javascript 图片裁剪技巧解读
Nov 15 Javascript
window.open打开页面居中显示的示例代码
Dec 27 Javascript
原生javaScript做得动态表格(注释写的很清楚)
Dec 29 Javascript
js实现div层缓慢收缩与展开的方法
May 11 Javascript
jQuery实现的Tab滑动选项卡及图片切换(多种效果)小结
Sep 14 Javascript
JavaScript实现的MD5算法完整实例
Feb 02 Javascript
页面点击小红心js实现代码
May 26 Javascript
详解Vue SSR( Vue2 + Koa2 + Webpack4)配置指南
Nov 13 Javascript
vue-router跳转时打开新页面的两种方法
Jul 29 Javascript
详解mpvue实现对苹果X安全区域的适配
Jul 31 Javascript
浅析Vue 防抖与节流的使用
Nov 14 Javascript
JS倒计时代码汇总
Nov 25 #Javascript
jquery中push()的用法(数组添加元素)
Nov 25 #Javascript
Jquery焦点图实例代码
Nov 25 #Javascript
jQuery事件绑定和委托实例
Nov 25 #Javascript
2014最热门的JavaScript代码高亮插件推荐
Nov 25 #Javascript
JS跨域问题详解
Nov 25 #Javascript
javascript 中__proto__和prototype详解
Nov 25 #Javascript
You might like
php通过正则表达式记取数据来读取xml的方法
2015/03/09 PHP
PHP+JS三级菜单联动菜单实现方法
2016/02/24 PHP
PHP 断点续传实例详解
2017/11/11 PHP
PHP isset()及empty()用法区别详解
2020/08/29 PHP
jquery实现智能感知连接外网搜索
2013/05/21 Javascript
JS删除字符串中重复字符方法
2014/03/09 Javascript
Angular中使用ui router实现系统权限控制及开发遇到问题
2016/09/23 Javascript
Bootstrap Table从服务器加载数据进行显示的实现方法
2016/09/29 Javascript
Node.js常用工具之util模块
2017/03/09 Javascript
原生js jquery ajax请求以及jsonp的调用方法
2017/08/04 jQuery
如何从头实现一个node.js的koa框架
2019/06/17 Javascript
微信小程序 组件的外部样式externalClasses使用详解
2019/09/06 Javascript
vue+elementUi 实现密码显示/隐藏+小图标变化功能
2020/01/18 Javascript
python中实现精确的浮点数运算详解
2017/11/02 Python
python 简单备份文件脚本v1.0的实例
2017/11/06 Python
100行Python代码实现自动抢火车票(附源码)
2018/01/11 Python
python matlibplot绘制多条曲线图
2021/02/19 Python
python2和python3的输入和输出区别介绍
2018/11/20 Python
python处理multipart/form-data的请求方法
2018/12/26 Python
python 用for循环实现1~n求和的实例
2019/02/01 Python
浅谈python常用程序算法
2019/03/22 Python
详解如何管理多个Python版本和虚拟环境
2019/05/10 Python
python安装本地whl的实例步骤
2019/10/12 Python
Python属性和内建属性实例解析
2020/01/14 Python
python分别打包出32位和64位应用程序
2020/02/18 Python
Python下载网易云歌单歌曲的示例代码
2020/08/12 Python
泰国排名第一的家居用品中心:HomePro
2020/11/18 全球购物
巴西最大的玩具连锁店:Ri Happy
2020/06/17 全球购物
全球最大运动品牌的男装、女装和童装官方库存商:A&A Sports
2021/01/17 全球购物
linux面试题参考答案(8)
2016/04/19 面试题
企业办公室岗位职责
2014/03/12 职场文书
村党支部公开承诺书
2014/05/29 职场文书
5s标语大全
2014/06/23 职场文书
2015年电话销售工作总结范文
2015/04/20 职场文书
小学运动会宣传稿
2015/07/23 职场文书
2016入党培训心得体会范文
2016/01/08 职场文书