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 相关文章推荐
如何判断图片地址是否失效
Feb 02 Javascript
jquery 跨域访问问题解决方法(笔记)
Jun 08 Javascript
分享精心挑选的23款美轮美奂的jQuery 图片特效插件
Aug 14 Javascript
jquery 实现窗口的最大化不论什么情况
Sep 03 Javascript
jquery实现人性化的有选择性禁用鼠标右键
Jun 30 Javascript
JavaScript判断用户是否对表单进行了修改的方法
Mar 18 Javascript
从零开始学习Node.js系列教程三:图片上传和显示方法示例
Apr 13 Javascript
十个免费的web前端开发工具详细整理
Sep 18 Javascript
详解Node全局变量global模块
Sep 28 Javascript
jquery实现侧边栏左右伸缩效果的示例
Dec 19 jQuery
浅谈webpack性能榨汁机(打包速度优化)
Jan 09 Javascript
React四级菜单的实现
Apr 08 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
4月1日重磅发布!《星际争霸II》6.0.0版本更新
2020/04/09 星际争霸
php.ini 中文版
2006/10/28 PHP
一步一步学习PHP(4) php 函数 补充2
2010/02/15 PHP
PHP中curl_setopt函数用法实例分析
2015/04/16 PHP
运用Windows XP附带的Msicuu.exe、Msizap.exe来彻底卸载顽固程序
2007/04/21 Javascript
extjs 学习笔记 四 带分页的grid
2009/10/20 Javascript
jquery 应用代码 方便的排序功能
2010/02/06 Javascript
Jquery提交表单 Form.js官方插件介绍
2012/03/01 Javascript
怎么选择Javascript框架(Javascript Framework)
2013/11/22 Javascript
导入extjs、jquery 文件时$使用冲突问题解决方法
2014/01/14 Javascript
JS 新增Cookie 取cookie值 删除cookie 举例详解
2014/10/10 Javascript
JavaScript中innerHTML,innerText,outerHTML的用法及区别
2015/09/01 Javascript
详解js中构造流程图的核心技术JsPlumb
2015/12/08 Javascript
使用jQuery制作基础的Web图片轮播效果
2016/04/22 Javascript
JavaScript中的FileReader图片预览上传功能实现代码
2017/07/24 Javascript
angular项目中bootstrap-datetimepicker时间插件的使用示例
2018/03/15 Javascript
用Vue写一个分页器的示例代码
2018/04/22 Javascript
element-ui表格列金额显示两位小数的方法
2018/08/24 Javascript
基于Proxy的小程序状态管理实现
2019/06/14 Javascript
JavaScript简易计算器制作
2020/01/17 Javascript
非常漂亮的js烟花效果
2020/03/10 Javascript
解决vue+router路由跳转不起作用的一项原因
2020/07/19 Javascript
Python爬虫DOTA排行榜爬取实例(分享)
2017/06/13 Python
Python编程之变量赋值操作实例分析
2017/07/24 Python
python爬虫_微信公众号推送信息爬取的实例
2017/10/23 Python
人生苦短我用python python如何快速入门?
2018/03/12 Python
python 字典中文key处理,读取,比较方法
2018/07/06 Python
CSS3之多背景background使用示例
2013/10/18 HTML / CSS
CSS3中Animation属性的使用详解
2015/08/06 HTML / CSS
iRobot官网:改变生活的家用机器人品牌
2016/09/20 全球购物
La Senza官网:北美顶尖性感内衣品牌
2018/08/03 全球购物
个人自我剖析材料
2014/02/07 职场文书
幼儿园父亲节活动方案
2014/03/11 职场文书
圣诞晚会主持词
2015/07/01 职场文书
java基础——多线程
2021/07/03 Java/Android
SQL Server内存机制浅探
2022/04/06 SQL Server