PDA

View Full Version : Error when downloading xls Excel File



gelleneu
3 Apr 2008, 11:42 PM
Hello,

I'm a little confused. In some other threads, I have read, that creating an Excel File "on the fly", and showing a download-dialog for that is not so easy, even if you want to do this with an Ajax-Request and POST-Variables.

So I go another way. My trick is to send an Ext.Ajax.Request with POST Data to a php file. This PHP-File writes an (physical) *.xls File with a specified Filename directly on the server.

In my Callback method of the Ajax-Request, I will start downloading these xls-File with
"location.href = http://mydomain.com/myexcel.xls".

But when I call the location.href, I get an Error Message in Firebug:

[Exception... "'<error>' when calling method: [nsIContentHandler::handleContent]" nsresult: "0x805d0001 (<unknown>)" location: "<unknown>" data: no]

But the download Dialog appears, and download works correctly. What could be the Problem?

gelleneu
4 Apr 2008, 1:35 AM
I get this message too, if I try to download any xls File from the server. Possibly, the error occurs, because I've installed only OpenOffice Calc instead of MS Excel?

Animal
4 Apr 2008, 1:39 AM
Let me get this clear, you're sending two requests, one POST containing the whole of the Grid data, and in the callback, you're setting the location.href to something?

gelleneu
4 Apr 2008, 5:09 AM
Yes. I send Post data with an Ext.Ajax.Request to a php file.
The php file creates an excel-file on the server, including the post data of the grid.
Then the php files responses success = true and filename = export.xls.

In the callback function I start location.href='http://myserver.com/'+response.responseText.filename

What should I say? it works. But the extension .xls causes the error. When I save the file as f.e. export.zip, the download works without any errors, but I have to rename the exported file manually.

I think, the problem is, that I haven't installed MS Excel on my PC. Instead of this I use OpenOffice Calc.

But the solution itself works perfectly. The created file on the server will be overwritten on any export, so that everytime only one excel file on the server exists.

Animal
4 Apr 2008, 5:38 AM
The best thing to do would be to post the data NOT using Ajax, but using a hidden form element containing the data. Target the form at a hidden iframe.

Then in your server code set the headers



Content-Type: application/vnd.ms-excel
Content-Disposition: attachment;filename=whatever-you-want.xls


And send back the Excel data.

The browser sees that, and pops up the open/save prompt using the name you specify in the filename portion of the disposition.

Just one request needed.

keypoint
21 Apr 2008, 3:12 PM
The previous methods for generating attachments worked fine, if the method was GET.
For POST, in order to obtain a download attachment window, you can use something like this; I am using the hdExport field to tell the form processing script to expot instead of process the form normally. What the code does is submit the form normally (not via Ajax), in a new window. Place this in the handler of your export button and you're done.



myForm().getForm().getEl().dom.target = '_blank';
myForm().getForm().getEl().dom.action = 'myUrl';
if (!Ext.fly('hdExport')) {
Ext.DomHelper.insertFirst(myForm().getForm().getEl(), {
tag: 'input',
type: 'hidden',
id: 'hdExport',
name: 'hdExport',
value: '1'
});
}
myForm().getForm().getEl().dom.submit();

Animal
21 Apr 2008, 11:45 PM
Or, alternatively:



Ext.Ajax.request({
url: 'myUrl',
form: myForm,
params: {hdExport: 1},
isUpload: true
});

keypoint
22 Apr 2008, 1:03 PM
Heeey :)
This is exactly what I needed, but didn't find a clear reference to it. Thanks!
Much cleaner than my solution.

devnull
22 Apr 2008, 2:08 PM
using "isUpload: true" has not worked reliably for me for this purpose; IE would appear to do nothing (FF worked fine). I have continued to use the hidden iframe method.

Animal
23 Apr 2008, 12:07 AM
isUpload forces Ext.Ajax to use a hidden iframe.

If it doesn't work somewhere, there's a bug somewhere.

