如何在ASP.NET中下載檔案
這是筆者常被問到的一個問題,如何透過ASP.NET來下載檔案,這個問題可大可小,我們先從小的開始。當我們要讓使用者下載一個檔案,最簡單的方式是透過Response.Redirect指令:
Response.Redirect("test.doc")
您可以把上面這行指令放在Button的Click事件當中,當使用者按下按鈕之後,網頁就會被轉址到該word檔,造成下載的效果。
但是這樣的下載有幾個問題:
- 無法下載不存在的檔案:例如,我們若是想把程式動態(臨時)產生的文字,當作一個檔案下載的時候(也就是該檔案其實原先並不是真的存在,而是動態產生的),就無法下載。
- 無法下載儲存於資料庫中的檔案:這是類似的問題,該檔案並沒有真的存在,只是被存放在資料庫中的某個位置(某筆記錄中的某個欄位)的時候,就無法下載。
- 無法下載不存在於Web資料夾中的檔案:檔案確實存在,但該資料夾並不是可以分享出來的Web資料夾,例如,該檔案的位置在C:\winnt,您總不會想要把該資料夾當作Web資料夾吧?這時候,由於您無法使用Redirect指向該位置,所以無法下載。
- 下載檔案後,原本的頁面將會消失。
典型的狀況是,我們要讓使用者下載一個.txt文字檔,或是.csv格式的Excel檔案,但是...
- 這個檔案可能是透過ASP.NET程式動態產生的,而不是確實存在於Server端的檔案;
- 或是它雖然存在於伺服器端的某個實體位置,但我們並不想暴露這個位置(如果這個位置公開,很可能沒有權限的使用者也可以在網址列上輸入URL直接取得!!!)
- 或是這個位置並不在網站虛擬路徑所在的資料夾中。(例如C:\Windows\System32...)
這時候,我們就得採用不同的方式:
Shared Function DownloadFile(ByVal WebForm As System.Web.UI.Page, ByVal FileNameWhenUserDownload As String, ByVal FileBody As String)
WebForm.Response.ClearHeaders()
WebForm.Response.Clear()
WebForm.Response.Expires = 0
WebForm.Response.Buffer = True
WebForm.Response.AddHeader("Accept-Language", "zh-tw")
'檔案名稱
WebForm.Response.AddHeader("content-disposition", "attachment; filename=" & Chr(34) & System.Web.HttpUtility.UrlEncode(FileNameWhenUserDownload, System.Text.Encoding.UTF8) & Chr(34))
WebForm.Response.ContentType = "Application/octet-stream"
'檔案內容
WebForm.Response.Write(FileBody)
WebForm.Response.End()
End Function
上面這段程式碼是下載一個動態產生的文字檔,若這個檔案已經存在於伺服器端的實體路徑,則可以透過底下的函式:
WebForm.Response.ClearHeaders()
WebForm.Response.Clear()
WebForm.Response.Expires = 0
WebForm.Response.Buffer = True
WebForm.Response.AddHeader("Accept-Language", "zh-tw")
'檔案名稱
WebForm.Response.AddHeader("content-disposition", "attachment; filename=" & Chr(34) & System.Web.HttpUtility.UrlEncode(FileNameWhenUserDownload, System.Text.Encoding.UTF8) & Chr(34))
WebForm.Response.ContentType = "Application/octet-stream"
'檔案內容
WebForm.Response.Write(System.IO.File.ReadAllBytes(FilePath))
WebForm.Response.End()
End Sub
上面這兩個下載檔案的的函式,應可解決大多數開發人員在ASP.NET當中的檔案下載問題。
留言
上述資料流下載的方式,要如何應用在Ajax中呢?
最近公司要用到,就找到那麼好的文章
真是非常感謝
html的標頭之類碼到文字檔內,這會造成使用者的不便以及錯誤.
請問是否有方法解決呢?
我的code參照你的以後,發現也是相差無幾,
但我就是試不出來只有原文字檔內容,
可麻煩版大幫忙一下,謝謝!!
原因是 file name 中有空白才不會出現 "+" 號
建議將 Write(System.IO.File.ReadAllBytes(FilePath))改成
BinaryWrite(System.IO.File.ReadAllBytes(FilePath))
原因是下載的檔案內容才不會僅出現 System.Byte[] 而不是檔案真下的內容
WebForm.Response.BinaryWrite(System.IO.File.ReadAllBytes(FilePath))
改成 MSDN 的寫法
http://msdn.microsoft.com/en-us/library/system.web.httpresponse.binarywrite(v=vs.71).aspx
原因:System.ArgumentOutOfRangeException