C# HttpGet 响应给了我一个带有 EPPlus 的空 Excel 文件

Posted

技术标签:

【中文标题】C# HttpGet 响应给了我一个带有 EPPlus 的空 Excel 文件【英文标题】:C# HttpGet response gives me an empty Excel file with EPPlus 【发布时间】:2017-03-13 21:57:48 【问题描述】:

我创建了一个生成 Excel 文件的端点。它应该起到 GET 的作用,以防我想要一些其他代码将其发布到不同的端点以发送电子邮件,或者如果我想通过在浏览器中手动点击端点来下载 Excel 文件。它正在下载 Excel 文件,但是当我尝试打开它时,我看到消息“Excel 无法打开文件 'blahblah',因为文件格式或文件扩展名无效。验证文件没有损坏并且文件扩展名匹配文件的格式。”

收到该错误后,我尝试更改响应内容字段和/或文件扩展名中的 MIME 类型,错误消失,文件打开并显示以下警告:“文件格式和扩展名”等等废话”不匹配。文件可能已损坏或不安全。除非您信任其来源,否则不要打开它。您仍然要打开它吗?”如果我还是打开它,文件仍然是空的。

这是我将创建的 ExcelPackage 添加到响应中的代码。

var response = HttpContext.Current.Response;
response.ContentType = "application/vnd.openxmlformats-  officedocument.spreadsheetml.sheet";
var fileName = string.Format("blahblah-0.xls",     InstantPattern.CreateWithInvariantCulture("yyyy-dd-M-HH-mm-ss").Format(_clock.Now));
response.AddHeader("content-disposition", string.Format("attachment; filename=0", fileName));
response.BinaryWrite(excelPackage.GetAsByteArray());

我尝试添加不同的 mime 类型,例如 application/excel。我尝试使用 .xlsx 文件扩展名而不是 xls。什么都没有真正奏效。不过,我知道 ExcelPackage 工作簿的工作表实际上有我想要的数据,因为当我调试并将鼠标悬停在对象上时,我会看到我希望将其放入文件中的单元格值。那么我做错了什么?

我已尝试以两种方式生成 excelPackage,都在 using 块内。像这样:

using (var excelPackage = new ExcelPackage())

    // generate and download excel file

还有这样的:

using (var excelPackage = new ExcelPackage(new FileInfo(fileName)))

   // generate and download excel file

【问题讨论】:

mime 类型只是告诉浏览器要使用哪个应用程序,因此如果在您执行 Get 时浏览器正在打开 Excel,则您的 Mime 类型是正确的。如果您随后收到 Excel 错误,那是因为传递的任何字节都不是预期的格式。你是如何生成 excelPackage 的?这很可能是问题所在。 @Theo 我尝试使用默认构造函数(无参数)和 FileInfo 构造函数生成 ExcelPackage,传入相同的文件名。我目前正在一个 using 块中执行所有这些代码,我将在原始问题中进行编辑。 在您将字节写入响应内容后,控制器操作中的其他内容可能正在修改您的响应内容。写入字节后尝试添加response.End @Theo 当我这样做时,下载显示“失败 - 网络错误”并且它没有完成。我的控制器操作返回一个 Task,所以我在生成 excel 文件后返回 Ok()。 如果我将 excelPackage 保存为本地文件,我可以毫无问题地打开它。它里面有预期的内容。只有当我尝试将它添加到我收到错误的响应时。 【参考方案1】:

我用它把 Excel 文件发送到浏览器。

HttpResponse Response = HttpContext.Current.Response;

//first convert to byte array
byte[] bin = excelPackage.GetAsByteArray();

//clear the buffer stream
Response.ClearHeaders();
Response.Clear();
Response.Buffer = true;

//add the content type
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

//set the content length, without it, length is set to -1 and could give errors
Response.AddHeader("content-length", bin.Length.ToString());

//add a filename
Response.AddHeader("content-disposition", "attachment; filename=\"" + fileName + ".xlsx\"");

//send the file to the browser
Response.OutputStream.Write(bin, 0, bin.Length);

//cleanup
Response.Flush();
HttpContext.Current.ApplicationInstance.CompleteRequest();

【讨论】:

谢谢!这确实有效!我认为我在接下来看到的其他示例缺少内容长度和输出流部分。

以上是关于C# HttpGet 响应给了我一个带有 EPPlus 的空 Excel 文件的主要内容,如果未能解决你的问题,请参考以下文章

带有选项的 python 和 ngrok 给了我一个错误

web api c#为带有角度的long数据类型返回另一个值

我尝试使用 passport.js 对用户进行身份验证,但它给了我一个错误**服务器响应状态为 400(错误请求)**

带有分页的 Spring Data JPA 方法查询给了我一个错误

带有 MySql 冲突的 Docker 映像在启动时给了我一个异常

使用 ajax 返回 JSON 给了我带有返回参数的空白页