Bir AJAX çağrısı aracılığıyla bir dosyayı indirmek için doğrudan geri döndüremezsiniz, bu nedenle alternatif bir yaklaşım, ilgili verileri sunucunuza göndermek için bir AJAX çağrısı kullanmaktır. Daha sonra Excel Dosyasını oluşturmak için sunucu tarafı kodunu kullanabilirsiniz (bu bölüm çalışıyormuş gibi görünse de bunun için EPPlus veya NPOI kullanmanızı tavsiye ederim).
GÜNCEL Eylül 2016
Orijinal cevabım (aşağıda) 3 yaşın üzerindeydi, bu yüzden AJAX aracılığıyla dosya indirirken artık sunucuda dosya oluşturmadığım için güncelleme yapacağımı düşündüm, ancak yine de bağlı olarak hala biraz işe yarayabileceği için orijinal cevabı bıraktım. özel gereksinimleriniz.
MVC uygulamalarımdaki yaygın bir senaryo, kullanıcı tarafından yapılandırılmış bazı rapor parametrelerine (Tarih Aralıkları, Filtreler vb.) Sahip bir web sayfası aracılığıyla raporlama yapmaktır. Kullanıcı sunucuya gönderdiği parametreleri belirlediğinde, rapor üretilir (örneğin çıktı olarak bir Excel dosyası) ve ardından elde edilen dosyayı, TempData
benzersiz bir referansla birlikte bir bayt dizisi olarak depolar . Bu referans, daha sonra verileri TempData
son kullanıcı tarayıcısından çıkarmak ve bu tarayıcıya indirmek için ayrı denetleyici eylemine yönlendiren AJAX işlevime bir Json Sonucu olarak geri aktarılır .
Bunu daha fazla ayrıntı vermek için, Model sınıfına bağlı bir forma sahip bir MVC Görünümünüz olduğunu varsayarak Modeli çağıralım ReportVM
.
İlk olarak, yayınlanan modeli almak için bir kontrolör eylemi gereklidir, bir örnek şöyle olabilir:
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" }
};
}
MVC formumu yukarıdaki denetleyiciye gönderen ve yanıtı alan AJAX çağrısı şu şekilde görünür:
$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;
}
})
Dosyanın indirilmesini işlemek için denetleyici işlemi:
[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();
}
}
Gerekirse kolayca gerçekleştirilebilecek diğer bir değişiklik, dosyanın MIME Türünü üçüncü bir parametre olarak geçirmektir, böylece bir Denetleyici eylemi çeşitli çıktı dosyası biçimlerine doğru şekilde hizmet edebilir.
Bu, herhangi bir fiziksel dosyanın sunucuda oluşturulması ve depolanması ihtiyacını ortadan kaldırır, böylece temizlik rutinleri gerekmez ve bir kez daha bu son kullanıcı için sorunsuzdur.
Not kullanmanın avantajı TempData
ziyade Session
bir kez olmasıdır TempData
dosya istekleri yüksek hacimli varsa bellek kullanımı açısından daha verimli olacak, böylece veriler temizlenir okunur. TempData En İyi Uygulamasına bakın .
ORİJİNAL Cevap
Bir AJAX çağrısı aracılığıyla bir dosyayı indirmek için doğrudan geri döndüremezsiniz, bu nedenle alternatif bir yaklaşım, ilgili verileri sunucunuza göndermek için bir AJAX çağrısı kullanmaktır. Daha sonra Excel Dosyasını oluşturmak için sunucu tarafı kodunu kullanabilirsiniz (bu bölüm çalışıyormuş gibi görünse de bunun için EPPlus veya NPOI kullanmanızı tavsiye ederim).
Dosya sunucuda oluşturulduktan sonra, AJAX çağrınızın dönüş değeri olarak dosyanın yolunu (veya yalnızca dosya window.location
adını ) geri verin ve ardından JavaScript'i , tarayıcıdan dosyayı indirmesini isteyecek olan bu URL'ye ayarlayın .
Son kullanıcılar açısından bakıldığında, dosya indirme işlemi, talebin kaynaklandığı sayfadan asla ayrılmadıkları için sorunsuzdur.
Aşağıda, bunu başarmak için bir ajax çağrısının basit bir uydurma örneği bulunmaktadır:
$.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;
}
});
- url parametresi, kodunuzun Excel dosyasını oluşturacağı Denetleyici / İşlem yöntemidir.
- data parametresi, formdan çıkarılacak json verilerini içerir.
- returnValue , yeni oluşturulan Excel dosyanızın dosya adı olacaktır.
- Window.location aslında indirmek için dosyanızı döndüren Kontrolör / Aksiyon yöntemine komut yönlendirmeler.
İndirme eylemi için örnek bir denetleyici yöntemi şöyle olacaktır:
[HttpGet]
public virtual ActionResult Download(string file)
{
string fullPath = Path.Combine(Server.MapPath("~/MyFiles"), file);
return File(fullPath, "application/vnd.ms-excel", file);
}