數據報表作為企事業單位上報和下達的重要信息載體,隨着信息化建設的不斷推進,在實際的工作中得到了前所未有的應用。因此,數據報表已經成為管理信息系統中重要的一項功能,並且,由於數據的多樣性和統計信息的增加,數據報表的系統實現變得越來越復雜。
Microsoft Excel 軟件具有十分強大的制表、表格計算等功能,是普通人員常用的制表工具。因此Excel在眾多企業中的應用十分廣泛。當企業進行信息化建設時,必然需要將Excel的數據導入到信息化系統中去,或將數據導出到Excel中來。如果信息化系統采用C/S結構,導出數據到Excel還比較好說,采用B/S結構就不好說了,相關的資料非常的少。
下面本文將介紹一種使用javascript將HTML的Table數據導出到Excel的方法。
1. 用javascript操作Excel
Excel是一個Com,因此我們在javascript中像其他的開發語言一樣創建Excel對象,從而獲得訪問Excel的能力。
var xls = new ActiveXObject( "Excel.Application" );
上面這句話就創建了一個Excel的Application對象。
var xlBook = xls.Workbooks.Add;
上面這句話增加一個Excel的WorkBook。
var xlsheet = xlBook.Worksheets(1);
上面這句話獲得WorkBook的Sheet1對象。
通過xlsheet.Cells(X, Y)可以訪問Sheet中的單元格對象,其中X, Y是單元格的坐標位置。
Cell對象有很多屬性和方法,這里我們將使用到Cell的Value屬性,Border屬性等。下面給出Cell對象三個常用的屬性:
Cell的Value屬性是指表格中的字符串值。
Cell的Interiro.color屬性是指單元格的背景色,例如:
xlsheet.Cells(CurX, CurY).Interior.color = 0x00FF66;
Cell的Borders.LineStyle屬性是指單元格的邊框樣式,該屬性是整型值,0表示沒有邊框,1表示Solid形變框,其他的數字則表示其他的邊框類型,大家可以逐個試一下。例如:
xlsheet.Cells(CurX, CurY).Borders.LineStyle = 1;
同時Cell還有其它的屬性,例如單元格格式等其他屬性,有興趣的朋友可以查找相關的資料。
2. 用javascript獲得Table的信息
在javascript中我們可以通過定義Table的id,來訪問Table的相關信息,Table具有以下一些對象:
rows對象:行集對象,保存了TR的相關信息,其中用rows[RowIndex]即可訪問對應的TR的信息,rows.length返回了Table中的TR的個數,也就是行的個數。
cells對象:單元格對象,保存了TD的相關信息。cells對象存在於rows[RowIndex]對象中,訪問時得通過具體的rows對象來訪問,例如訪問第一行的表格對象:rows[0].cells;cells.length返回了cells對象所屬行中的TD的個數,cells[ColIndex]則對應具體的TD的信息。cells[ColIndex].outerHTML返回了TD的定義語句,cells[ColIndex].innerHTML返回了TD中的內容。例如TD的定義如下:
<TD width=80>單元格定義</TD>
則cells[ColIndex].outerHTML返回的結果是“<TD width=80>單元格定義</TD>”,cells[ColIndex].innerHTML返回的結果是“單元格定義”
3. 用javascript遍歷HTML中的Table
了解了Table的屬性以后,我們就可以用javascript來遍歷Table的每一個單元格了,下面是遍歷的程序,具體的例子代碼請查看附錄1
function AccessALLTable(objTab)
{
for (var i = 0; i < objTab.rows.length; i++)
{
for (var j = 0; j < objTab.rows[i].cells.length; j++)
{
s = objTab.rows[i].cells[j].outerHTML;
alert("第" + i + "行,第" + j + "列:outerHTML為" + s);
s = objTab.rows[i].cells[j].outerHTML;
alert("第" + i + "行,第" + j + "列:innerHTML為" + s);
}
}
}
4. 合並單元格
在HTML的Table中,合並單元格是很簡單的事情,只需要指定TD的colspan或者rowspan即可跨行或者跨列,而在Excel中,合並單元格需要先指定Range(范圍),例如,合並從Cells(0, 0)到Cells(2, 2)的單元格,則在javascript中這樣寫就可以了:
xls.Range(xls.Cells(0, 0), xls.Cells(2, 2)).MergeCells = true;
Range同時還是一個對象,我們可以聲明一個變量來取出Range對象,並設置對象的相關屬性,例如:
var R = xls.Range(xls.Cells(0, 0), xls.Cells(2, 2));
R.MergeCells = true;
5. 導出HTML的Table到Excel中去
有了上面的知識,我們就可以開始用javascript導出HTML的Table到Excel中去了。下面是導出的代碼,具體的例子代碼請查看附錄1
function PrintTableToExcel(objTab)
{
try
{
var xls = new ActiveXObject( "Excel.Application" );
}
catch(e)
{
alert( "要打印該表,您必須安裝Excel電子表格軟件,同時瀏覽器須使用“ActiveX 控件”,您的瀏覽器須允許執行控件。請點擊【幫助】了解瀏覽器設置方法!");
return false;
}
xls.visible = true;
var xlBook = xls.Workbooks.Add;
var xlsheet = xlBook.Worksheets(1);
var x = 1;
var y = 1;
for (var i = 0; i < objTab.rows.length; i++)
{
y = 1;
for (var j = 0; j < objTab.rows[i].cells.length; j++)
{
xlsheet.Cells(x, y).Value = objTab.rows[i].cells[j].innerHTML;
xlsheet.Cells(x, y).Borders.LineStyle = 1;
y++;
}
x++;
}
xlsheet.Columns.AutoFit; //自動適應大小
return;
}
6. 增強型的導出功能
因為Excel可以合並單元格,所以我們可以根據TD的定義中是否有colspan或rowspan屬性來判斷是否需要合並單元格。但是colspan和rowspan這兩個屬性似乎在javascript中沒有直接訪問的方法,因此我們只能采用笨方法來獲得colspan或rowspan的屬性值。首先我們取出TD的定義字符串,然后在這個字符串中查找是否有"colspan="或"rowspan="的子串,如果有的話,則取出子串后面跟着的數字,該數字表明TD跨列或跨行的個數,具體的實現程序如下所示:
// Str – TD的定義字符串
// Prop – 屬性值,可以是colspan、rowspan、border、width等數值型屬性的名稱
// 返回值是屬性的值
// 例如TD的定義為<td width=100>xx</td>
// 則getPropValue("td width=100>xx</td>", "width")返回100
function getIntPropValue(Str, Prop)
{
var s = Str.toUpperCase(Str);
var p = Prop.toUpperCase(Prop);
var idx = s.indexOf(p);
var PropValue = "";
if (idx >= 0)
{
var x = Prop.length;
while ((Str.charAt(idx + x) < "0") || (Str.charAt(idx + x) > "9"))
{
x++;
}
while ((Str.charAt(idx + x) >= "0") && (Str.charAt(idx + x) <= "9"))
{
PropValue = PropValue + Str.charAt(idx + x);
x++;
}
return PropValue;
}
else
return "0";
}
同樣,我們還可以把上面的函數改造一下,讓它可以返回TD的align等字符串型的屬性,這里就不再給出實現函數了。
有了上面的函數,我們就可以在導出Table到Excel時動態判斷TD的colspan和rowspan屬性,然后在Excel中合並相應的單元格,從而增強導出功能,使Excel的格式同Table的格式完全匹配。附錄1給出了一個導出簡單Table到Excel的例子,這里的Table有跨行和跨列的TD存在,導出結果同HTML的Table完全一樣,這是比較簡單的Table,TD在跨行時只能在第一列,否則將不能正確導出。大家可以改造一下導出的算法,讓它可以適應復雜的表格導出,不過比較困難。
7. IE的安全問題
由於IE在創建ActiveX控件時可能會產生安全問題,因此IE的安全設置中該項的默認值是禁止創建ActiveX控件的,為了在使用時能夠正確的完成功能,只需在IE的安全設置中創建ActiveX控件的選項設置為啟用或提示即可。具體設置如下圖:

