15

当我尝试使用 EPPlus 生成 Excel 文件时,Excel 给我以下错误消息:

Excel 无法打开文件“myfilename.xlsx”,因为文件格式或文件扩展名无效。验证文件没有损坏并且文件扩展名与文件格式匹配。

这是我的代码:

public ActionResult Index()
{
    using (ExcelPackage package = new ExcelPackage())
    {
        // I populate the worksheet here.  I'm 90% sure this is fine
        // because the stream file size changes based on what I pass to it.

        var stream = new MemoryStream();
        package.SaveAs(stream);

        string fileName = "myfilename.xlsx";
        string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

        var cd = new System.Net.Mime.ContentDisposition
        {
            Inline = false,
            FileName = fileName
        };
        Response.AppendHeader("Content-Disposition", cd.ToString());
        return File(stream, contentType, fileName);
    }
}

知道我做错了什么吗?

4

3 回答 3

31

您需要做的就是重置流位置。stream.Position = 0;

不应该直接写入 Response,这不是 MVC 方式。它没有遵循正确的 MVC 管道,并且将控制器操作代码与 Response 对象紧密耦合。

当您在 中添加文件名作为第三个参数时File(),MVC 会自动添加正确的Content-Disposition标题...因此您不需要手动添加它。

简而言之,这就是你想要的:

public ActionResult Index()
{
    using (ExcelPackage package = new ExcelPackage())
    {
        // I populate the worksheet here.  I'm 90% sure this is fine
        // because the stream file size changes based on what I pass to it.

        var stream = new MemoryStream();
        package.SaveAs(stream);

        string fileName = "myfilename.xlsx";
        string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

        stream.Position = 0;
        return File(stream, contentType, fileName);
    }
}
于 2012-09-03T18:57:20.537 回答
10

您的代码没有显示stream被写入HttpResponse- 大概是在File您尚未发布的方法中完成的。

一种可行的方法如下:

Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader(
            "content-disposition", String.Format(CultureInfo.InvariantCulture, "attachment; filename={0}", fileName));
Response.BinaryWrite(package.GetAsByteArray());
Response.End();
于 2012-03-07T20:37:31.520 回答
2

与乔的回答类似,我仍然不得不打电话Response.ClearHeaders()

   protected void btnDownload_Click(object sender, EventArgs e)
   {

       ExcelPackage pck = new ExcelPackage();
       var ws = pck.Workbook.Worksheets.Add("Sample2");

       ws.Cells["A1"].Value = "Sample 2";
       ws.Cells["A1"].Style.Font.Bold = true;
       var shape = ws.Drawings.AddShape("Shape1", eShapeStyle.Rect);
       shape.SetPosition(50, 200);
       shape.SetSize(200, 100);
       shape.Text = "Sample 2 outputs the sheet using the Response.BinaryWrite method";
       Response.Clear();    
       Response.ClearHeaders();
       Response.BinaryWrite(pck.GetAsByteArray());
       Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
       Response.AddHeader("content-disposition", "attachment;  filename=Sample2.xlsx");
       Response.End();
  }
于 2014-02-11T07:55:52.967 回答