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窗口在最小化之后,内存占用会有明显改善。

时间: 2024-07-31 19:30:16

JavaScript 导出Excel 代码的相关文章

Javascript导出Excel

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <html>  <head>  <meta http-equiv="Content-Type" content="text/html; charset=gb2312">  <titl

原生JavaScript 导出excel表格(兼容ie和其他主流浏览器)

因同事的需求是想前端导出excel表格,网上找了一些demo,自己修改了一下,可能以后会用到,记录下来吧,兼容ie和一些主流浏览器,ie可能会报错,原因参考 这里,edge 浏览器还没有办法导出,正在尝试... <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>table 导出excel表格</title>

java 通过Apache poi导出excel代码demo实例

package com.zuidaima.excel.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.

Java中用JXL导出Excel代码详解

jxl是一个韩国人写的java操作excel的工具, 在开源世界中,有两套比较有影响的API可供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一点.但jExcelAPI对中文支持非常好,API是纯Java的, 并不依赖Windows系统,即使运行在Linux下,它同样能够正确的处理Excel文件. 另外需要说明的是,这套API对图形和图表的支持很有限,而且仅仅识别PNG格式.使用如下:搭建环境 将下载后的文件解包,得到jxl.jar,放入classpath,安装就完成了.

.NET导出Excel的四种方法及评测

.NET导出Excel的四种方法及评测 导出Excel是.NET的常见需求,开源社区.市场上,都提供了不少各式各样的Excel操作相关包.本文,我将使用NPOI.EPPlus.OpenXML.Aspose.Cells四个市面上常见的库,各完成一个导出Excel示例.然后对其代码风格和性能做一个横向比较.最后我将说出我自己的感想. 文中所有的示例代码可以在这里下载: https://github.com/sdcb/blog-data/tree/master/2019/20190824-dotnet

带复杂表头合并单元格的HtmlTable转换成DataTable并导出Excel(转)

步骤: 一.前台JS取HtmlTable数据,根据设定的分隔符把数据拼接起来 <!--导出Excel--> <script type="text/javascript"> //导出Excel function exportExcel() { var data = ""; $("#divRptTable").find("table").find("tr").each(function

JQGrid导出Excel文件

系列索引 Web jquery表格组件 JQGrid 的使用 - 从入门到精通 开篇及索引 Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数.ColModel API.事件及方法 Web jquery表格组件 JQGrid 的使用 - 5.Pager翻页.搜索.格式化.自定义按钮 Web jquery表格组件 JQGrid 的使用 - 6.准备工作 & Hello JQGrid Web jquery表格组件 JQGrid 的使用 - 7.查询数据.编辑数据.删除数据

Extjs4.2纯前台导出excel中不支持treepanel

Extjs4.2纯前台导出excel代码中,Button.js的构造函数中 this.on("afterrender", function () { // We wait for the combo to be rendered, so we can look up to grab the component containing it            self.setComponent(self.store || self.component || self.up("

C# NPOI 导入与导出Excel文档 兼容xlsx, xls(xf13中已经引用了xlsx的npoi)

这里使用的NPOI版本为: 2.1.3.1 官方下载地址: http://npoi.codeplex.com/releases 版本内包含.Net 2.0 与.Net 4.0 .Net 4.0中包含文件 使用时需引用需要引用所有5个dll 使用到的引用 using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; 还有经过自己整理的导入导出Excel代码: /// <summary> /// Exc