• Asp.net直接保存(下载)文件到客户端


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

      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 }

        最后得出结论:要实现柚子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

  • 相关阅读:
    [转发]深入理解git,从研究git目录开始
    iOS系统网络抓包方法
    charles抓包工具
    iOS多线程中performSelector: 和dispatch_time的不同
    IOS Core Animation Advanced Techniques的学习笔记(五)
    IOS Core Animation Advanced Techniques的学习笔记(四)
    IOS Core Animation Advanced Techniques的学习笔记(三)
    IOS Core Animation Advanced Techniques的学习笔记(二)
    IOS Core Animation Advanced Techniques的学习笔记(一)
    VirtualBox复制CentOS后提示Device eth0 does not seem to be present的解决方法
  • 原文地址:https://www.cnblogs.com/nianshi/p/794425.html
Copyright © 2020-2023  润新知