Хоча стандартні результати дій FileContentResult або FileStreamResult можуть використовуватися для завантаження файлів для їх повторного використання, створення найкращого результату дій може бути найкращим рішенням.
Як приклад, давайте створимо користувальницький результат дії для експорту даних у файли Excel на ходу для завантаження.
Клас ExcelResult успадковує абстрактний клас ActionResult і замінює метод ExecuteResult.
Ми використовуємо пакет FastMember для створення DataTable з об'єкта IEnumerable та пакет ClosedXML для створення файлу Excel з 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());
}
}
}
}
}
У контролері використовуйте спеціальний результат дії ExcelResult наступним чином
[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);
}
Оскільки ми завантажуємо файл за допомогою HttpGet, створимо порожній перегляд без моделі та порожнього макета.
Повідомлення в блозі про користувацький результат дії для завантаження файлів, створених на ходу:
https://acanozturk.blogspot.com/2019/03/custom-actionresult-for-files-in-aspnet.html