Free Programming

我的生活在一行又一行的代码中前行........

 

web中把Table的资料转到Excel里面去 (转)

(来自: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文件里修改

--------------------------------------------------------------------
以上三种方法

posted on 2007-01-14 21:37  sharewind  阅读(719)  评论(0编辑  收藏  举报

导航