.NET Core 3.1通过HttpContext发送EPPlus Excel文件报错如何解决
解决方案
错误根因
SendFileAsync 方法仅支持传入物理文件路径或 Microsoft.Extensions.FileProviders.IFileInfo 类型参数,你传入的 OfficeOpenXml.ExcelPackage 是内存中的Excel对象,没有对应磁盘文件自然无法转换为IFileInfo。你不需要将生成的Excel落盘到服务器,直接输出内存二进制流即可完成下载。
方案1:修改现有操作HttpContext的代码
// 方法返回值改为async Task避免异步同步混用导致的异常 public async Task Export(ProductionLine productionLine, HttpContext context) { using (var package = new ExcelPackage()) { var ws = package.Workbook.Worksheets.Add("MySheet"); ws.Cells["A1"].Value = "This is cell A1"; // 文件名做URL编码,避免中文/特殊字符乱码 var fileName = Uri.EscapeDataString("MySheet.xlsx"); context.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; context.Response.Headers.Add("Content-Disposition", $"attachment; filename={fileName}"); // 将Excel对象转为字节数组后写入响应体 var fileBytes = package.GetAsByteArray(); await context.Response.Body.WriteAsync(fileBytes, 0, fileBytes.Length); } }
方案2:控制器直接返回FileResult(更推荐)
如果你是在控制器动作中调用导出逻辑,不需要手动操作HttpContext,直接返回ASP.NET Core封装的File结果即可,代码更简洁不易出错:
public IActionResult Export(ProductionLine productionLine) { using (var package = new ExcelPackage()) { var ws = package.Workbook.Worksheets.Add("MySheet"); ws.Cells["A1"].Value = "This is cell A1"; var fileBytes = package.GetAsByteArray(); var fileName = Uri.EscapeDataString("MySheet.xlsx"); return File(fileBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName); } }
注意事项
- 如果你使用的是EPPlus 5及以上版本,需注意其商用授权规则,非开源项目使用需要申请商业授权,可降级到EPPlus 4.x版本(MIT协议支持免费商用)
- 导出大文件时不建议一次性转为字节数组,可直接用
package.SaveAs(context.Response.Body)的方式将流写入响应,避免内存溢出
内容的提问来源于stack exchange,提问作者Wouter-J
相关产品推荐
相关产品推荐

