PDA

View Full Version : [SOLVED] Download data from variable with a browser prompt



DarkStarDS
10 Sep 2009, 2:31 AM
Hello, I'm trying to find a solution for 2 days now :
I want to export data from a store to a csv file. I have first tried client side.
There are only 2 ways: with data url or openning a new window and do save as. This is not perfect at all as urls in IE have a very short size compared to FF or chrome. And we can add security issues.
So now, i have written the php function to have my csv string ready to be exported. But how do I do that ?

I have a button csv export that sends an AJAX call :


new Ext.Button({
id: 'grid-csv-button',
text: 'Export to CSV',
iconCls: 'csv',
handler: function()
{
Ext.Ajax.request({
url: './server.php',
method: 'POST',
params: {task: 'csv', query: reportStore.getReportInfo('name', report_id)},
success: function(response, opts) {
//var obj = Ext.decode(response.responseText);
//console.dir(obj);
},
failure: function(response, opts) {
//console.log('server-side failure with status code ' + response.status);
}
});
}
})In the PHP file, I have defined headers :


function exportToCsv()
{
$report = getReport();
// Required for Internet Explorer, otherwise Content-disposition is ignored
if( ini_get('zlib.output_compression'))
{
ini_set('zlib.output_compression', 'Off');
}

header( "Pragma: public" );
header( "Expires: 0" );
header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
header( "Pragma: no-cache" );
header( "Cache-Control: private", false );
header( "Content-Type: text/csv" );
header( "Content-Disposition: attachment; filename=\"test.csv\";" );
header( "Content-Transfer-Encoding: binary" );
header( "Content-Length: " . strlen( $report ) );

echo $report;
}Nothing happens, no Save as dialog box... Help ! :)

BitPoet
10 Sep 2009, 2:46 AM
Ajax (i.e. the XMLHttpRequest object) won't give you a download prompt. You can either use a form with hidden fields for 'task' and 'query' and do a BasicForm.standardSubmit or pass those parameters in the url for the src of a hidden iframe.

DarkStarDS
10 Sep 2009, 3:29 AM
Ajax is just a way to send requests to the server. Then the php script handles the prompt with the headers it sends to the browser. Am I wrong ?
And I haven't understood the solutions you propose to me. Can you be more precise with some examples ?
Thank you.

Condor
10 Sep 2009, 3:47 AM
Simple extension:

Ext.ux.Report = Ext.extend(Ext.Component, {
autoEl: {tag: 'iframe', cls: 'x-hidden', src: Ext.SSL_SECURE_URL},
load: function(config){
this.getEl().dom.src = config.url + (config.params ? '?' + Ext.urlEncode(config.params) : '');
}
});
Ext.reg('ux.report', Ext.ux.Report);

Usage:

Add this to your layout:

{
id: 'report',
xtype: 'ux.report'
}
and use:

Ext.getCmp('report').load({
url: './server.php',
params: {
task: 'csv',
query: reportStore.getReportInfo('name', report_id)
}
});

(and no, I can't add a 'loading' message, because there is no indication when it's done)

DarkStarDS
10 Sep 2009, 4:13 AM
Thank you Condor.
I have tried this. I am sorry again, I don't really understand the code you posted. This component has an hidden iframe property that contains the data ?
I don't know where I have to put these lines :


{
id: 'report',
xtype: 'ux.report'
}

In my GridPanel ? In my store than contains the data ?
What is the expected result ? A Save as dialog box ?
Do I need to change something server side ? Are the headers ok ?

Condor
10 Sep 2009, 4:20 AM
Anywhere in your layout will do.

Alternatively you could use:

var report = new Ext.ux.Report({
renderTo: Ext.getBody()
});
...
report.load({
url: './server.php',
params: {
task: 'csv',
query: reportStore.getReportInfo('name', report_id)
}
});

DarkStarDS
10 Sep 2009, 4:27 AM
Ok, I've done it. When I click on the button, nothing happens. Well, nothing appears, the report's load method has been indeed triggered and has retrieved the info from the script. But no download prompt.
Can you answer my few question above please ? Thx

Condor
10 Sep 2009, 4:59 AM
Are you sure that all your headers are correct?

The most important one has a ';' too many:

header( "Content-Disposition: attachment; filename=\"test.csv\";" );

DarkStarDS
10 Sep 2009, 6:20 AM
No, it's not an error, I've fixed the problem and it works with the ";".
The error happened in a previous switch case in my php script. Everything is ok now, thank you !

esparqui
30 Dec 2009, 2:23 AM
In this case, the parameters are sent by method GET. How could I send the parameters byt POST using this?

Thank.

Condor
30 Dec 2009, 2:26 AM
That's a bit more complicated. You would have to create an invisible form with inputs that hold the values and set the target to the IFRAME.

ps. Most of this code can be copied from Ext.data.Connection.doFormUpload (but Content-type:attachment won't generate a callback).

esparqui
30 Dec 2009, 3:31 AM
This is my code:

var connectionPDF = new Ext.data.Connection();
connectionPDF.request({
url: 'rpdf.php',
method: 'POST',
params: {
title: 'title',
data: Ext.util.JSON.encode(dataStore),
header: Ext.util.JSON.encode(dataHeaders)
}
});

It send right de data by POST, but when I get de response it not handle well de response, because the response is:

%PDF-1.3
%????

1 0 obj
<< /Type /Catalog
/Outlines 2 0 R
....
....

Therefore, it not get the header content-type: attachment.

How I can solved this?

Thank.

Condor
30 Dec 2009, 3:45 AM
You can't use Ext.data.Connection to download a binary attachment!

esparqui
30 Dec 2009, 8:41 AM
ok. I did what you said, using the doFormUpload method code and the code following link:

http://www.extjs.com/forum/showthread.php?t=44862

And solve the problem.

Thanks for your help.

madirishman
3 Mar 2010, 9:02 AM
Where can I find "Ext.ux.Report"? I looked in the examples folder, but no luck.

Thanks
md

fay
3 Mar 2010, 9:26 AM
Seo (http://www.extjs.com/forum/showthread.php?p=385087#post385087)! Just above ye :)

It's just a simple extension created by Condor.

madirishman
3 Mar 2010, 10:32 AM
ahhh, thanks. It's been a long week already!

madirishman
9 Mar 2010, 7:15 AM
I just discovered this is not working on friggin' ie6. (yup, I work for a 1.6 billon dollar company that still uses a 10 year old browser as standard). Anyways...

It works great on FF, and it appears to retrieve the doc in ie6, although it seems to hide it somewhere - it doesn't display the "save" dialog.

any ideas?

thanks!
md

astrocybernaute
15 Dec 2011, 4:00 AM
hi all,
does this work in extjs4 ? i have the same problem as esparqui (http://www.sencha.com/forum/member.php?100129-esparqui)
can u plz help me

tayyabah
29 Apr 2012, 11:34 PM
This extention is given the security warning in IE8; Can anybody help me how can I avoid this?
many thanks...

Yacine BRITAH
8 Feb 2013, 1:13 AM
can anybody tell how to get the server-side generated report in Ext.window and not in browser:
here is my code:

var frame = Ext.create('Ext.window.Window', {
title: 'PDF View',
width: 600,
height: 400,
hidden:true,
fileUpload:true,
items: [{
xtype: 'box',
autoEl:{
tag:'iframe',
style: 'height: 100%; width: 100%; border: none',
src:'/Report/Download?reportKey='+action.result.data
}
}]
});
frame.show();


the pdf file is still coming in a browser window (with the question for open or save the file) out of the ext.window. I want this generated pdf file in Ext.windows!!