asp.net下载文件

下载文件问题(弹出多余空白页面)

最近在项目中经常用到模态窗口(showModalDialog),客户需要在一个模态窗口中有"生成Excel报表"并"导出"的功能。接到任务后,直接就开始按常规操作实现。
    在按钮的Click事件中,根据模板生成Excel报表,填充数据,保存到临时文件夹,然后用Response.WriteFile函数输出文件,一切看上去都很顺利。代码如下: 

Java代码

 

//根据数据集创建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();
}
}

}

posted on 2014-04-10 13:55  carekee  阅读(594)  评论(0编辑  收藏  举报