首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从静态方法调用Response.TransmitFile()

从静态方法调用Response.TransmitFile()
EN

Stack Overflow用户
提问于 2010-02-17 03:59:43
回答 5查看 7.4K关注 0票数 3

我有一些页面,需要支持导出数据到Excel电子表格。我可以很好地生成Excel文件,但我正在努力解决如何抽象此行为,以便在需要它的所有页面中轻松重用它。我目前的想法是使用静态实用程序方法,如下所示:

代码语言:javascript
复制
public static void SendExcelFile(System.Web.UI.Page callingPage, string downloadFileName, List<List<string>> data, string worksheetTitle)
{
    string tempFileName = Path.GetTempFileName();

    try
    {
        // Generate file using ExcelPackage
        GenerateExcelDoc(tempFileName, data, worksheetTitle);

        callingPage.Response.AddHeader("Content-Disposition", "attachment;filename=" + downloadFileName);
        callingPage.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        callingPage.Response.AddHeader("Content-Length", new FileInfo(tempFileName).Length.ToString());
        callingPage.Response.TransmitFile(tempFileName);
    }
    finally
    {
        //When this is removed, the method works as expected.
        if (File.Exists(tempFileName))
            File.Delete(tempFileName);  
    }
}

我调用SendExcelFile的点击处理程序如下所示:

代码语言:javascript
复制
protected void lnkExport_Click(object sender, EventArgs e)
{
    List<List<string>> dataList = GatherDataForSpreadsheet();
    Utility.SendExcelFile(this, "fileNameForDownload.xlsx", dataList, "MyReports");
}

这段代码作为调用页面的实例方法工作得很好。然而,作为一种静态方法,它根本不起作用。当我点击这个按钮时,浏览器会无限期地显示加载动画,但不会提示下载文件。

我对ASP.NET (和一般的web编程)非常陌生,所以我确信我在这里遗漏了一些东西。有没有人能解释一下我看到的行为,并提出一个合理的替代方法?

编辑:如果我在最后删除了对File.Delete()的调用,该方法将按预期工作。Response.TransmitFile()是否以异步方式进行传输?

编辑2:在删除文件之前,我只需要调用Response.Flush()。请看我下面的回答。谢谢!

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-02-17 05:28:45

问题是临时文件在发送数据之前就被删除了。我只需要像这样调用Response.Flush():

代码语言:javascript
复制
public static void SendExcelFile(System.Web.UI.Page callingPage, string downloadFileName, List<List<string>> data, string worksheetTitle)
{
    string tempFileName = Path.GetTempFileName();

    try
    {
        // Generate file using ExcelPackage
        GenerateExcelDoc(tempFileName, data, worksheetTitle);

        callingPage.Response.AddHeader("Content-Disposition", "attachment;filename=" + downloadFileName);
        callingPage.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        callingPage.Response.AddHeader("Content-Length", new FileInfo(tempFileName).Length.ToString());
        callingPage.Response.TransmitFile(tempFileName);
        callingPage.Response.Flush();  //This is what I needed
    }
    finally
    {
        if (File.Exists(tempFileName))
            File.Delete(tempFileName);  
    }
}
票数 5
EN

Stack Overflow用户

发布于 2010-02-17 04:05:33

试试这个,你可以直接从HttpContext.Current上得到RequestResponse

代码语言:javascript
复制
public static void SendExcelFile(string downloadFileName, List<List<string>> data, string worksheetTitle)
{
    var context = HttpContext.Current;
    string tempFolder = context.Request.PhysicalApplicationPath + "temp";
    string tempFileName = tempFolder + "tempFileName.xlsx"

    if (!Directory.Exists(tempFolder))
        Directory.CreateDirectory(tempFolder);

    // Generate file using ExcelPackage
    GenerateExcelDoc(tempFileName, data, worksheetTitle);

    context.Response.AddHeader("Content-Disposition", "attachment;filename=" + downloadFileName);
    context.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    context.Response.AddHeader("Content-Length", new FileInfo(tempFileName).Length.ToString());
    context.Response.TransmitFile(tempFileName);

    File.Delete(tempFileName);
}

另一种选择是为包含此方法的页面创建一个基类,这可能是一种更容易的方法。您的页面不必继承System.Web.UI.Page,它们可以继承其他内容,如下所示:

代码语言:javascript
复制
public class BasePage : System.Web.UI.Page
{
    public void SendExcelFile(string downloadFileName, List<List<string>> data, string worksheetTitle)
    {
        string tempFolder =Request.PhysicalApplicationPath + "temp";
        string tempFileName = tempFolder + "tempFileName.xlsx"

        if (!Directory.Exists(tempFolder))
            Directory.CreateDirectory(tempFolder);

        // Generate file using ExcelPackage
        GenerateExcelDoc(tempFileName, data, worksheetTitle);

       Response.AddHeader("Content-Disposition", "attachment;filename=" + downloadFileName);
       Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
       Response.AddHeader("Content-Length", new FileInfo(tempFileName).Length.ToString());
       Response.TransmitFile(tempFileName);

        File.Delete(tempFileName);
    }
}

然后在你的页面中,这个类看起来像这样:

代码语言:javascript
复制
public partial class MyPage : BasePage
{
  //Stuff!
}
票数 1
EN

Stack Overflow用户

发布于 2010-02-17 04:53:24

我们需要更多的信息--你所做的应该是可行的。

我创建了一个精简版本,它只是将调用页面的副本发送到客户端,它可以按预期工作:

代码语言:javascript
复制
public class Utility {
    // This just sends the client a copy of the calling page itself
    public static void SendExcelFile(Page callingPage) {
        string path = callingPage.Request.PhysicalPath;
        callingPage.Response.AddHeader("Content-Disposition", "attachment;filename=test.xls");
        callingPage.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        callingPage.Response.AddHeader("Content-Length", new FileInfo(path).Length.ToString());
        callingPage.Response.TransmitFile(path);
    }
}

这是我的呼叫页面:

代码语言:javascript
复制
public partial class main : System.Web.UI.Page {
    protected void SendButton_Click(object sender, EventArgs e) {        
        Utility.SendExcelFile(this);
    }
}

您是否看到与您的实现有什么不同?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2275894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档