(来自:http://blog.csdn.net/cxzhq2002/archive/2006/07/04/876007.aspx)
经常看到有些人问怎么把Table的资料转到Excel里面去,很多人在碰到这个问题都先考虑用execl.appliction,使用不太好,首先必需要掌握它的一些内部用法,其次它在客户端使用时涉及安全性,以下介绍三种方法:
//服务端方法,采用的是FSO方法,输出到服务端
方法一:用单纯的文本格式实现
该方法相当简单,以下给出代码,各位就容易明白
<
%
set
fso
=
server.createobject(
"
scripting.filesystemobject
"
)
strExcelFile
=
server.MapPath(
"
txtToExcel.xls
"
)
if
fso.fileExists(strExcelFile)
then
fso.deletefile strExcelFile
Set
xslFile
=
fso.CreateTextFile(strExcelFile ,
True
)
xslFile.WriteLine(
"
df
"
&
vbTab
&
"
345
"
&
vbLf
&
"
fe
"
&
vbTab
&
"
mon
"
&
vbLf)
xslFile.Close
set
fso
=
nothing
response.write
"
OK
"
%
>
原理:
相信大家都知道,Excel是可以打开文本文件的,而对于里面的文本内容Excel则会这样处理:如果遇到[制表符]Tab键则跳下一列,如果遇到[换行符]则换下一行,所以根据这个规则我们整理一下就可以产生单一表格式Excel文件了,
优点:
掌握简单,纯粹的文字整理而已。
缺点:
效率较低,把一个较多内容的table转成Excel档要则执行较长的循环(),而文档格式只能是规则的行列格式,对表格不能做更多的设置
//client端方法,借助的是客户端的ActiveX owc控件,将客户端的Table 数据借助owc office控制转成Excel,所以对客户端要求装Office2000以上,这决定了这种方法只能用在企业intranet 应用程序。
方法二:用OWC实现:
此方法也简单,只是少为人知而已,同样先给出代码:
<
script language
=
"
javascript
"
>
function
exportExcel(atblData)
{
if (typeof(EXPORT_OBJECT)!="object"){
document.body.insertAdjacentHTML("afterBegin","<OBJECT style=’display:none’ classid=clsid:0002E510-0000-0000-C000-000000000046 id=EXPORT_OBJECT></Object>");
}
with (EXPORT_OBJECT){
DataType = "HTMLData";
HTMLData =atblData.outerHTML;
try{
ActiveSheet.Export("C:\\owcToExcel.xls", 0);
alert(’汇出完毕’);
}
catch (e){
alert(’汇出Excel表失败,请确定已安装Excel2000(或更高版本),并且没打开同名xls文件’);
}
}
}
</
script
>
<
table id
=
"
tblData
"
>
<
tr
><
td
>
gdsssa
</
td
><
td
>
445
</
td
></
tr
>
<
tr
><
td
>
gdsssa
</
td
><
td
>
445
</
td
></
tr
>
</
table
>
<
input type
=
"
button
"
value
=
"
export
"
onclick
=
"
exportExcel(tblData)
"
>
原理:
大家应该看出这是前端脚本html实现,其实这是利用OWC的功能来转出Excel档,我们只需整理出一个Table档,基本上我 们整理出的Table在网页上是什么样子,在Excel上就是什么样子,但要注意:网页里的<style>不会汇出到Excel中,所以网页 里的样式表不会在Excel中看到.
优点:
掌握也很简单,而且可以在前台实现,并且不会设计权限问题,为前台产生Excel档存到客户端而伤透脑筋的兄弟姐妹们,这个方法.
缺点:
客户端必需安装Excel2000或更高版本(不过这个一般都不成问题的了),而且样式表的内容不能输出。
---------------------------------------
方法三:利用XML来产生
首先讲讲道理,先随便编一个Excel档,然后把它另存为*.htm文件,再用文本编辑器打开,是不是跟我们一般的网页内容非常相似,那么我们是不是只需要整理出这些文字出来就可以了,关键是怎样整理出这份文本文字档案呢
我们分析一下这些文字,第一部分是<style>样式表的定义,第二部分是Excel特有的定义内容,第三部分是则是最熟悉的Table数据了,那么对于这三部分,前两部分基本是固定了,我整理一下基本只需要这些:
<
html
xmlns:s
="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882"
xmlns:dt
="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882"
xmlns:rs
="urn:schemas-microsoft-com:rowset"
xmlns:z
="#RowsetSchema"
xmlns:o
="urn:schemas-microsoft-com:office:office"
xmlns:x
="urn:schemas-microsoft-com:office:excel"
xmlns
="http://www.w3.org/TR/REC-html40"
>
<
head
>
<
meta
http-equiv
="Content-Type"
content
="text/html;"
/>
<
style
>
xl24{mso-style-parent:style0;mso-number-format:"\@";text-align:right;}
</
style
>
<
xml
>
<
x:ExcelWorkbook
>
<
x:ExcelWorksheets
>
<
x:ExcelWorksheet
>
<
x:Name
>
Sheet1
</
x:Name
>
<
x:WorksheetOptions
>
<
x:ProtectContents
>
False
</
x:ProtectContents
>
<
x:ProtectObjects
>
False
</
x:ProtectObjects
>
<
x:ProtectScenarios
>
False
</
x:ProtectScenarios
>
</
x:WorksheetOptions
>
</
x:ExcelWorksheet
>
</
x:ExcelWorksheets
>
</
x:ExcelWorkbook
>
</
xml
>
</
head
>
然后是第三部分,我们可以通过recordset来读取数据的指定内容,而且可以通过save来直接把那些内容生成一个xml文件,所以我们只需要根据这 个xml文件写一个xsl文件来转换就行了,那么这个方法是我认为最好的,因为我们可以任意设定Table的样式,同时不必诸多循环,有效解决Excel 一些自做聪明的小动作
这种方法的优点是你可以定制很好的格式的Excel文件,只要你xsl会写,包括统计都可以做出来,所以懂xsl的人估计来到这里比较明白了,而且效率很高,不用再慢慢循环了
缺点嘛:就是技术要求高了一点,至于算有多高,各人不同了。
最后附上代码:
===========xmlToExcel.asp=============
<
%
Set
Conn
=
Server.CreateObject(
"
ADODB.Connection
"
)
Conn.Open
"
Provider = Microsoft.Jet.OLEDB.4.0; Data Source =
"
&
Server.MapPath(
"
comp_apply.mdb
"
)
’strSelect
=
"
select dept_no,dept_name,dept_check from dept_data
"
strSelect
=
"
select * from user_data
"
’改变该SQL语句则可改变excel的内容
Set
rs
=
server.createobject(
"
adodb.recordset
"
)
rs.open strSelect,conn,
1
,
1
set
fso
=
server.createobject(
"
scripting.filesystemobject
"
)
strXmlFile
=
server.MapPath(
"
xmlToExcelTmp.xml
"
)
strXslFile
=
server.MapPath(
"
xmlToExcel.xsl
"
)
strExcelFile
=
server.MapPath(
"
xmlToExcel.xls
"
)
if
fso.fileExists(strXmlFile)
then
fso.deletefile strXmlFile
rs.save strXmlFile,
1
rs.close
Conn.close
set
Conn
=
nothing
set
xmlDoc
=
server.createobject(
"
microsoft.xmldom
"
)
set
xslDoc
=
server.createobject(
"
microsoft.xmldom
"
)
xslDoc.load(strXslFile)
xmlDoc.load(strXmlFile)
xmlDoc.loadXml(xmlDoc.transformNode(xslDoc))
if
fso.fileExists(strExcelFile)
then
fso.deletefile strExcelFile
Set
xslFile
=
fso.CreateTextFile(strExcelFile ,
True
)
xslFile.WriteLine(xmlDoc.xml)
xslFile.Close
fso.deletefile strXmlFile
set
fso
=
nothing
response.redirect
"
xmlToExcel.xls
"
%
>
==============xmlToExcel.xsl=============
<
xsl:stylesheet
version
="1.0"
xmlns:xsl
="http://www.w3.org/1999/XSL/Transform"
xmlns:s
=’uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882’
xmlns:dt
=’uuid:C2F41010-65B3-11d1-A29F-00AA00C14882’
xmlns:rs
=’urn:schemas-microsoft-com:rowset’
xmlns:z
=’#RowsetSchema’>
<xsl:output method
="html"
indent
="yes"
/>
<
xsl:template
match
="xml/rs:data"
>
<
html
xmlns:o
="urn:schemas-microsoft-com:office:office"
xmlns:x
="urn:schemas-microsoft-com:office:excel"
xmlns
="http://www.w3.org/TR/REC-html40"
>
<
head
>
<
meta
http-equiv
="Content-Type"
content
="text/html;charset=gb2312"
/>
<
style
>
.xl24{mso-style-parent:style0;mso-number-format:"\@";text-align:right;}
</
style
>
<
xml
>
<
x:ExcelWorkbook
>
<
x:ExcelWorksheets
>
<
x:ExcelWorksheet
>
<
x:Name
>
Sheet1
</
x:Name
>
<
x:WorksheetOptions
>
<
x:ProtectContents
>
False
</
x:ProtectContents
>
<
x:ProtectObjects
>
False
</
x:ProtectObjects
>
<
x:ProtectScenarios
>
False
</
x:ProtectScenarios
>
</
x:WorksheetOptions
>
</
x:ExcelWorksheet
>
</
x:ExcelWorksheets
>
</
x:ExcelWorkbook
>
</
xml
>
</
head
>
<
body
>
<
table
border
="1"
cellpadding
="0"
cellspacing
="0"
>
<
tr
><
xsl:for-each
select
="/xml/s:Schema/s:ElementType/s:AttributeType"
>
<
th
><
xsl:value-of
select
="@name"
/></
th
>
</
xsl:for-each
>
</
tr
>
<
xsl:apply-templates
select
="z:row"
/>
</
table
>
</
body
>
</
html
>
</
xsl:template
>
<
xsl:template
match
="z:row"
>
<
xsl:variable
name
="position"
><
xsl:value-of
select
="position()"
/></
xsl:variable
>
<
tr
><
xsl:for-each
select
="/xml/s:Schema/s:ElementType/s:AttributeType"
>
<!--
读取定义好的数据列名
-->
<
xsl:variable
name
="strColumn"
><
xsl:value-of
select
="@name"
/></
xsl:variable
>
<
xsl:variable
name
="strvalue"
><
xsl:value-of
select
="/xml/rs:data/z:row[position()=$position]/@*[name() = $strColumn]"
/></
xsl:variable
>
<
td
class
="xl24"
>
<
xsl:value-of
select
="$strvalue"
/>
</
td
>
</
xsl:for-each
>
</
tr
>
</
xsl:template
>
</
xsl:stylesheet
>
补充一下:对于第三种方法因为Recordset 用 Save方法后有时对于那些null的字段在row中不会有它的字段名,所以我现在通过去ElementType那里读取字段名,以保证不造成到时的 Excel的纵列方位出错,但这个问题在.net里的DataSet确很好解决,因为DataSet中如果碰到这种null的数据它也会有< columnName />这样的空节点出现。
问题:
能保証select出正確的數據后﹐如果仍沒看到需要的Excel內容的話﹐請確認以下情況:
1.估計是你的msxml版本低了﹐試試去MS下載個msxmlsp2或更高的版本安裝再看看
2.請確定你的FSO有足夠的讀寫權限
3.請保証同名的Excel文件沒在使用中
怎樣修改標題名﹕
這個可以在select 時用別名來命名好標題名﹐但如果用中文的時候有時會出錯﹐我在簡繁體之間就飽受這點的困擾﹔如果不要做到通用的話也可以直接在xsl文件里修改
--------------------------------------------------------------------
以上三种方法