asp.net下载文件
下载文件问题(弹出多余空白页面)
最近在项目中经常用到模态窗口(showModalDialog),客户需要在一个模态窗口中有”生成Excel报表”并”导出”的功能。接到任务后,直接就开始按常规操作实现。
在按钮的Click事件中,根据模板生成Excel报表,填充数据,保存到临时文件夹,然后用Response.WriteFile函数输出文件,一切看上去都很顺利。代码如下:
//根据数据集创建Excel报表并返回Excel报表路径
string fileName = CreateExcel(ds);
Response.Clear();
Response.Charset = “utf-8”;
Response.Buffer = true;
this.EnableViewState = false;
Response.ContentEncoding = System.Text.Encoding.UTF8;
Response.AppendHeader(“Content-Disposition”, “attachment;filename=” + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
//设置输出文件类型为excel文件。
Response.ContentType = “application/ms-excel”;
Response.WriteFile(fileName);
Response.Flush();
Response.Close();
Response.End();
//根据数据集创建Excel报表并返回Excel报表路径 string fileName = CreateExcel(ds); Response.Clear(); Response.Charset = "utf-8"; Response.Buffer = true; this.EnableViewState = false; Response.ContentEncoding = System.Text.Encoding.UTF8; Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8)); //设置输出文件类型为excel文件。 Response.ContentType = "application/ms-excel"; Response.WriteFile(fileName); Response.Flush(); Response.Close(); Response.End();
但是当完成了代码,开始测试的时候,却发现点击”导出”按钮没有反应。开始的时候以为是创建Excel报表的代码有问题,但经过调试后,证实创建Excel代码没有问题,也成功的在临时文件夹下生成了Excel报表,但是却没有”导出”报表(没弹出下载文件对话框)。再看输出文件的代码,应该也没有问题,之前一直这样输出都没有问题的。
在百思不得其解的时候,发现了一个关键点。就是之前输出文件成功的面页都是一般的网页窗口,而这次的操作却是在模态窗口中。问题会不会出在这里呢?赶紧试验了一下。把模态窗口改成了一般的网页窗口,果然可以输出文件没问题,也成功下载了报表。
虽然问题有点怪异,但找到了切入点和问题的关键所在,解决应该就不难了。google一下,发现模态窗口定义了<base
target=”_self”>,这应该是问题所在。然后在页面中重新定义了这个标签,改成了<base
target=”_blank”>,问题成功解决,文件可以正常下载了。但这时候又来了新的问题,下载是可以了,但是却会弹出一个新页面,在模态窗口中下载再弹出页面肯定影响了用户体验。有没有方法在模态窗口中直接下载而不弹出新的页面呢?既然target=_self的时候有问题,target=_blank的时候又会弹出新的页面,这让我想到了在框架中打开新窗口的做法。在页面中加一个看不到的框架,然后把target设为框架名应该可以解决。随后在页面中再加了一个大小为0的iframe
<iframe id=”download” name=”download” height=”0px”
width=”0px”></iframe><!–用iframe模拟文件下载–>
然后重新修改<base>标签target为框架名:
<base
target=”download”>
重新生成,浏览,测试。问题成功解决。
完整添加代码为:
aspx内
1.在head内添加base
<head runat=”server”>
<base target=”download” />
</head>
2.在body内添加iframe
<body>
<form id=”form1″ runat=”server”>
<iframe id=”download” name=”download” height=”0px” width=”0px”></iframe>
<asp:Button ID=”ButtonSaveAnnex” runat=”server” Text=”下载附件” OnClick=”ButtonSaveAnnex_Click” />
<div/>
</form>
</body>
cs内
1.添加按钮事件响应
protected void ButtonSaveAnnex_Click(object sender, EventArgs e)
{
if (Session[“SESSION_ANNEX_NAME”] != null)
{
string strName = Session[“SESSION_ANNEX_NAME”].ToString();
if (strName != null && strName.Length > 0)
{
string strSavePath = Server.MapPath(“../”);
strSavePath += “upLoadNotice\\”;
strSavePath += strName;
FileDownload(strSavePath);
}
}
}
2.添加下载实现
/// <summary>
/// 下载文件
/// </summary>
/// <param name=”FileName”>下载文件对应服务器硬盘完整路径</param>
public void FileDownload(string FileName)
{
FileInfo DownloadFile = new FileInfo(FileName);
if (DownloadFile.Exists)
{
FileStream stream = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
try
{
Response.Charset = “GB2312”;
Response.ContentEncoding = System.Text.Encoding.GetEncoding(“GB2312”);
Response.ContentType = “application/txt”;
Response.AppendHeader(“Content-Disposition”, “attachment;filename=” + System.Web.HttpUtility.UrlEncode(DownloadFile.Name));
int bufSize = (int)stream.Length;
byte[] buf = new byte[bufSize];
int bytesRead = stream.Read(buf, 0, bufSize);
stream.Close();
Response.OutputStream.Write(buf, 0, bytesRead);
Response.End();
}
catch (IOException)
{
stream.Close();
}
}
}