如何下载文件
如何下载文件
我一直在关注下面列出的所有链接,并找到了编写这个小型创建Excel和下载函数的最佳方法(使用EPPlus处理Excel)。
它每次运行时都能完美地通过代码,没有错误,但是却没有“推出”要下载的文件(即保存为对话框或其他)。
public ActionResult ShowReport() { using (var stream = new MemoryStream()) { ExcelPackage pck = new ExcelPackage(); var ws = pck.Workbook.Worksheets.Add("Sample1"); ws.Cells["A1"].Value = "Sample 1"; 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 1 text text text"; var fileDownloadName = "sample.xlsx"; var contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; var fileStream = new MemoryStream(); pck.SaveAs(fileStream); fileStream.Position = 0; var fsr = new FileStreamResult(fileStream, contentType); fsr.FileDownloadName = fileDownloadName; byte[] fileBytes = ReadToEnd(fileStream); string fileName = "example"; return File(fileBytes, contentType, fileName); } }
我做错了什么/漏掉了什么?-我需要自己编写那个对话框吗?
PS:我还尝试了另一种方式
byte[] fileBytes = ReadToEnd(fileStream); string fileName = "example"; return File(fileBytes, contentType, fileName);
当然,我需要找出如何将Stream转换为Byte,但仍然没有显示任何内容。
Chrome网络开发工具的图片
抱歉图片很小(如果您无法看到它,请使用ctl +鼠标滚轮放大),如果您使用支持的浏览器就可以看到。
问题的原因是直接将Excel文件写入到Response对象中,这种做法会使控制器与HTTP上下文紧密耦合,导致控制器难以移植并且很难进行单元测试。
解决方法是将返回值改为ActionResult类型,在控制器操作中返回一个ActionResult对象。然后,使用MemoryStream将Excel文件保存,并将其传递给Response对象。最后,设置Response的相关属性,以便正确地下载文件。
具体的解决方法如下:
public ActionResult DownloadFile()
{
// 保存Excel Package到MemoryStream中
MemoryStream stream = new MemoryStream();
// 保存Excel Package的代码省略...
// 设置Response属性
Response.AddHeader("content-disposition", "attachment;filename=FILENAME.xlsx");
Response.Charset = String.Empty;
Response.ContentType = "application/ms-excel";
// 将Excel文件写入Response对象,并结束响应
Response.BinaryWrite(stream.ToArray());
Response.End();
// 返回一个空的ActionResult对象
return new EmptyResult();
}
通过以上的修改,我们将控制器与HTTP上下文解耦,使得控制器更易于移植和进行单元测试。