1. 程式人生 > >ASP 操作ADO 讀寫Excel檔案

ASP 操作ADO 讀寫Excel檔案

為了把資料庫中的資料匯出Excel,在網上找了N多的資料有直接伺服器中建立excel的,也有用owc生成的,還有javascript輸出的,每種方法開始是以為不錯最後經過除錯和試用都發現了這樣和那樣的問題。比如,CreateObject("Excel.Application") 此方法無法建立物件,伺服器端有excel office;Response.ContentType = "application/vnd.ms-excel" ,此方法容易輸入亂碼並且操作excel的格式困難,資料量較大(試用生成的檔案才2M多)時開啟excel超慢;Scripting.FileSystemObject,此方法也可以直接生成excel檔案,但無法操作utf-8編碼,同樣是亂碼;Javascript excelapp=new activexObject("excel.application") 此方法與

application/vnd.ms-excel問題類似,並且在用<input onclick='';>呼叫時IE8點選無反應。

終於解決了問題並貼出相關程式碼:

[code]

<!--#include file="code.asp"-->
<!--#include file="conn.asp"-->
<%
  
    Dim sSourceXLS
    Dim sDestXLS
    Dim sNWind

    sSourceXLS = Server.MapPath(".") & "/templet/export.xls"  '伺服器excel模板位置
    filename="export_"&session("username")&"_"&year(date())&month(date())&day(date())&hour(time())&Minute(time())&second(time())&".xls"
    filepath="/export/"&filename                                                '要建立檔案的位置
    sDestXLS = Server.MapPath(".") & filepath
    exportpath="/sales"&filepath                                               '子目錄位置這個與程式位置環境有關
     'Copy the source workbook file (the "template") to the destination filename
    Dim fso
    Set fso = Server.CreateObject("Scripting.FileSystemObject")
    fso.GetFile(sSourceXLS).Copy sDestXLS
    Set fso = Nothing
    'Open the ADO connection to the Excel workbook
    Dim oConn
    Set oConn = Server.CreateObject("ADODB.Connection")
    oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
               "Data Source=" & sDestXLS & ";" & _
               "Extended Properties=""Excel 8.0;HDR=NO;"""

    'Open a connection to the Northwind database and retrieve the Order information
    'in OrderDetails table
    Dim oNWindConn, oOrdersRS
  
    Set oOrdersRS = Server.CreateObject("ADODB.Recordset")
  
    sqlstr="select * from sales"
    oOrdersRS.open sqlstr,conn,3
    'oOrdersRS.Open "SELECT [Order Details].OrderID, Products.ProductName, " & _
    '               "[Order Details].UnitPrice , [Order Details].Quantity, " & _
    '               "[Order Details].Discount FROM Products INNER JOIN " & _
    '               "[Order Details] ON Products.ProductID = " & _
    '               "[Order Details].ProductID ORDER BY [Order Details].OrderID", _
    '               conn, 3
                  
    '**Note: The first "row" in the Orders_Table is hidden -- it contains dummy data that
    '        the OLE DB Provider uses to determine the data types for the table.
   
    'Add the data from the Order Details table in Northwind to the workbook

    Dim oRS
    Set oRS = Server.CreateObject("ADODB.Recordset")
    oRS.Open "Select * from export_table", oConn, 1, 3          '注意這裡在模板中要先定義一個名稱,此工具在excel檔案選單欄的插入--名稱--定義中找到。
               

    oRS.addnew
      For i = 0 To oOrdersRS.fields.count-1
            oRS.Fields(i).Value = oOrdersRS.Fields(i).name
        Next
     oRS.Update
        oOrdersRS.MoveNext
    Do While Not (oOrdersRS.EOF)
        oRS.AddNew
        For i = 0 To oOrdersRS.fields.count-1
            oRS.Fields(i).Value = oOrdersRS.Fields(i).Value
        Next
        oRS.Update
        oOrdersRS.MoveNext
    Loop
   
    'Close the recordset and connection to Northwind
    oOrdersRS.Close
    Set oOrdersRS = Nothing
    oNWindConn.Close
    Set oNWindConn = Nothing
   
    'Close the connection to the workbook
    oConn.Close
    Set oConn = Nothing

   response.write "pls,right hit save as to download your export file:<a href='"&exportpath&"'>"&filename&" </a>"

%>

[/code]

另外此種方法亦有個小問題,模板設定好的表名稱不知道用什麼方法修改,通過次找到微軟的一個頁面可以在建立表時設定名稱如下連結

如何複製模板中的表

您可以使用 SELECT INTO 語句將 Jet 可以讀取的任何資料來源中的資料複製到任何資料目標,隨時建立新的表(在 Excel 中為新工作表)。將工作表名稱用作目標時,不要使用美元符號語法,例如 [Sheet1$]。目標工作簿可以存在,也可以不存在;但是,目標工作表必須尚未存在。