View Code
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
runat
="server"
>
<
title
>無標題頁
</
title
>
<
script
type
="text/javascript"
language
="javascript"
>
function
PrintTableToExcel(objTab)
{
try
{
var
xls
=
new
ActiveXObject(
"
Excel.Application
"
);
}
catch
(e)
{
alert(e)
//
alert( "要打印該表,您必須安裝Excel電子表格軟件,同時瀏覽器須使用“ActiveX 控件”,您的瀏覽器須允許執行控件。 請點擊【幫助】了解瀏覽器設置方法!");
return
false
;
}
xls.visible
=
true
;
var
xlBook
=
xls.Workbooks.Add;
var
xlsheet
=
xlBook.Worksheets(
1
);
var
x
=
1
;
var
y
=
1
;
for
(
var
i
=
0
; i
<
objTab.rows.length; i
++
)
{
y
=
1
;
for
(
var
j
=
0
; j
<
objTab.rows[i].cells.length; j
++
)
{
xlsheet.Cells(x, y).Value
=
objTab.rows[i].cells[j].innerHTML;
xlsheet.Cells(x, y).Borders.LineStyle
=
1
;
y
++
;
}
x
++
;
}
xlsheet.Columns.AutoFit;
//
自動適應大小
return
;
}
</
script
>
</
head
>
<
body
>
<
form
id
="form1"
runat
="server"
>
<
div
>
<
table
id
="Table1"
cellpadding
="0"
cellspacing
="0"
style
="width:90%"
>
<
tr
>
<
td
>
姓名
</
td
>
<
td
>
學號
</
td
>
<
td
>
語文
</
td
>
<
td
>
數學
</
td
>
</
tr
>
<
tr
>
<
td
>
張三
</
td
>
<
td
>
200118056
</
td
>
<
td
>
78
</
td
>
<
td
>
95
</
td
>
</
tr
>
<
tr
>
<
td
>
李四
</
td
>
<
td
>
201118057
</
td
>
<
td
>
89
</
td
>
<
td
>
37
</
td
>
</
tr
>
<
tr
>
<
td
>
王五
</
td
>
<
td
>
201118058
</
td
>
<
td
>
92
</
td
>
<
td
>
88
</
td
>
</
tr
>
</
table
>
<
input
id
="Submit1"
type
="submit"
value
="submit"
onclick
="PrintTableToExcel(Table1)"
/>
</
div
>
</
form
>
</
body
>
</
html
>