keypoint
6 May 2008, 1:48 PM
devnull, do you have a form to provide as the form argument? If you don't it will not work. For example if you only have a grid and you need an export button somewhere. If that is the case, add a hidden form element and provide that as the argument. Here's a sample for a formless attachment request:



function getTbExcel() {
if (!Ext.fly('tbExcel')) {
return {
xtype: 'tbbutton',
id: 'tbExcel',
text: 'Excel',
cls: 'x-btn-text-icon',
icon: 'images/icons/excel-s.gif',
handler: function() {
//create dummy form
if (!Ext.fly('frmDummy')) {
var frm = document.createElement('form');
frm.id = 'frmDummy';
frm.name = id;
frm.className = 'x-hidden';
document.body.appendChild(frm);
}

//get attachment
Ext.Ajax.request({
url: 'reports/loadexcel',
form: Ext.fly('frmDummy'),
isUpload: true
});
}
};
} else {
return Ext.getCmp('tbExcel');
}
}


This is a function I use to get my excel export button. See the part with the form creation and ajax request. If you do have a form in the page, you don't need that part. Just say form: myFormPanel.getForm().el and you're done

By the way, Animal, how do you feel about this approach for creating/using fields? It's pretty close to the Java getter thing :)

fshort
10 Jun 2008, 12:44 PM
Hi,
Off of this, lets say at the time the user clicks the export button I show a progress dialog while the data is being fetched from the server. When the request completes and the file dialog pops up, will Ext.Ajax.request detect the fact the request completed, invoke the callback function, so I can and close the progress dialog?

Thanks,
Fred

Shmoo
9 Jul 2008, 12:45 AM
Hi,

I am also doing something similar, but in my case, I use Java in my server side.

My problem is quite strange, after viewing the grid, and clicking a button to save as a csv file, it goes back to the server, makes a csv file there, then returns to me the url to that file.

Firefox shows the "save file as" dialog but the "Ok" button is disabled. In IE7, nothing happens when I click the button.

I am just doing

var filewin = window.open('$File_path_url');

at my client-side script.

Any ideas what went wrong?

tonedeaf
16 Aug 2008, 11:21 AM
Hi,
Off of this, lets say at the time the user clicks the export button I show a progress dialog while the data is being fetched from the server. When the request completes and the file dialog pops up, will Ext.Ajax.request detect the fact the request completed, invoke the callback function, so I can and close the progress dialog?

Thanks,
Fred

Firefox invokes the callback function after the AJAX request, but IE6 doesn't (haven't checked with IE7).

I'm displaying the grid loadMask (GridPanel.loadMask.show()) and when the request completes, I hide it in the callback function.

Firefox invokes the callback function, hides the loadMask and shows the save dialog. IE6 doesn't invoke the callback function and shows the save dialog directly, the loadMask stays on and the callback is never invoked.

Same would apply to your progress dialog. One workaround is not to show any progress dialog, but for long operations, the user might need some feedback.

Can anyone help in resolving this situation for IE ?

descheret
9 Sep 2008, 4:30 AM
hello,

my problem is similar - I have a grid, select some downloads with the checkbox model, click a button and a "save as" window should pop up. works perfect in IE7 and FF but not in IE6. Is there anyone who can help me :-/

I'm using the following scripts and Ext 2.2:

Javascript:



/*
# there is a grid with the checkboxselection model, from the selected rows I create a
# json "array" with the download ids (strParams) - these go to the action handle
# which looks for the right files, group and zip them and open a zip save as dialoge
*/

if (!Ext.fly('frmDummy')) {
var frm = document.createElement('form');
frm.id = 'frmDummy';
frm.name = id;
frm.className = 'x-hidden';
document.body.appendChild(frm);
}
Ext.Ajax.request({
url: 'action.php',
method : 'POST',
form: Ext.fly('frmDummy'),
callback: function(o, s, r){
//alert(r.responseText);
},
isUpload: true,
params: { a: action, documents: strParams }
});


