Downloaded Excel file with Macros is corrupted via MVC ajax - ajax

I am trying to download an Excel file from MVC Ajax call, but everytime it downloads, I cannot open the file, because it says it is corrupted.
Following is my Ajax call:
function Download() {
$.ajax({
url: '/Home/ExcelDownload',
type: "POST",
success: function (result) {
if (result !== null || result !== "") {
$('<iframe src=' + result + ' frameborder="0" scrolling="no" id="myFrame"></iframe>')
.appendTo('body');
}
//var iframe = document.getElementById('invisible');
//iframe.src = result;
},
error: function (data) {
}
});}
From my controller I call the action method like this:
string host = Request.Url.Authority;
return Json("http://" + host + "/ExcelTemplates/EInvoiceTemplateNew.xlsm");
I am having macros enabled in Excel as well.
The file downloads properly but when I try to open it, it gives me a warning about being from a trusted source, and on clicking yes, I get another dialog saying "The workbook cannot be opened or repaired By Microsoft excel because it is corrupt".
Any help or suggestions or workarounds to make my code working.
Thanks In Advance!!!..

I'm not able to do a project and try the excel library right now as I'm at work, so I'm just doing this much quickly.
To start, I think you can get away from using ajax completely. Which is always nice because it's less code to maintain, you can use a normal anchor tag:
Download
This won't redirect the page, because the browser should interpret the content-disposition/Mime type, and just download the file.
Then you can try returning the file like this, where you first read the file (in this case into a stream, but you could do it as a byte[] as well as File has a overload for it), and then return it through your controller by using File and FileResult.
E.g:
public FileResult GetExcelDocument(int id)
{
string filePath = GetPathToDocumentWithId(id); //However you get the excel file path
return File(System.IO.File.OpenRead(filePath),
System.Web.MimeMapping.GetMimeMapping(filePath),
"filename.xlsm");
}
This website says that the content type/MIME of .xlsm is "application/vnd.ms-excel.sheet.macroEnabled.12", but I think GetMimeMapping should work.
Optionally, if you want the file to download in a new tab, you can set the target of the anchor tag to "_blank" and it should open a new tab and download the file there.
Let me know what the result is.
If you're set on using JQuery and ajax, I found this example which follows along your previous attempt:
From Here
var $idown; // Keep it outside of the function, so it's initialized once.
downloadURL : function(url) {
if ($idown) {
$idown.attr('src',url);
} else {
$idown = $('<iframe>', { id:'idown', src:url }).hide().appendTo('body');
}
},

Related

Can't download file with open bootstrap Modal

