Anda tidak dapat langsung mengembalikan file untuk diunduh melalui panggilan AJAX, jadi pendekatan alternatifnya adalah menggunakan panggilan AJAX untuk memposting data terkait ke server Anda. Anda kemudian dapat menggunakan kode sisi server untuk membuat File Excel (Saya akan merekomendasikan menggunakan EPPlus atau NPOI untuk ini meskipun kedengarannya seolah-olah Anda memiliki bagian ini berfungsi).
UPDATE September 2016
Jawaban asli saya (di bawah) berusia lebih dari 3 tahun, jadi saya pikir saya akan memperbarui karena saya tidak lagi membuat file di server saat mengunduh file melalui AJAX namun, saya telah meninggalkan jawaban asli karena mungkin ada gunanya masih tergantung pada kebutuhan spesifik Anda.
Skenario umum dalam aplikasi MVC saya melaporkan melalui halaman web yang memiliki beberapa parameter laporan yang dikonfigurasi pengguna (Rentang Tanggal, Filter, dll.). Ketika pengguna telah menentukan parameter yang mereka posting ke server, laporan dibuat (katakanlah misalnya file Excel sebagai output) dan kemudian saya menyimpan file yang dihasilkan sebagai array byte dalam TempData
keranjang dengan referensi unik. Referensi ini dikirimkan kembali sebagai Hasil Json ke fungsi AJAX saya yang kemudian dialihkan ke tindakan pengontrol terpisah untuk mengekstrak data dari TempData
dan mengunduh ke browser pengguna akhir.
Untuk memberikan detail lebih lanjut, dengan asumsi Anda memiliki Tampilan MVC yang memiliki formulir yang terikat ke kelas Model, mari panggil Model ReportVM
.
Pertama, tindakan pengontrol diperlukan untuk menerima model yang diposting, contohnya adalah:
public ActionResult PostReportPartial(ReportVM model){
ExcelPackage workbook = new ExcelPackage();
string handle = Guid.NewGuid().ToString();
using(MemoryStream memoryStream = new MemoryStream()){
workbook.SaveAs(memoryStream);
memoryStream.Position = 0;
TempData[handle] = memoryStream.ToArray();
}
return new JsonResult() {
Data = new { FileGuid = handle, FileName = "TestReportOutput.xlsx" }
};
}
Panggilan AJAX yang memposting formulir MVC saya ke pengontrol di atas dan menerima respons terlihat seperti ini:
$ajax({
cache: false,
url: '/Report/PostReportPartial',
data: _form.serialize(),
success: function (data){
var response = JSON.parse(data);
window.location = '/Report/Download?fileGuid=' + response.FileGuid
+ '&filename=' + response.FileName;
}
})
Tindakan pengontrol untuk menangani pengunduhan file:
[HttpGet]
public virtual ActionResult Download(string fileGuid, string fileName)
{
if(TempData[fileGuid] != null){
byte[] data = TempData[fileGuid] as byte[];
return File(data, "application/vnd.ms-excel", fileName);
}
else{
return new EmptyResult();
}
}
Satu perubahan lain yang dapat dengan mudah diakomodasi jika diperlukan adalah meneruskan Jenis MIME file sebagai parameter ketiga sehingga satu tindakan Pengontrol dapat menyajikan berbagai format file keluaran dengan benar.
Ini menghilangkan semua kebutuhan file fisik untuk dibuat dan disimpan di server, jadi tidak ada rutinitas rumah tangga yang diperlukan dan sekali lagi ini mulus bagi pengguna akhir.
Perhatikan, keuntungan menggunakan TempData
daripada Session
sekali TempData
dibaca, data dihapus sehingga akan lebih efisien dalam hal penggunaan memori jika Anda memiliki volume permintaan file yang tinggi. Lihat Praktik Terbaik TempData .
Jawaban ASLI
Anda tidak dapat langsung mengembalikan file untuk diunduh melalui panggilan AJAX, jadi pendekatan alternatifnya adalah menggunakan panggilan AJAX untuk memposting data terkait ke server Anda. Anda kemudian dapat menggunakan kode sisi server untuk membuat File Excel (Saya akan merekomendasikan menggunakan EPPlus atau NPOI untuk ini meskipun kedengarannya seolah-olah Anda memiliki bagian ini berfungsi).
Setelah file dibuat di server, kembalikan path ke file (atau hanya nama file) sebagai nilai kembali ke panggilan AJAX Anda dan kemudian atur JavaScript window.location
ke URL ini yang akan meminta browser untuk mendownload file.
Dari perspektif pengguna akhir, operasi pengunduhan file berjalan mulus karena mereka tidak pernah meninggalkan halaman tempat permintaan berasal.
Di bawah ini adalah contoh panggilan ajax yang dibuat sederhana untuk mencapai ini:
$.ajax({
type: 'POST',
url: '/Reports/ExportMyData',
data: '{ "dataprop1": "test", "dataprop2" : "test2" }',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (returnValue) {
window.location = '/Reports/Download?file=' + returnValue;
}
});
- Parameter url adalah metode Pengontrol / Tindakan di mana kode Anda akan membuat file Excel.
- parameter data berisi data json yang akan diekstrak dari formulir.
- returnValue akan menjadi nama file dari file Excel yang baru Anda buat.
- The window.location perintah pengalihan dengan metode Controller / Action yang benar-benar mengembalikan file Anda untuk di-download.
Metode pengontrol sampel untuk tindakan Download adalah:
[HttpGet]
public virtual ActionResult Download(string file)
{
string fullPath = Path.Combine(Server.MapPath("~/MyFiles"), file);
return File(fullPath, "application/vnd.ms-excel", file);
}