FileInfo fi = new FileInfo(excelFile);
HttpResponse contextResponse = HttpContext.Current.Response;
contextResponse.Redirect(string.Format("~/Template/{0}", excelName), false);
这样在三个浏览器下测试都正常了,因为请求的是实际文件的地址,在迅雷中显示的也是实际文件的地址。下载就不会出现问题。但这样相当于告知客户端用户文件的实际地址,隐私性不佳。但好在这里并不需要太好的隐私性,而且文件会在一定时间之后删除,所以倒并不是太大的问题了。
上面是第一次考虑的结果,似乎还是有些懒了……
事后考虑,既然每次迅雷实际都是重新请求URL,那么我们就应该给迅雷传入一个能生成Excel文件的URL。
即,在点击“生成Excel”按钮的时候,转向另一个Export页面,在这个页面的Page_Load方法中完成生成Excel文件、下载Excel文件的步骤。
复制代码 代码如下:
String fileName = Request.QueryString["FileName"];
String exportName = Request.QueryString["Export"];
if(fileName != null)
{
ExportManger.CreateExcel(fileName);//先在服务器端创建Excel文件。
Response.Redirect(String.Format("{0}?Export={1}",Request.Path.ToString(),fileName));//重定向到本页面,但Query参数变为Export。
}
else if(exportName != null)
{
ExportManger.ExportExcel(exportName);//下载Excel文件。
}
这里页面跳转了两次,第一次是生成Excel,第二次是下载Excel。
之所以跳转两次,是因为迅雷会捕获最后的URL,如果生成和下载放在一起进行,那么迅雷下载时会重复再生成一遍Excel文件。下载Excel文件的代码ExportManger.ExportExcel(exportName)就使用了本文开头介绍的Response.Write方法,也可以用分段下载的方法:
复制代码 代码如下:
if(fi.Length > 0)
{
FileStream sr = new FileStream(fi.FullName,System.IO.FileMode.Open,System.IO.FileAccess.Read, System.IO.FileShare.Read);
int size = 1024;//设置每次读取长度。
for (int i = 0; i < fi.Length / size + 1; i++)
{
byte[] buffer = new byte[size];
int length = sr.Read(buffer, 0, size);
contextResponse.OutputStream.Write(buffer, 0, length);
}
sr.Close();
}
else
{
contextResponse.WriteFile(fi.FullName);
}
这里的结果是只生成了一次Excel并在服务器保留,以后每次下载的时候都使用带"Export"的参数下载相同的文件。那么如果需要文件只是一次性的,每次下载都需要重新生成,则只需要把Export页面的下载和生成放到一起。然后把开头的Response.Write方法最后变成:
复制代码 代码如下:
contextResponse.Flush();
fi.Delete();
contextResponse.End();
即每次响应清空后把文件先删除,再结束响应。这样就解决了利用下载工具出现的下载不能的问题,同时保护了服务器文件地址的隐私,并可以采用分段写入的方法写入大文件,而且可以按需要即时删除生成的文件而不占用服务器空间。
您可能感兴趣的文章: