Mặc dù kết quả hành động tiêu chuẩn FileContentResult hoặc FileStreamResult có thể được sử dụng để tải xuống tệp, để có thể sử dụng lại, tạo kết quả hành động tùy chỉnh có thể là giải pháp tốt nhất.
Ví dụ, hãy tạo một kết quả hành động tùy chỉnh để xuất dữ liệu sang tệp Excel ngay lập tức để tải xuống.
Lớp ExcelResult kế thừa lớp ActionResult trừu tượng và ghi đè phương thức ExecuteResult.
Chúng tôi đang sử dụng gói FastMember để tạo DataTable từ đối tượng IEnumerable và gói ClosedXML để tạo tệp Excel từ DataTable.
public class ExcelResult<T> : ActionResult
{
private DataTable dataTable;
private string fileName;
public ExcelResult(IEnumerable<T> data, string filename, string[] columns)
{
this.dataTable = new DataTable();
using (var reader = ObjectReader.Create(data, columns))
{
dataTable.Load(reader);
}
this.fileName = filename;
}
public override void ExecuteResult(ControllerContext context)
{
if (context != null)
{
var response = context.HttpContext.Response;
response.Clear();
response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
response.AddHeader("content-disposition", string.Format(@"attachment;filename=""{0}""", fileName));
using (XLWorkbook wb = new XLWorkbook())
{
wb.Worksheets.Add(dataTable, "Sheet1");
using (MemoryStream stream = new MemoryStream())
{
wb.SaveAs(stream);
response.BinaryWrite(stream.ToArray());
}
}
}
}
}
Trong Bộ điều khiển, sử dụng kết quả hành động ExcelResult tùy chỉnh như sau
[HttpGet]
public async Task<ExcelResult<MyViewModel>> ExportToExcel()
{
var model = new Models.MyDataModel();
var items = await model.GetItems();
string[] columns = new string[] { "Column1", "Column2", "Column3" };
string filename = "mydata.xlsx";
return new ExcelResult<MyViewModel>(items, filename, columns);
}
Vì chúng tôi đang tải xuống tệp bằng HttpGet, hãy tạo một Chế độ xem trống không có mô hình và bố cục trống.
Bài đăng trên blog về kết quả hành động tùy chỉnh để tải xuống các tệp được tạo nhanh chóng:
https://acanozturk.blogspot.com/2019/03/custom-actionresult-for-files-in-aspnet.html