all vars are transported very well to the php script (works in ie7 and ff)

PHP:



// I'm creating an archive here and save it in a temp folder

header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header('Content-type: application/zip');
header("Content-Disposition: attachment;filename=" . basename($archive));
//header("Content-Transfer-Encoding: binary ");
readfile($archive);

unlink($archive);
exit;



thanks a lot
Ron

Bandorka
22 Feb 2009, 9:33 AM
Hi,

Yes it all works, but with the isUpload method in IE, a security warning appears for the download and if you click yes, the whole page reloads and you are back at the beginning...


Any idea

B

rblon
15 Jun 2010, 11:30 AM
Sorry to revive an old thread, but it answered my question "how to save to file" perfectly.

I have tested the solution by keypoint also in IE 6 and it worked, so I'm not sure why it didn't for the others. Perhaps it has to with security settings that are different on my machine? Descheret, Bandorka, did you find out what was causing the issue you were observing?

aw1zard2
11 Aug 2010, 12:10 PM
I was looking up something on php.net and found this comment under the header() function. I copied the comment here and made bold text out of the interesting part. And thinking about it does make a lot of sense. :)


After lots of research and testing, I'd like to share my findings about my problems with Internet Explorer and file downloads.

Take a look at this code, which replicates the normal download of a Javascript:

<?php
if(strstr($_SERVER["HTTP_USER_AGENT"],"MSIE")==false) {
header("Content-type: text/javascript");
header("Content-Disposition: inline; filename=\"download.js\"");
header("Content-Length: ".filesize("my-file.js"));
} else {
header("Content-type: application/force-download");
header("Content-Disposition: attachment; filename=\"download.js\"");
header("Content-Length: ".filesize("my-file.js"));
}
header("Expires: Fri, 01 Jan 2010 05:00:00 GMT");
if(strstr($_SERVER["HTTP_USER_AGENT"],"MSIE")==false) {
header("Cache-Control: no-cache");
header("Pragma: no-cache");
}
include("my-file.js");
?>
Now let me explain:

I start out by checking for IE, then if not IE, I set Content-type (case-sensitive) to JS and set Content-Disposition (every header is case-sensitive from now on) to inline, because most browsers outside of IE like to display JS inline. (User may change settings). The Content-Length header is required by some browsers to activate download box. Then, if it is IE, the "application/force-download" Content-type is sometimes required to show the download box. Use this if you don't want your PDF to display in the browser (in IE). I use it here to make sure the box opens. Anyway, I set the Content-Disposition to attachment because I already know that the box will appear. Then I have the Content-Length again.

Now, here's my big point. I have the Cache-Control and Pragma headers sent only if not IE. THESE HEADERS WILL PREVENT DOWNLOAD ON IE!!! Only use the Expires header, after all, it will require the file to be downloaded again the next time. This is not a bug! IE stores downloads in the Temporary Internet Files folder until the download is complete. I know this because once I downloaded a huge file to My Documents, but the Download Dialog box put it in the Temp folder and moved it at the end. Just think about it. If IE requires the file to be downloaded to the Temp folder, setting the Cache-Control and Pragma headers will cause an error!

I hope this saves someone some time!
~Cody G.

x10
5 Apr 2011, 5:46 AM
Thank you friends, this thread saved hours of headache.
It works for me with ExtJS 3.3 + Zend Framework 1.10 + PHPExcel 1.7.6



Ext.Ajax.request({
url: 'myUrl',
form: myWindow.myFormPanel.getForm().el,
params: {myParam: 1},
isUpload: true
});
For server side code visit PHPExcel forum
http://phpexcel.codeplex.com/discussions/250120

anuragchaturvedi
2 Sep 2012, 1:35 AM
Hi Guys,

but when I export to word or Excel then downloaded file does not show extension .doc or xls.

Regards
Anurag