แม้ว่าผลการดำเนินการมาตรฐาน 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());
}
}
}
}
}
ใน Controller ใช้ผลลัพธ์การดำเนินการ 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 ให้สร้าง View ว่างโดยไม่มีโมเดลและเลย์เอาท์เปล่า
โพสต์บล็อกเกี่ยวกับผลการดำเนินการที่กำหนดเองสำหรับการดาวน์โหลดไฟล์ที่สร้างขึ้นทันที:
https://acanozturk.blogspot.com/2019/03/custom-actionresult-for-files-in-aspnet.html