在我们的系统的编写过程中,应该有很多的时候需要客户下载文件.我第一次的做法(应该也是大部分人的做法吧?)是:
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("//")+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
新闻热点
疑难解答
图片精选