当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > Asp.net直接保存文件到客户端

ASP.NET
使用函数传递参数来执行相应的数据库操作
如何实现在窗体和窗体之间进行传递数据
ASP.NET中文显示之两种解决方法
ASP.NET、JSP及PHP之间的抉择
ASP.NET 2.0发送电子邮件中存在的问题
谈谈HtmlControl与WebControl的区别与用途
从ASP.NET 1.1升级到ASP.NET 2.0要考虑的Cookie问题
通过系统配置来提高ASP.NET应用程序的稳定性
妙用ASP2.0中的URL映射改变网址
AJAX实现web页面中级联菜单的设计
ASP.NET跨页面传值技巧总结
再议ASP.NET DataGrid控件中的“添加新行”功能
Geometry 对象浅析
重构CollapsibleSplitter
如何利用.NET Framework使用RSS feed
ASP.NET获取IP与MAC地址的方法
在ASP.NET 2.0中使用样式、主题和皮肤
ASP.NET中为GridView添加删除提示框
ASP.NET 2.0,无刷新页面新境界
看看一个.net版对话框控件

ASP.NET 中的 Asp.net直接保存文件到客户端


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-23   浏览: 47 ::
收藏到网摘: n/a

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


  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);
 

  但是有个问题了,就是会被广告拦截软件直接拦截掉,另我非常的头痛,于是寻找更好的解决方法.看了用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

  请作者联系本站,及时附注您的姓名。联系邮箱:edu#ruanchen.com(把#改为@)。