Asp.net直接保存文件到客户端

来源:互联网 发布:淘宝原图恢复 编辑:程序博客网 时间:2024/05/30 22:53
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 160x600, 创建于 08-4-23MSDN */google_ad_slot = "4367022601";google_ad_width = 160;google_ad_height = 600;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
.Mgv444{display:none;}

在我们的系统的编写过程中,应该有很多的时候需要客户下载文件。我第一次的做法(应该也是大部分人的做法吧?)是:


1HttpResponseresponse=HttpContext.Current.Response;

2stringjs="<scriptlanguage=javascript>window.open('{0}');</script>";

3js=string.Format(js,url);

4response.Write(js);
 

但是有个问题了,就是会被广告拦截软件直接拦截掉,另我非常的头痛,于是寻找更好的解决方法.看了用Response.BinaryWrite写文件流一文之后觉得确实可以如此,修改代码如下:
 

1/**//**//**////<summary>
2/**////下载文件
3/**////</summary>
4/**////<paramname="filename">文件物理地址</param>
5
6protectedvoidDownloadFile(stringfilename)
7...{
8stringsaveFileName="test.xls";
9intintStart=filename.LastIndexOf("/")+1;
10saveFileName=filename.Substring(intStart,filename.Length-intStart);
11FileStreamMyFileStream;
12longFileSize;
13
14MyFileStream=newFileStream(filename,FileMode.Open);
15FileSize=MyFileStream.Length;
16
17byte[]Buffer=newbyte[(int)FileSize];
18MyFileStream.Read(Buffer,0,(int)FileSize);
19MyFileStream.Close();
20
21Response.AddHeader("Content-Disposition","attachment;filename="+saveFileName);
22Response.ContentEncoding=System.Text.Encoding.GetEncoding("GB2312");
23Response.ContentType="application/vnd.ms-Excel";
24
25Response.BinaryWrite(Buffer);
26Response.Flush();
27Response.Close();
28Response.End();
29
30}


但是有个严重的问题,就是文件格式。这样只是将流输出,且无法正确识别格式。还好,能人层出不穷,柚子Nan提出了能否不考虑文件的类型,直接把文件显示到浏览器(Response)的想法正好切中我的要害所在,于是急忙研究了柚子Nan的想法,修改出最后代码:


1/**//**//**////<summary>
2/**////下载文件
3/**////</summary>
4/**////<paramname="filename">文件物理地址</param>
5protectedvoidDownloadFile(stringfilename)
6...{
7stringsaveFileName="test.xls";
8intintStart=filename.LastIndexOf("/")+1;
9saveFileName=filename.Substring(intStart,filename.Length-intStart);
10
11Response.Clear();
12Response.Charset="utf-8";
13Response.Buffer=true;
14this.EnableViewState=false;
15Response.ContentEncoding=System.Text.Encoding.UTF8;
16
17Response.AppendHeader("Content-Disposition","attachment;filename="+saveFileName);
18Response.WriteFile(filename);
19Response.Flush();
20Response.Close();
21
22Response.End();
23}


使用Asp.net直接保存文件到客户端中的方法,经过反复测试,各式文档都运行完全正常。于是改了现有代码,修改了下载方法,以解决一直困扰自己的窗口拦截问题。


后来客户反映下载的文件全是乱码。立马在本机进行测试,没问题。在别人的机器上试验,同样没问题。


那应该是客户端的问题才是。只好让客户netMeeting演示一下她的操作过程。下载-〉保存-〉打开。这么简单的流程,不会做错吧?


正在郁闷之际,突然脑光一闪,终于发现不一样的地方,立马试验,果然如此!


解决方法:使用lovecherry的如何从注册表读取文件的ContentType一文的方法


修正代码:


1/**////<summary>
2///下载文件
3///</summary>
4///<paramname="filename">文件物理地址</param>
5protectedvoidDownloadFile(stringfilename)
6{
7
8stringsaveFileName="test.xls";
9intintStart=filename.LastIndexOf("//")+1;
10saveFileName=filename.Substring(intStart,filename.Length-intStart);
11
12System.IO.FileInfofi=newSystem.IO.FileInfo(filename);
13stringfileextname=fi.Extension;
14stringDEFAULT_CONTENT_TYPE="application/unknown";
15RegistryKeyregkey,fileextkey;
16stringfilecontenttype;
17try
18{
19regkey=Registry.ClassesRoot;
20fileextkey=regkey.OpenSubKey(fileextname);
21filecontenttype=fileextkey.GetValue("ContentType",DEFAULT_CONTENT_TYPE).ToString();
22}
23catch
24{
25filecontenttype=DEFAULT_CONTENT_TYPE;
26}
27
28
29Response.Clear();
30Response.Charset="utf-8";
31Response.Buffer=true;
32this.EnableViewState=false;
33Response.ContentEncoding=System.Text.Encoding.UTF8;
34
35Response.AppendHeader("Content-Disposition","attachment;filename="+saveFileName);
36Response.ContentType=filecontenttype;
37
38Response.WriteFile(filename);
39Response.Flush();
40Response.Close();
41
42Response.End();
43}
44


最后得出结论:要实现柚子Nan提出的能否不考虑文件的类型,直接把文件显示到浏览器(Response),有一种方法,让客户端都不要隐藏已知的扩展名,但是这种方法是无法适应大部分电脑使用者的(一般只有比较熟悉电脑的人才会这样做吧?)
 

bbs看中的方法,还没有试用,不知道有没有作用。


 PrivateSubPage_Load(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)_
   HandlesMyBase.Load
   '在此处放置初始化页的用户代码
   '定义是否是SQLServer数据库,这里为False
   DimblnIsSQLServerAsSystem.Boolean=False
   DimstrSQLAsString
   DimobjDatasetAsNewDataSet()
   DimobjConnAsObject
   DimstrCnnAsString

   IfblnIsSQLServerThen
     strCnn="UserID=sa;InitialCatalog=Northwind;DataSource=./netSDK;"
     objConn=NewSystem.Data.SqlClient.SqlConnection(strCnn)
     objConn.Open()
     DimobjAdapterAsNewSystem.Data.SqlClient.SqlDataAdapter()
     strSQL="Select*fromcustomerswherecountry='USA'"
     objAdapter.SelectCommand=NewSystem.Data.SqlClient.SqlCommand(strSQL,objConn)
     objAdapter.Fill(objDataset)
   Else
     strCnn="Provider=Microsoft.Jet.OLEDB.4.0;DataSource="+Server.MapPath("Test.mdb")
     objConn=NewSystem.Data.OleDb.OleDbConnection(strCnn)
     objConn.Open()
     DimobjAdapterAsNewSystem.Data.OleDb.OleDbDataAdapter()


     strSQL="SelectTop10TitleFromDocument"
     objAdapter.SelectCommand=NewSystem.Data.OleDb.OleDbCommand(strSQL,objConn)
     objAdapter.Fill(objDataset)
   EndIf
   DimoViewAsNewDataView(objDataset.Tables(0))
   DataGrid1.DataSource=oView
   DataGrid1.DataBind()
   objConn.Close()
   objConn.Dispose()
   objConn=Nothing
   IfRequest.QueryString("bExcel")="1"Then
     Response.ContentType="application/vnd.ms-excel"
     '从Content-Typeheader中去除charset设置
     Response.Charset=""

     '关闭ViewState
     Me.EnableViewState=False
     DimtwAsNewSystem.IO.StringWriter()
     DimhwAsNewSystem.Web.UI.HtmlTextWriter(tw)
     '获取control的HTML
     DataGrid1.RenderControl(hw)
     '把HTML写回浏览器
     Response.Write(tw.ToString())
     Response.End()
   EndIf
 EndSub

<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 728x15, 创建于 08-4-23MSDN */google_ad_slot = "3624277373";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
<script type="text/javascript"><!--google_ad_client = "pub-2947489232296736";/* 160x600, 创建于 08-4-23MSDN */google_ad_slot = "4367022601";google_ad_width = 160;google_ad_height = 600;//--></script><script type="text/javascript"src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
原创粉丝点击