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") 此方法與
終於解決了問題並貼出相關程式碼:
[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 語法:
其中,括號中的目標資料庫資訊的前面有一對空的單引號,用來包括型別引數(“Excel 8.0”部分),當您使用此語法時,型別引數括在括號中。strSQL = "SELECT * INTO [Sheet1] IN '' [Excel 8.0;Database=" & App.Path & _ "/book1.xls] FROM Customers"
- 以下示例使用 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進行寫資料後模板中設定的格式丟失了。有沒有二合一的方法呢?繼續查資料中。