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 相关文章推荐
QQ邮箱的一个文本编辑器代码
Mar 14 Javascript
JS类定义原型方法的两种实现的区别评论很多
Sep 12 Javascript
js实现文本框中焦点在最后位置
Mar 04 Javascript
jquery.map()方法的使用详解
Jul 09 Javascript
javascript实现手机震动API代码
Aug 05 Javascript
Javascript基于对象三大特性(封装性、继承性、多态性)
Jan 04 Javascript
实例讲解JavaScript中instanceof运算符的用法
Jun 08 Javascript
十大热门的JavaScript框架和库
Mar 21 Javascript
js链表操作(实例讲解)
Aug 29 Javascript
浅谈小程序 setData学问多
Feb 20 Javascript
vue 实现cli3.0中使用proxy进行代理转发
Oct 30 Javascript
vue中实现回车键登录功能
Feb 19 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
《魔兽争霸3:重制版》更新 多项视觉效果调整
2020/05/04 魔兽争霸
vBulletin HACK----关于排版的两个HACK
2006/10/09 PHP
WordPress开发中短代码的实现及相关函数使用技巧
2016/01/05 PHP
PHP中ltrim()函数的用法与实例讲解
2019/03/28 PHP
css动画效果之animation的常用样式
2021/03/09 HTML / CSS
jquery数据验证插件(自制,简单,练手)实例代码
2013/10/24 Javascript
jQuery中大家不太了解的几个方法
2015/03/04 Javascript
JavaScript检测弹出窗口是否已经关闭的方法
2015/03/24 Javascript
JS实现的最简Table选项卡效果
2015/10/14 Javascript
javascript学习小结之prototype
2015/12/03 Javascript
支付宝小程序实现省市区三级联动
2020/06/21 Javascript
[00:56]2014DOTA2国际邀请赛 DK、iG 赛前探访
2014/07/10 DOTA
Python自定义scrapy中间模块避免重复采集的方法
2015/04/07 Python
Python搭建HTTP服务器和FTP服务器
2017/03/09 Python
Python正则表达式分组概念与用法详解
2017/06/24 Python
Python实现连接两个无规则列表后删除重复元素并升序排序的方法
2018/02/05 Python
TensorFlow模型保存/载入的两种方法
2018/03/08 Python
python+pyqt5实现24点小游戏
2019/01/24 Python
Python判断有效的数独算法示例
2019/02/23 Python
Python异常处理例题整理
2019/07/07 Python
Django框架自定义模型管理器与元选项用法分析
2019/07/22 Python
Python实现socket非阻塞通讯功能示例
2019/11/06 Python
python和php哪个容易学
2020/06/19 Python
生物技术专业研究生自荐信
2013/09/22 职场文书
毕业设计计划书
2014/01/09 职场文书
大学生最新职业生涯规划书范文
2014/01/12 职场文书
学生会个人自荐书范文
2014/02/12 职场文书
建议书怎么写
2014/03/12 职场文书
安全生产承诺书范文
2014/05/22 职场文书
项目投资合作意向书
2014/07/29 职场文书
2014党员学习《反腐倡廉警示教育读本》思想汇报
2014/09/13 职场文书
酒店辞职书怎么写
2015/02/26 职场文书
投诉信格式范文
2015/07/02 职场文书
Python 如何将integer转化为罗马数(3999以内)
2021/06/05 Python
Python os和os.path模块详情
2022/04/02 Python
MySQL范围查询优化的场景实例详解
2022/06/10 MySQL