I have an AngularJS front-end that opens a Bootstrap Modal that has a button on it. When this button is clicked it calls a Web API method on the server that generates an OPEN XML Word Document as a stream and returns the file to the client. I have several files downloading successfully in IE where I see this:
However, for the file I'm trying to download with the open Modal I never see the above image. It's not the file itself because it downloads successfully when I try it without the open Modal. Also, I don't see any errors reported in IE Dev Tools. I don't think it's the code that generates the streams because the same code generates other files successfully. I also tried closing the Modal before downloading but that didn't work either. It's almost like the Modal is "blocking" the download.
Here is the Modal definition:
var isOUOModal;
var isSubmitItem = false;
var openSignificanceModal = function () {
return $modal.open({
scope: $scope,
templateUrl: './app/oa/significance_modal.html',
controller: SignificanceModalCtrl,
keyboard: false,
backdrop: 'static',
resolve: {
item: function () {
return $scope.item;
}
}
});
};
var SignificanceModalCtrl = function ($scope, $modalInstance, item, $window) {
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
I seem to be out of ideas at the moment so any assistance is much appreciated.
Thanks,
Pete
I was able to determine the cause of the problem here. It had to do with the way I was calling the Web API Method. I was using an AJAX JQuery GET call. Instead I had to do something like this:
var url = url;
window.location.href = url;
When I changed the way I was calling the Web API method I saw the stream returned to the client as expected.

How to 'POST' a image through xhttp?

I´m trying to do this:
var http = new XMLHttpRequest();
var url = "guardarImg.php";
var params = $('#form').serialize();
http.open("POST", url, true);
http.setRequestHeader("Content-type", "multipart/form-data");
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
But is not working, it shows me in my php that 'Image' is not defined, but when I do it through a average Submit it works fine.
All the similar samples I saw work with string data but I need to achieve it with images to make it work later in Intel XDK
What I´m doing wrong?
Can you show me a sample?
Sorry if my question is too basic, I´m a noob with xmlhttp and ajax stuff.
You have the right idea with regard to $("#form").serialize() but for the mess that is (still) AJAX uploads. Yuck (and shame on me for not noting that detail the first time :-( ).
The problem with file uploads via AJAX is (as is often the case), Internet Explorer. Basically, it didn't support the FormData object until IE10 (which means that, if you care about supporting XP users, they'd better be running not-IE). FormData greatly simplifies the process of uploading stuff via AJAX; if you don't have that, here are your options:
Put a little tiny IFRAME on the page and manage that for the actual file upload.
Encode the form data programmatically using something like JSON and send that via jQuery.
Use a nice plugin that wraps this all for you (and uses one or more of these techniques under the covers).
I'm going to assume you don't care about IE8/9 (pretty much everyone else isn't a problem) and give you a FormData solution. Unlike the previous edit, I'm popping in the whole function in here since it's decently informative. This particular solution uploads an entire form, pulling in the existing fields into the FormData object and treating the files specially.
<!-- Many ways to skin this particular feline; I like this one :-) -->
<form onsubmit="return uploadFiles(this)">
<!-- Access from PHP using $_FILES["somefile"]["name"][$idx]... -->
<input type="file" name="somefiles" multiple="1" />
</form>
<script>
// Function to upload a form via FormData, breaking out files and cutting
// any non-named elements. Assumes that there's a #status DIV and the
// URL is hardcoded.
function uploadFiles(frm) {
var formdata = new FormData();
// I'm doing this to separate out the upload content. Note that multiple
// files can be uploaded and will appear as a decently-friendly PHP array
// in $_FILES. Note also that this does handle multiple files properly
// (a default FormData(frm) wouldn't exactly :-( ).
$(frm).find(":input").each(function(idx, ele) {
// This is a file field. Break it out.
if(ele.files) {
for(i=0; i<ele.files.length; i++) {
formdata.append(ele.name + "[" + i + "]", ele.files[i]);
}
// Not a file element, so put in the upload iff there's a name.
} else if(ele.name) {
formdata.append(ele.name, ele.value);
}
});
// Run the AJAX.
$.ajax({
url: "test.php", // Change Me :-)
type: "POST",
data: formdata,
processData: false, // Need these to keep jQuery from messing up your form
contentType: false,
success: function(data) {
$("#status").html(data);
},
error: function(xhr, status, error) {
$("#status").html("Error uploading file(s): " + error);
},
});
return false; // Keep the form from submitting
}
</script>
I have a complete HTML file and corresponding PHP that work at pastebin.
If I were you, I'd actually just use Sebastian's jQuery File Upload if you can. It's got all that modern UI goodness (include progress metering), browser abstraction, and it's MIT licensed to boot. That said, this answer will get you on your way if you just need something to copypasta. Good luck!

Download links with TideSDK

I have seen several posts coming close to solving my issue, but I am still not able to accomplish my simple task, which is this:
Imagine I have a window which contains a link to a remote file (most often it will be a zip file). How can I structure and call a function that accesses the file and opens a "Save As" dialogue so that the user can choose where to save the downloaded file? It would be nice to be able to pass different variables from other links to the same function to accomplish the same thing for other downloadable files.
And yes, I am completely new to TideSDK and not exactly a javascript expert, if this is causing much painful slapping of foreheads.
Try this.
Any link with a class of "save-as" will trigger the "Save as" dialog. The file will be saved AFTER the user selects the location, gives it a name and clicks Save. This does use jquery.
Download WordPress
<script>
$(function(){
var currentLink;
$('.save-as').click(function() {
var link = $(this).attr('href');
var filename = link.substring(link.lastIndexOf('/')+1);
currentLink = link;
Ti.UI.currentWindow.openSaveAsDialog(saveComplete, {
title: 'Save As...',
multiple: false,
defaultName : filename
});
return false;
}); // End save as.
var saveComplete = function(results) {
if(results.length>0) {
var downloadFile = results[0];
console.log("Download the file");
var httpClient = Ti.Network.createHTTPClient();
httpClient.open('GET', currentLink);
httpClient.receive(function(data) {
var file = Ti.Filesystem.getFile(downloadFile);
var fileStream = file.open(Ti.Filesystem.MODE_APPEND);
fileStream.write(data);
fileStream.close();
});
}
};
});
</script>

Asp MVC 3 download a zipped file

I have a view with a generate button. When I click It I am navigating to a Generate method of a controller using ajax call.
generate = function () {
$.ajax({
url: "/franchise/Generate",
type: "POST",
data: { id: omega.franchiseInfo.Id(), imagesPath: omega.franchiseInfo.ImagesPath() },
});
}
Here is my Generate method:
public ActionResult Generate(int id, string imagesPath)
{
// some logic here
var zipFileName = #"D:\FranchiseGeneration\MyZipFile.zip";
using (var zip = new ZipFile())
{
zip.AddDirectory(#"D:\FranchiseGeneration\Test", "Generation");
zip.Save(zipFileName);
}
return File(zipFileName, "application/zip", "MyZipFile.zip");
}
MyZipFile.zip is created on my hard drive as specified. I expect the user to be prompted to download the zipped file ... but nothing happens. I am rather new to Mvc3 and I am not sure what I am doing wrong. Any suggestions with code samples are welcome. Thank You!
It's an ajax call, it doesn't make sense to return a File in an ajax call... ajax stands for Asynchronous JavaScript and XML.. ok with json ad some other text based things, but to work with binary files you'll need some exta works.
In you scenario, I think the best thing to do (the simplest one) is to perform a normal postback, not ajax (or even a simple GET would work).
It is not possible to trigger a file download via an ajax request like this.
There are other ways to make something like it happen though.
http://johnculviner.com/post/2012/03/22/Ajax-like-feature-rich-file-downloads-with-jQuery-File-Download.aspx

Sending data from a file on iPad to a php file on server via AJAX

I'm trying to upload data captured in a local html file on an iPad and save it to server.
I found this: Sending data to an external file via Ajax
So as far as I can understand, there is no way to send the info doing something like this:
ajax.open("POST",'http://www.misite.com/canvas/testSave.php',true);
from a html on the iPad, I'm right?
So I just want to know if anyone knows a trick to do this. Thanks!
After a couple of weeks this is what I could achieved.
1.- The function that sends the data (an image generated from a canvas):
function sendImageData()
{
var filename = $("#filename").val().trim();
if(filename == ''){
alert("File name is needed");
return;
}
var uploadCanvas = $("#uploadCanvas");
var canvasData = uploadCanvas[0].toDataURL("image/png");
var debugConsole= $("#debugConsole");
debugConsole.val(canvasData);
$.ajax({
type: 'POST',
url: "http://yourremoteserver.com/canvas/save.php",
data: {
canvasData:canvasData,
filename:filename
}
}).done(function() {
alert("saved: " + filename + ".png");// THIS IS NOT WORKING YET.
}
);
}
2.- The PHP that receives and saves the data:
<?php
$imagen = $_POST['canvasData'];
$filename = $_POST['filename'];
if (isset($imagen)){
$imageData=$imagen;
$filteredData=substr($imageData, strpos($imageData, ",")+1);
$unencodedData=base64_decode($filteredData);
$fp = fopen( $filename.'.png', 'wb' );
fwrite( $fp, $unencodedData);
fclose( $fp );
}
?>
If anyone can help me with the .done function to work (remember, the html file is in an ipad and the php on a server) let me know. Cheers.
I have used Plupload for this purpose. It automagically switches between flash, silverlight, and html5 so it should work on just about any browser (including the safari on the iPad). Basically, it uploads a file to a processing script with some generated id (it generates it for you). Then, you can poll another page to get the uploaded data once it is finished uploading.
EDIT: Re-reading your post I am not sure how pertinent this is since it requires the user to select a file and I'm not sure that's what you are getting at exactly.

Resources