अंत में इस काम को प्राप्त करने के लिए प्रबंधन करें और सोचा कि मैं यहां दस्तावेज दूंगा कि दूसरों को दर्द से बचाने की उम्मीद में यहां कैसे।
वातावरण
- VS2012
- SQL सर्वर 2008R2
- .NET 4.5
- ASP.NET MVC4 (रेज़र)
- विंडोज 7
समर्थित वेब ब्राउज़र
- फायरफोक्स 23
- IE १०
- क्रोम 29
- ओपेरा 16
- सफारी 5.1.7 (विंडोज के लिए अंतिम एक?)
मेरा कार्य ui बटन क्लिक पर था, मेरे नियंत्रक पर एक विधि को कॉल करें (कुछ params के साथ) और फिर इसे xslt परिवर्तन के माध्यम से MS-Excel XML लौटाएं। MS-Excel XML लौटाया गया तो ब्राउज़र ओपन / सेव डायलॉग को पॉपअप करेगा। यह सभी ब्राउज़रों (ऊपर सूचीबद्ध) में काम करना था।
पहले तो मैंने अजाक्स के साथ और फ़ाइलनाम के लिए "डाउनलोड" विशेषता के साथ एक गतिशील एंकर बनाने की कोशिश की, लेकिन यह केवल 5 ब्राउज़रों (एफएफ, क्रोम, ओपेरा) में से लगभग 3 के लिए काम किया और आईई या सफारी के लिए नहीं। और वास्तविक "डाउनलोड" का कारण बनने के लिए एंकर के क्लिक इवेंट को प्रोग्रामिक रूप से फायर करने की कोशिश करने के मुद्दे थे।
मैंने जो किया वह एक "अदृश्य" IFRAME का उपयोग करते हुए समाप्त हो गया और इसने सभी 5 ब्राउज़रों के लिए काम किया!
तो यहाँ है कि मैं क्या लेकर आया हूँ: [कृपया ध्यान दें कि मैं किसी भी तरह से html / जावास्क्रिप्ट गुरु नहीं हूँ और केवल प्रासंगिक कोड शामिल किया है]
HTML (प्रासंगिक बिट्स का स्निपेट)
<div id="docxOutput">
<iframe id="ifOffice" name="ifOffice" width="0" height="0"
hidden="hidden" seamless='seamless' frameBorder="0" scrolling="no"></iframe></div>
JAVASCRIPT
//url to call in the controller to get MS-Excel xml
var _lnkToControllerExcel = '@Url.Action("ExportToExcel", "Home")';
$("#btExportToExcel").on("click", function (event) {
event.preventDefault();
$("#ProgressDialog").show();//like an ajax loader gif
//grab the basket as xml
var keys = GetMyKeys();//returns delimited list of keys (for selected items from UI)
//potential problem - the querystring might be too long??
//2K in IE8
//4096 characters in ASP.Net
//parameter key names must match signature of Controller method
var qsParams = [
'keys=' + keys,
'locale=' + '@locale'
].join('&');
//The element with id="ifOffice"
var officeFrame = $("#ifOffice")[0];
//construct the url for the iframe
var srcUrl = _lnkToControllerExcel + '?' + qsParams;
try {
if (officeFrame != null) {
//Controller method can take up to 4 seconds to return
officeFrame.setAttribute("src", srcUrl);
}
else {
alert('ExportToExcel - failed to get reference to the office iframe!');
}
} catch (ex) {
var errMsg = "ExportToExcel Button Click Handler Error: ";
HandleException(ex, errMsg);
}
finally {
//Need a small 3 second ( delay for the generated MS-Excel XML to come down from server)
setTimeout(function () {
//after the timeout then hide the loader graphic
$("#ProgressDialog").hide();
}, 3000);
//clean up
officeFrame = null;
srcUrl = null;
qsParams = null;
keys = null;
}
});
C # SERVER-SIDE (कोड स्निपेट) @ ड्रू ने XmlActionResult नामक एक कस्टम ActionResult बनाया है जिसे मैंने अपने उद्देश्य के लिए संशोधित किया है।
XML को एक नियंत्रक के एक्शन से एक ActionResult के रूप में लौटाएं?
मेरा नियंत्रक तरीका (ActionResult लौटाता है)
- SQL सर्वर संग्रहीत संग्रह के लिए कुंजी पैरामीटर पास करता है जो XML उत्पन्न करता है
- तब XML को MS-Excel xml (XmlDocument) में xslt के माध्यम से बदल दिया जाता है
संशोधित XmlActionResult का उदाहरण बनाता है और इसे लौटाता है
XmlActionResult परिणाम = नया XmlActionResult (excelXML, "एप्लिकेशन / vnd.ms-excel)"; स्ट्रिंग संस्करण = DateTime.Now.ToString ("dd_MMM_yyyy_hhmmsstb"); string fileMask = "LabelExport_ {0} .xml";
result.DownloadFilename = string.Format (fileMask, संस्करण); वापसी परिणाम;
XDActionResult वर्ग का मुख्य संशोधन जो @ बनाया गया था।
public override void ExecuteResult(ControllerContext context)
{
string lastModDate = DateTime.Now.ToString("R");
//Content-Disposition: attachment; filename="<file name.xml>"
// must set the Content-Disposition so that the web browser will pop the open/save dialog
string disposition = "attachment; " +
"filename=\"" + this.DownloadFilename + "\"; ";
context.HttpContext.Response.Clear();
context.HttpContext.Response.ClearContent();
context.HttpContext.Response.ClearHeaders();
context.HttpContext.Response.Cookies.Clear();
context.HttpContext.Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);// Stop Caching in IE
context.HttpContext.Response.Cache.SetNoStore();// Stop Caching in Firefox
context.HttpContext.Response.Cache.SetMaxAge(TimeSpan.Zero);
context.HttpContext.Response.CacheControl = "private";
context.HttpContext.Response.Cache.SetLastModified(DateTime.Now.ToUniversalTime());
context.HttpContext.Response.ContentType = this.MimeType;
context.HttpContext.Response.Charset = System.Text.UTF8Encoding.UTF8.WebName;
//context.HttpContext.Response.Headers.Add("name", "value");
context.HttpContext.Response.Headers.Add("Last-Modified", lastModDate);
context.HttpContext.Response.Headers.Add("Pragma", "no-cache"); // HTTP 1.0.
context.HttpContext.Response.Headers.Add("Expires", "0"); // Proxies.
context.HttpContext.Response.AppendHeader("Content-Disposition", disposition);
using (var writer = new XmlTextWriter(context.HttpContext.Response.OutputStream, this.Encoding)
{ Formatting = this.Formatting })
this.Document.WriteTo(writer);
}
वह मूल रूप से यह था। आशा है कि यह दूसरों की मदद करता है।