對於將整個 Customers 表從 Microsoft Access Northwind 資料庫複製到 Excel 工作簿的新工作表中的複製命令,有三種編寫方法。每種語法需要一個 SQL 語句並在目標工作表的第一行建立列標題。

  • 以下示例使用 SELECT INTO 語法:
    Dim strSQL As String
    strSQL = "SELECT * INTO [Excel 8.0;Database=" & App.Path & _ 
        "/book1.xls].[Sheet1] FROM Customers"
    cnSrc.Execute strSQL
    					
  • 以下示例使用 SELECT INTO ...IN 語法:
    strSQL = "SELECT * INTO [Sheet1] IN '' [Excel 8.0;Database=" & App.Path & _
        "/book1.xls] FROM Customers"
    						
    其中,括號中的目標資料庫資訊的前面有一對空的單引號,用來包括型別引數(“Excel 8.0”部分),當您使用此語法時,型別引數括在括號中。
  • 以下示例使用 IN 子句的替代語法:
    strSQL = "SELECT * INTO [Sheet1] IN '" & App.Path & _
        "/book1.xls' 'Excel 8.0;' FROM Customers"
    						
    其中,型別引數現在被單獨列在目標檔案路徑之後。

修改後的程式碼如下:

[code]


    Dim sSourceXLS
    Dim sDestXLS

    sSourceXLS = Server.MapPath(".") & "/templet/export.xls"
    filename=userdepart&"-"&session("username")&"_"&year(date())&month(date())&day(date())&hour(time())&Minute(time())&second(time())&".xls"
    filepath="/export/"&filename
    sDestXLS = Server.MapPath(".") & filepath
    exportpath="/annual"&filepath
     'Copy the source workbook file (the "template") to the destination filename
    Dim fso
    Set fso = Server.CreateObject("Scripting.FileSystemObject")
    fso.GetFile(sSourceXLS).Copy sDestXLS
    Set fso = Nothing
    'Open the ADO connection to the Excel workbook
    Dim oConn
    Set oConn = Server.CreateObject("ADODB.Connection")
    oConn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
               "Data Source=" & sDestXLS & ";" & _
               "Extended Properties=""Excel 8.0;HDR=NO;"""
    Dim oOrdersRS,oRS
    Set oRS = Server.CreateObject("ADODB.Recordset")
    Set oOrdersRS = Server.CreateObject("ADODB.Recordset")
    if userdepart<>"" then
     sqlstr="select distinct userid,username from annual_v where department='"&userdepart&"'"
   else
     sqlstr="select distinct userid,username from annual_v where userid="&mainkey
    end if
    set rs=conn.execute (sqlstr,0,1)
    
    do while not rs.eof
     sqlstr="select * into [Excel 8.0;Database="&sDestXLS&"].["&rs("username")&"] from [Templet$]"
     oConn.execute sqlstr '從模板中複製使用者名錶
     
      sqlstr="select joined from user_table where userid="&rs("userid")
    set temprs=conn.execute (sqlstr,0,1)
     joineddate=temprs("joined")
    set temprs=nothing
     
     sqlstr="select * from annual_v where userid="&rs("userid")&" order by whatdate"
     oOrdersRS.open sqlstr,conn,3
     
     sqlstr="select * from ["&rs("username")&"]"
     oRS.open sqlstr,oConn,1,3
    i=0
    do while not oRS.eof
     if i=3 then
      oRS.fields(2)=rs("username")
      oRS.update
     end if
     if i=4 then
      oRs.fields(2)=joineddate
      oRS.update
     end if
     i=i+1
     oRS.movenext
    loop
    
   
      Do While Not (oOrdersRS.EOF)
        oRS.AddNew
       
        oRS.Fields(0)=oOrdersRS("whatdate")&":"&oOrdersRS("something")
      
        if isnumeric(oOrdersRS("adddate")) then
         adddate=oOrdersRS("adddate")
        else
         adddate=0
        end if
        if isnumeric(oOrdersRS("divdate")) then
         divdate=oOrdersRS("divdate")
        else
         divdate=0
        end if        
        select case oOrdersRS("sttype")
         case 1
          leave(1)=leave(1)+adddate-divdate
          oRS.Fields(1)=adddate
          oRS.Fields(3)=divdate          
          oRS.Fields(4)=leave(1)
         case 2
          leave(2)=leave(2)+adddate-divdate
          oRS.Fields(5)=adddate
          oRS.Fields(7)=divdate
          oRS.Fields(8)=leave(2)
         case 3
          leave(3)=leave(3)+adddate-divdate
          oRS.Fields(9)=adddate
          oRS.Fields(11)=divdate
          oRS.Fields(12)=leave(3)
         case 4
          leave(4)=leave(4)+adddate-divdate
          oRS.Fields(13)=adddate
          oRS.Fields(14)=divdate
          oRS.Fields(16)=leave(4)
         case else
         end select
         
        oRS.Fields(17)=oOrdersRS("remark")    
        oRS.Update
        oOrdersRS.MoveNext
     Loop
     oOrdersRS.Close
     oRS.close
   rs.movenext
  loop

    
    Set oOrdersRS = Nothing
    
    oConn.Close
    Set oConn = Nothing
 
   response.write "pls,right hit save as to download your export file:<a href='"&exportpath&"'>"&filename&" </a>"
   response.write "<input type='button' value='ReturnBack' onclick='history.back(-1);'>"

[/code]

但此方法開啟ADO進行寫資料後模板中設定的格式丟失了。有沒有二合一的方法呢?繼續查資料中。