Asp.net生成Excel文件并下載(更新:解決使用迅雷下載頁(yè)面而不是文件的問(wèn)題)
生成Excel文件的方法,見(jiàn):【原】.Net創(chuàng)建Excel文件(插入數(shù)據(jù)、修改格式、生成圖表)的方法
先試用Response.WriteFile的方法:
FileInfo fi = new FileInfo(excelFile);//excelFile為文件在服務(wù)器上的地址
HttpResponse contextResponse = HttpContext.Current.Response;
contextResponse.Clear();
contextResponse.Buffer = true;
contextResponse.Charset = "GB2312"; //設(shè)置了類型為中文防止亂碼的出現(xiàn)
contextResponse.AppendHeader("Content-Disposition", String.Format("attachment;filename={0}", excelName)); //定義輸出文件和文件名
contextResponse.AppendHeader("Content-Length", fi.Length.ToString());
contextResponse.ContentEncoding = Encoding.Default;
contextResponse.ContentType = "application/ms-excel";//設(shè)置輸出文件類型為excel文件。
contextResponse.WriteFile(fi.FullName);
contextResponse.Flush();
contextResponse.End();
其中第一行的excelFile為Excel文件在服務(wù)器上的地址,比如:“C:\Website\Excel\xx.xlsx”。
這種方法也是網(wǎng)上一般提供的方法,但在實(shí)際操作中,卻出現(xiàn)了意向不到的問(wèn)題:
在Chrome下
一切正常,Excel文件直接下載到Chrome的默認(rèn)下載文件夾中。
在Firefox下
由于安裝了FlashGot插件,會(huì)先選擇應(yīng)用的下載工具:
在這里顯示是正常的,如果選擇“保存文件”,Excel文件也會(huì)被保存到默認(rèn)文件夾中,但如果試用第三方下載工具,比如迅雷,會(huì)出現(xiàn)如下窗口:
注意到網(wǎng)址一欄,會(huì)在頁(yè)面實(shí)際地址后添加ViewState信息,而另存名稱也不是Excel文件本身的名稱,而是頁(yè)面的名稱。
點(diǎn)擊確定后,被下載的文件又變成了實(shí)際文件(有時(shí)會(huì)先變成.zip文件,再變?yōu)閷?shí)際文件)
在IE7下
會(huì)先彈出保存對(duì)話框,文件正常,同樣因?yàn)檠b了迅雷的緣故,點(diǎn)保存時(shí),彈出迅雷的下載對(duì)話框,和Firefox下不同,網(wǎng)址后面沒(méi)有ViewState信息。
點(diǎn)確定,下載的則是頁(yè)面文件:
如果在迅雷的下載對(duì)話框中點(diǎn)取消,則會(huì)使用IE的下載,這里的文件又是正確的了:
懷疑迅雷是根據(jù)下載對(duì)話框中的網(wǎng)址重新請(qǐng)求下載,與發(fā)起請(qǐng)求的頁(yè)面已經(jīng)無(wú)關(guān),而IE又不會(huì)把ViewState信息傳到迅雷中,導(dǎo)致下載的文件不是想要的Excel頁(yè)面。
之后又嘗試了分段下載的方式,其實(shí)也是無(wú)效的,因?yàn)檠咐赘静焕頃?huì)你提供給它的下載機(jī)制,而且這樣在Firefox下調(diào)用迅雷時(shí),由于分段下載的Viewstate并不包含Excel文件的完整信息,迅雷下載下的也是殘缺的文件。
最后只能采用最老土的解決方法:Response.Redirect(),轉(zhuǎn)向?qū)嶋H文件地址。
FileInfo fi = new FileInfo(excelFile);
HttpResponse contextResponse = HttpContext.Current.Response;
contextResponse.Redirect(string.Format("~/Template/{0}", excelName), false);
這樣在三個(gè)瀏覽器下測(cè)試都正常了,因?yàn)檎?qǐng)求的是實(shí)際文件的地址,在迅雷中顯示的也是實(shí)際文件的地址。下載就不會(huì)出現(xiàn)問(wèn)題。但這樣相當(dāng)于告知客戶端用戶文件的實(shí)際地址,隱私性不佳。但好在這里并不需要太好的隱私性,而且文件會(huì)在一定時(shí)間之后刪除,所以倒并不是太大的問(wèn)題了。
上面是第一次考慮的結(jié)果,似乎還是有些懶了……
事后考慮,既然每次迅雷實(shí)際都是重新請(qǐng)求URL,那么我們就應(yīng)該給迅雷傳入一個(gè)能生成Excel文件的URL。
即,在點(diǎn)擊“生成Excel”按鈕的時(shí)候,轉(zhuǎn)向另一個(gè)Export頁(yè)面,在這個(gè)頁(yè)面的Page_Load方法中完成生成Excel文件、下載Excel文件的步驟。
String fileName = Request.QueryString["FileName"];
String exportName = Request.QueryString["Export"];
if(fileName != null)
{
ExportManger.CreateExcel(fileName);//先在服務(wù)器端創(chuàng)建Excel文件。
Response.Redirect(String.Format("{0}?Export={1}",Request.Path.ToString(),fileName));//重定向到本頁(yè)面,但Query參數(shù)變?yōu)镋xport。
}
else if(exportName != null)
{
ExportManger.ExportExcel(exportName);//下載Excel文件。
}
這里頁(yè)面跳轉(zhuǎn)了兩次,第一次是生成Excel,第二次是下載Excel。
之所以跳轉(zhuǎn)兩次,是因?yàn)檠咐讜?huì)捕獲最后的URL,如果生成和下載放在一起進(jìn)行,那么迅雷下載時(shí)會(huì)重復(fù)再生成一遍Excel文件。下載Excel文件的代碼ExportManger.ExportExcel(exportName)就使用了本文開(kāi)頭介紹的Response.Write方法,也可以用分段下載的方法:
if(fi.Length > 0)
{
FileStream sr = new FileStream(fi.FullName,System.IO.FileMode.Open,System.IO.FileAccess.Read, System.IO.FileShare.Read);
int size = 1024;//設(shè)置每次讀取長(zhǎng)度。
for (int i = 0; i < fi.Length / size + 1; i++)
{
byte[] buffer = new byte[size];
int length = sr.Read(buffer, 0, size);
contextResponse.OutputStream.Write(buffer, 0, length);
}
sr.Close();
}
else
{
contextResponse.WriteFile(fi.FullName);
}
這里的結(jié)果是只生成了一次Excel并在服務(wù)器保留,以后每次下載的時(shí)候都使用帶"Export"的參數(shù)下載相同的文件。那么如果需要文件只是一次性的,每次下載都需要重新生成,則只需要把Export頁(yè)面的下載和生成放到一起。然后把開(kāi)頭的Response.Write方法最后變成:
contextResponse.Flush();
fi.Delete();
contextResponse.End();
即每次響應(yīng)清空后把文件先刪除,再結(jié)束響應(yīng)。這樣就解決了利用下載工具出現(xiàn)的下載不能的問(wèn)題,同時(shí)保護(hù)了服務(wù)器文件地址的隱私,并可以采用分段寫(xiě)入的方法寫(xiě)入大文件,而且可以按需要即時(shí)刪除生成的文件而不占用服務(wù)器空間。
- ASP.NET MVC3關(guān)于生成純靜態(tài)后如何不再走路由直接訪問(wèn)靜態(tài)頁(yè)面
- 使用ASP.NET模板生成HTML靜態(tài)頁(yè)面的五種方案
- ASP.NET動(dòng)態(tài)生成靜態(tài)頁(yè)面的實(shí)例代碼
- ASP.NET 生成靜態(tài)頁(yè)面 實(shí)現(xiàn)思路
- Asp.NET 生成靜態(tài)頁(yè)面并分頁(yè)的代碼
- Asp.Net生成靜態(tài)頁(yè)面的實(shí)現(xiàn)方法
- ASP.NET MVC生成靜態(tài)頁(yè)面的方法
- asp.net生成Excel并導(dǎo)出下載五種實(shí)現(xiàn)方法
- asp.net(C#) 生成隨機(jī)驗(yàn)證碼的代碼
- ASP.net(c#)生成條形碼 code39條碼生成方法
- asp.net C#生成和解析二維碼的實(shí)例代碼
- ASP.NET編程簡(jiǎn)單實(shí)現(xiàn)生成靜態(tài)頁(yè)面的方法【附demo源碼下載】
相關(guān)文章
SQL為查詢的結(jié)果加上序號(hào)(ROW_NUMBER) 合并多個(gè)查詢結(jié)果
SQL為查詢的結(jié)果加上序號(hào)(ROW_NUMBER) 合并多個(gè)查詢結(jié)果2010-03-03asp.net使用JS+form表單Post和Get方式提交數(shù)據(jù)
今天小編就為大家分享一篇關(guān)于asp.net使用JS+form表單Post和Get方式提交數(shù)據(jù),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-01-01asp.net 無(wú)刷新翻頁(yè)就是這么簡(jiǎn)單
前兩天看了一個(gè)自定義分頁(yè)控件,和AspNetPager一樣是實(shí)現(xiàn)IPostBackEventHandler接口,不過(guò)簡(jiǎn)潔許多,就想能不能實(shí)現(xiàn)ICallbackEventHandler接口做到無(wú)刷新分頁(yè)呢?想到了就馬上去做,終于,設(shè)想變成了現(xiàn)實(shí)?。?/div> 2010-03-03asp.net 網(wǎng)頁(yè)編碼自動(dòng)識(shí)別代碼
另外一位網(wǎng)友空間/IV提供的代碼,功能同HttpWebRequest獲取網(wǎng)頁(yè)源代碼時(shí)自動(dòng)識(shí)別網(wǎng)頁(yè)編碼2008-09-09.net使用jwt進(jìn)行身份認(rèn)證的流程記錄
這篇文章主要給大家介紹了關(guān)于.net使用jwt進(jìn)行身份認(rèn)證的相關(guān)資料,JWT是Auth0提出的通過(guò)對(duì)JSON進(jìn)行加密簽名來(lái)實(shí)現(xiàn)授權(quán)驗(yàn)證的方案,本文通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09asp.net程序編譯調(diào)試時(shí)偶爾出現(xiàn)訪問(wèn)被拒絕的錯(cuò)誤的解決方法
asp.net程序編譯調(diào)試時(shí)偶爾出現(xiàn)訪問(wèn)被拒絕的錯(cuò)誤的解決方法...2007-04-04.NET IoC模式依賴反轉(zhuǎn)(DIP)、控制反轉(zhuǎn)(Ioc)、依賴注入(DI)
這篇文章主要介紹了.NET IoC模式依賴反轉(zhuǎn)(DIP)、控制反轉(zhuǎn)(Ioc)、依賴注入(DI),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06最新評(píng)論