Để download file mà không sử dụng thẻ Form, ta có các cách sau:
- Tạo thẻ Form giả và gọi submit form
- Sử dụng thư viện JS để hỗ trợ download byte array data
- Convert Byte Array data sang base 64 và gởi trả về phía client.
Trong bài viết này, mình sẽ sử dụng cách 3.
Các bước gồm có:
- End user dùng Ajax gọi download file
- Hệ thống render ra file data với kiểu dữ liệu Byte Array
- Convert Byte array sang base 64. base64 là phương thức convert dạng mã hóa 2 chiều từ binary sang string để có thể gửi đi được trong network một cách dễ dàng
- Sau khi gọi Ajax thành công, gọi hàm _base64ToArrayBuffer() để chuyển base 64 sang dạng Byte Array
- Tạo link chứa Blob object. Tạo thẻ <a> để thực hiện việc download file.
(Binary Large Object (BLOB) là Object lớn nhị phân (BLOB) - Remove thẻ <a> sau khi download file
Ví dụ
Giả sử bạn tạo file excel. Ở đây mình sử dụng thư viện Epplus
Tạo file excelusing OfficeOpenXml;
using System.Drawing;
namespace Nhatkyhoctap.Implement
{
public class ClassService : IClassService
{
//some code lines are hidden...
public async Task<byte[]> ExportFileAsync(int semester)
{
// If you use EPPlus in a noncommercial context
// according to the Polyform Noncommercial license:
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
var memoryStream = new MemoryStream();
using (var package = new ExcelPackage())
{
//Add a new worksheet to the empty workbook
var worksheet = package.Workbook.Worksheets.Add("Inventory");
//Add the headers
worksheet.Cells[1, 1].Value = "ID";
worksheet.Cells[1, 2].Value = "Product";
worksheet.Cells[1, 3].Value = "Quantity";
worksheet.Cells[1, 4].Value = "Price";
worksheet.Cells[1, 5].Value = "Value";
await package.SaveAsAsync(memoryStream);
}
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream.ToArray();
}
}
}
Controller
[HttpPost]
public async Task<JsonResult> ExportData(int id)
{
var fileByteArray = await _classService.ExportFileAsync(id);
string fileName = $"Nhatkyhoctap_{DateTime.Now.ToShortDateString()}.xlsx";
return Json(new { filename = fileName, message = Convert.ToBase64String(fileByteArray) });
}
View
function _base64ToArrayBuffer(base64) {
var binary_string = window.atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
}
function saveByteArray(reportName, byte) {
var blob = new Blob([byte], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
var isIE = false || !!document.documentMode;
if (isIE) {
window.navigator.msSaveBlob(blob, reportName);
} else {
var url = window.URL || window.webkitURL;
link = url.createObjectURL(blob);
var a = $("<a />");
a.attr("download", reportName);
a.attr("href", link);
$("body").append(a);
a[0].click();
$("body").remove(a);
}
};
function downloadTimeTable(id) {
$.ajax({
url: "@Url.Content("~/Export/ExportData/")" + id,
method: 'POST'
}).done(function (data, jqXHR, response) {
if (jqXHR == "success") {
var bytes = _base64ToArrayBuffer(data.message);
saveByteArray(data.filename, bytes);
}
});
}
Chúc các bạn thành công!
Nhận xét
Đăng nhận xét