आप सीधे एक AJAX कॉल के माध्यम से डाउनलोड के लिए एक फ़ाइल वापस नहीं कर सकते हैं, एक वैकल्पिक दृष्टिकोण अपने सर्वर से संबंधित डेटा पोस्ट करने के लिए AJAX कॉल का उपयोग करना है। फिर आप एक्सेल फाइल बनाने के लिए सर्वर साइड कोड का उपयोग कर सकते हैं (मैं इसके लिए EPPlus या NPOI का उपयोग करने की सिफारिश करूंगा, हालांकि ऐसा लगता है जैसे आपके पास यह भाग काम कर रहा है)।
अद्यतन सितंबर 2016
मेरा मूल उत्तर (नीचे) 3 साल से अधिक पुराना था, इसलिए मैंने सोचा कि मैं अपडेट करूंगा क्योंकि मैं AJAX के माध्यम से फाइल डाउनलोड करते समय सर्वर पर फाइलें नहीं बनाता हूं, हालांकि, मैंने मूल उत्तर छोड़ दिया है क्योंकि यह अभी भी कुछ उपयोग पर निर्भर हो सकता है आपकी विशिष्ट आवश्यकताएं।
मेरे एमवीसी अनुप्रयोगों में एक सामान्य परिदृश्य एक वेब पेज के माध्यम से रिपोर्टिंग कर रहा है जिसमें कुछ उपयोगकर्ता कॉन्फ़िगर किए गए रिपोर्ट पैरामीटर (दिनांक रेंज, फ़िल्टर आदि) हैं। जब उपयोगकर्ता ने उन मापदंडों को निर्दिष्ट किया है जो वे सर्वर पर पोस्ट करते हैं, तो रिपोर्ट उत्पन्न होती है (उदाहरण के लिए एक्सेल फ़ाइल को आउटपुट के रूप में कहें) और फिर मैं परिणामस्वरूप फ़ाइल को बाइट में बाइट सरणी के रूप में TempData
एक अद्वितीय संदर्भ के साथ संग्रहीत करता हूं । यह संदर्भ मेरे AJAX फ़ंक्शन के लिए एक Json परिणाम के रूप में वापस पारित किया गया है जो बाद में डेटा को निकालने TempData
और अंतिम उपयोगकर्ता ब्राउज़र पर डाउनलोड करने के लिए अलग-अलग नियंत्रक कार्रवाई को पुनर्निर्देशित करता है।
इसे और अधिक विस्तार देने के लिए, मान लें कि आपके पास एक MVC दृश्य है जो एक मॉडल वर्ग के लिए बाध्य है, जो मॉडल को कॉल करने देता है ReportVM
।
सबसे पहले, पोस्ट किए गए मॉडल को प्राप्त करने के लिए एक नियंत्रक कार्रवाई की आवश्यकता होती है, एक उदाहरण होगा:
public ActionResult PostReportPartial(ReportVM model){
// Validate the Model is correct and contains valid data
// Generate your report output based on the model parameters
// This can be an Excel, PDF, Word file - whatever you need.
// As an example lets assume we've generated an EPPlus ExcelPackage
ExcelPackage workbook = new ExcelPackage();
// Do something to populate your workbook
// Generate a new unique identifier against which the file can be stored
string handle = Guid.NewGuid().ToString();
using(MemoryStream memoryStream = new MemoryStream()){
workbook.SaveAs(memoryStream);
memoryStream.Position = 0;
TempData[handle] = memoryStream.ToArray();
}
// Note we are returning a filename as well as the handle
return new JsonResult() {
Data = new { FileGuid = handle, FileName = "TestReportOutput.xlsx" }
};
}
AJAX कॉल जो मेरे MVC फॉर्म को उपरोक्त नियंत्रक को पोस्ट करता है और प्रतिक्रिया प्राप्त करता है वह इस तरह है:
$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;
}
})
फ़ाइल को डाउनलोड करने से निपटने के लिए नियंत्रक क्रिया:
[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{
// Problem - Log the error, generate a blank file,
// redirect to another controller action - whatever fits with your application
return new EmptyResult();
}
}
एक अन्य परिवर्तन जिसे आवश्यकता पड़ने पर आसानी से समायोजित किया जा सकता है, वह है फ़ाइल के MIME प्रकार को तीसरे पैरामीटर के रूप में पास करना ताकि एक कंट्रोलर एक्शन कई प्रकार के आउटपुट फ़ाइल स्वरूपों को सही ढंग से परोस सके।
यह सर्वर पर बनाई गई और संग्रहीत की गई किसी भी भौतिक फ़ाइलों की किसी भी आवश्यकता को हटा देता है, इसलिए किसी हाउसकीपिंग रूटीन की आवश्यकता नहीं होती है और एक बार फिर यह अंतिम उपयोगकर्ता के लिए सहज है।
ध्यान दें, इसके TempData
बजाय का उपयोग करने का लाभ यह Session
है कि एक बार TempData
डेटा को पढ़ने के बाद साफ़ किया जाता है, इसलिए यदि आपके पास फ़ाइल अनुरोधों की अधिक मात्रा है, तो यह मेमोरी उपयोग के मामले में अधिक कुशल होगा। टेंपडाटा बेस्ट प्रैक्टिस देखें ।
मूल जवाब
आप सीधे एक AJAX कॉल के माध्यम से डाउनलोड के लिए एक फ़ाइल वापस नहीं कर सकते हैं, एक वैकल्पिक दृष्टिकोण अपने सर्वर से संबंधित डेटा पोस्ट करने के लिए AJAX कॉल का उपयोग करना है। फिर आप एक्सेल फाइल बनाने के लिए सर्वर साइड कोड का उपयोग कर सकते हैं (मैं इसके लिए EPPlus या NPOI का उपयोग करने की सिफारिश करूंगा, हालांकि ऐसा लगता है जैसे आपके पास यह भाग काम कर रहा है)।
एक बार जब फ़ाइल सर्वर पर बन जाती है, तो आपके AJAX कॉल पर वापसी मान के रूप में फ़ाइल (या सिर्फ फ़ाइल नाम) के लिए पथ वापस करें और फिर window.location
इस URL पर जावास्क्रिप्ट सेट करें जो फ़ाइल को डाउनलोड करने के लिए ब्राउज़र को संकेत देगा।
अंतिम उपयोगकर्ता के दृष्टिकोण से, फ़ाइल डाउनलोड ऑपरेशन सहज है क्योंकि वे उस पृष्ठ को कभी नहीं छोड़ते हैं जिस पर अनुरोध उत्पन्न होता है।
नीचे इसे प्राप्त करने के लिए अजाक्स कॉल का एक सरल आकस्मिक उदाहरण है:
$.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 पैरामीटर कंट्रोलर / एक्शन विधि है जहाँ आपका कोड एक्सेल फाइल बनाएगा।
- डेटा पैरामीटर में json डेटा होता है जिसे फ़ॉर्म से निकाला जाएगा।
- returnValue आपकी नई बनाई गई एक्सेल फ़ाइल का फ़ाइल नाम होगा।
- विंडो स्थान नियंत्रक / कार्रवाई विधि है कि वास्तव में डाउनलोड के लिए आपकी फ़ाइल रिटर्न के लिए आदेश रीडायरेक्ट हैं।
डाउनलोड क्रिया के लिए एक नमूना नियंत्रक विधि होगी:
[HttpGet]
public virtual ActionResult Download(string file)
{
string fullPath = Path.Combine(Server.MapPath("~/MyFiles"), file);
return File(fullPath, "application/vnd.ms-excel", file);
}