在我們的系統的編寫過程中,應該有很多的時候需要客戶下載文件.我第一次的做法(應該也是大部分人的做法吧?)是:
1 httpresponse response = httpcontext.current.response;
2 string js = "<script language=javascript>window.open('{0}');</script>";
3 js = string.format(js, url);
4 response.write(js);
5
但是有個問題了,就是會被廣告攔截軟件直接攔截掉,另我非常的頭痛,于是尋找更好的解決方法.看了用response.binarywrite寫文件流一文之后覺得確實可以如此,修改代碼如下:
1/**//**//**//// <summary>
2 /**//// 下載文件
3 /**//// </summary>
4 /**//// <param name="filename">文件物理地址</param>
5
6protected void downloadfile(string filename)
7 ...{
8 string savefilename = "test.xls";
9 int intstart = filename.lastindexof("/")+1;
10 savefilename = filename.substring(intstart,filename.length-intstart);
11 filestream myfilestream;
12 long filesize;
13
14 myfilestream = new filestream(filename,filemode.open);
15 filesize = myfilestream.length;
16
17 byte[] buffer = new byte[(int)filesize];
18 myfilestream.read(buffer, 0, (int)filesize);
19 myfilestream.close();
20
21 response.addheader("content-disposition", "attachment;filename="+savefilename);
22 response.contentencoding = system.text.encoding.getencoding("gb2312");
23 response.contenttype = "application/vnd.ms-excel";
24
25 response.binarywrite(buffer);
26 response.flush();
27 response.close();
28 response.end();
29
30 }
但是有個嚴重的問題,就是文件格式。這樣只是將流輸出,且無法正確識別格式。還好,能人層出不窮, 柚子nan 提出了能否不考慮文件的類型,直接把文件顯示到瀏覽器(response) 的想法正好切中我的要害所在,于是急忙研究了柚子nan的想法,修改出最后代碼:
1 /**//**//**//// <summary>
2 /**//// 下載文件
3 /**//// </summary>
4 /**//// <param name="filename">文件物理地址</param>
5 protected void downloadfile(string filename)
6 ...{
7 string savefilename = "test.xls";
8 int intstart = filename.lastindexof("/")+1;
9 savefilename = filename.substring(intstart,filename.length-intstart);
10
11 response.clear();
12 response.charset = "utf-8";
13 response.buffer= true;
14 this.enableviewstate = false;
15 response.contentencoding = system.text.encoding.utf8;
16
17 response.appendheader("content-disposition","attachment;filename=" + savefilename);
18 response.writefile(filename);
19 response.flush();
20 response.close();
21
22 response.end();
23 }
使用昨天asp.net直接保存文件到客戶端 中的方法,經過我的反復測試,各式文檔都運行完全正常。于是昨晚修改了現有代碼,修改了下載方法,以解決一直困擾自己的窗口攔截問題。
早上本來還沾沾自喜,這下再也不用老跟客戶解釋為什么窗口會沒掉了。可惜啊,人算不如天算。
早上客戶就反映下載的文件全是亂碼。立馬在本機進行測試,沒問題。再同事的機器上試驗,同樣沒問題。
那應該是客戶端的問題才是。只好讓客戶netmeeting演示一下她的操作過程。下載-〉保存-〉打開。這么簡單的流程,不會做錯吧?
正在郁悶之際,突然腦光一閃,終于發現不一樣的地方,立馬試驗,果然如此!
到底有什么區別呢?請看操作圖:
客人操作圖
我的操作圖
各位應該看出不同之處了吧?還看不出來?
這件事情的罪魁禍首就是:
解決方法:使用lovecherry 的如何從注冊表讀取文件的contenttype 一文的方法
修正代碼:
1 /**//// <summary>
2 /// 下載文件
3 /// </summary>
4 /// <param name="filename">文件物理地址</param>
5 protected void downloadfile(string filename)
6 {
7
8 string savefilename = "test.xls";
9 int intstart = filename.lastindexof("http://")+1;
10 savefilename = filename.substring(intstart,filename.length-intstart);
11
12 system.io.fileinfo fi=new system.io.fileinfo(filename);
13 string fileextname=fi.extension;
14 string default_content_type = "application/unknown";
15 registrykey regkey,fileextkey;
16 string filecontenttype;
17 try
18 {
19 regkey=registry.classesroot;
20 fileextkey=regkey.opensubkey(fileextname);
21 filecontenttype=fileextkey.getvalue("content type",default_content_type).tostring();
22 }
23 catch
24 {
25 filecontenttype=default_content_type;
26 }
27
28
29 response.clear();
30 response.charset = "utf-8";
31 response.buffer= true;
32 this.enableviewstate = false;
33 response.contentencoding = system.text.encoding.utf8;
34
35 response.appendheader("content-disposition","attachment;filename=" + savefilename);
36 response.contenttype=filecontenttype;
37
38 response.writefile(filename);
39 response.flush();
40 response.close();
41
42 response.end();
43 }
44
最后得出結論:要實現柚子nan提出的能否不考慮文件的類型,直接把文件顯示到瀏覽器(response),有一種方法,讓客戶端都不要隱藏已知的擴展名,但是這種方法是無法適應大部分電腦使用者的(一般只有比較熟悉電腦的人才會這樣做吧?)
bbs 看中的方法,還沒有試用,不知道有沒有作用.
private sub page_load(byval sender as system.object, byval e as system.eventargs) _
handles mybase.load
'在此處放置初始化頁的用戶代碼
' 定義是否是 sql server 數據庫,這里為false
dim blnissqlserver as system.boolean = false
dim strsql as string
dim objdataset as new dataset()
dim objconn as object
dim strcnn as string
if blnissqlserver then
strcnn = "user id=sa;initial catalog=northwind;data source=./netsdk;"
objconn = new system.data.sqlclient.sqlconnection(strcnn)
objconn.open()
dim objadapter as new system.data.sqlclient.sqldataadapter()
strsql = "select * from customers where country='usa'"
objadapter.selectcommand = new system.data.sqlclient.sqlcommand(strsql, objconn)
objadapter.fill(objdataset)
else
strcnn = "provider=microsoft.jet.oledb.4.0;data source=" + server.mappath("test.mdb")
objconn = new system.data.oledb.oledbconnection(strcnn)
objconn.open()
dim objadapter as new system.data.oledb.oledbdataadapter()
strsql = "select top 10 title from document"
objadapter.selectcommand = new system.data.oledb.oledbcommand(strsql, objconn)
objadapter.fill(objdataset)
end if
dim oview as new dataview(objdataset.tables(0))
datagrid1.datasource = oview
datagrid1.databind()
objconn.close()
objconn.dispose()
objconn = nothing
if request.querystring("bexcel") = "1" then
response.contenttype = "application/vnd.ms-excel"
' 從content-type header中去除charset設置
response.charset = ""
' 關閉 viewstate
me.enableviewstate = false
dim tw as new system.io.stringwriter()
dim hw as new system.web.ui.htmltextwriter(tw)
' 獲取control的html
datagrid1.rendercontrol(hw)
' 把html寫回瀏覽器
response.write(tw.tostring())
response.end()
end if
end sub
新聞熱點
疑難解答
圖片精選