Aunque los resultados de la acción estándar FileContentResult o FileStreamResult se pueden utilizar para descargar archivos, la mejor solución podría ser crear un resultado de acción personalizado para su reutilización.
Como ejemplo, creemos un resultado de acción personalizado para exportar datos a archivos de Excel sobre la marcha para su descarga.
La clase ExcelResult hereda la clase ActionResult abstracta y anula el método ExecuteResult.
Estamos usando el paquete FastMember para crear DataTable a partir del objeto IEnumerable y el paquete ClosedXML para crear un archivo de Excel a partir de 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());
}
}
}
}
}
En el controlador, use el resultado personalizado de la acción ExcelResult de la siguiente manera
[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);
}
Dado que estamos descargando el archivo usando HttpGet, cree una Vista vacía sin modelo y diseño vacío.
Publicación de blog sobre el resultado de una acción personalizada para descargar archivos que se crean sobre la marcha:
https://acanozturk.blogspot.com/2019/03/custom-actionresult-for-files-in-aspnet.html