PDA

View Full Version : Regular form submit - Excel export



funcman
14 Jul 2007, 9:38 AM
Hello all,

I've implemented an excel export feature for selected rows of a grid and it works perfectly (brings up a download dialog to download the created xls file) if I visit the script directly

However if I click my grid toolbar button to export I get the following error:
missing ) in parenthetical - ext-all-debug.js (line 6003)

Here is the code for the export button

tb.add({
text: 'Export to Excel',
tooltip: 'Export modified records.',
handler: function() {
selectedRows = grid.getSelectionModel().getSelections();
rowCount = grid.getSelectionModel().getCount();
if(rowCount == 0) {
Ext.Msg.alert('Alert', 'Cannot export an empty selection');
}
else
{
var actual_records = "(";
for (var i = 0; i < rowCount; i++)
actual_records += selectedRows[i].data.familyId + ",";
actual_records = actual_records.substring(0,actual_records.length-1) + ")";

gridForm.submit(
{
waitMsg: 'Exporting selected data, please wait...',
url:'export.php',
params:{data:actual_records}
success:function(form, action) {
alert('Congrats! Your changes were exported!!!!');
},
failure: function(form, action) {
alert('Oops the export did not work out too well!');
}
}
);
}
}

In my export.php file the last lines after I've created the xls file are

header("Content-type: application/x-msdownload");
header("Content-Disposition: attachment; filename=export-".date('m-d-y').".xls");
header("Pragma: no-cache");
header("Expires: 0");
print "$header\n$data";

So when I click on the export button it gives the missing ) parenthetical error, and doesn't bring up the download dialog.

By the way, in firebug the export.php script is returning the text inside of the xls file.

Any help would be greatly appreciated.

Have a great weekend all!

jay@moduscreate.com
14 Jul 2007, 10:00 AM
Form.submit is requesting something like {success : true} from your server. It's trying to interpret the response back from the server.
Try to open a new page instead of doing a form.submit passing the form data to the server that way.

funcman
14 Jul 2007, 10:20 AM
How would i do that, Ext.Connection ?

Animal
14 Jul 2007, 10:54 PM
You're going to have to do a real browser submit rather than an XHR (which is what Ext.form.Form.submit does) to get a file download.

funcman
16 Jul 2007, 9:12 AM
Animal, could you point me in the right direction? I'm quite new to Ext.

devnull
16 Jul 2007, 9:16 AM
The way I dealt with this problem was to create a hidden iframe, and set its src property to a url (constructed as a "get" query) that returns the spreadsheet. The browser will then popup a save as dialog (or do whatever the default action for that mime type is). This is in my older code from before I discovered Ext tho, so maybe it can provide a slightly more elegant solution.

devnull
16 Jul 2007, 9:34 AM
on second thought I do have an example for Ext.


Ext.DomHelper.append(document.body, {
tag: 'iframe',
frameBorder: 0,
width: 0,
height: 0,
css: 'display:none;visibility:hidden;height:1px;',
src: getDocURL
});
you'll only want to call this once and save a reference to the object which you can set the src property on again later, since each time it will add a new iframe to the dom tree.

funcman
16 Jul 2007, 10:28 AM
I used your code snippet, however in firebug I do not see any POST's or GET's being sent out. Also I need to send a parameter along (an array of numbers which are the uid's of objects to get exported). Would you mind helping me out?

devnull
16 Jul 2007, 10:58 AM
I haven't actually used this code yet, im still in the process of porting the app to Ext that will be using it.
I will elaborate a little further on my existing code for you though.
in the HTML, I have this :


<style>
#xlsLoad{
frameBorder: no,
width: 0px,
height: 0px,
display:none;
visibility:hidden;
}
</style>
<iframe id=xlsLoad></iframe>

then:


url = "file.php?var1=foo&var2=bar";
document.getElementById('xlsLoad').src=url;
//Ext.get('xlsLoad').dom.src should work here as well

as soon as that src property is set, the browser should make the get request for the spreadsheet. theres probably a way to make it use post data as well, but I do not know how at this time.

funcman
19 Jul 2007, 6:54 AM
I'm still trying to bang this out, I'm just not sure if I'm doing this correctly so I would appreciate it if I could get some guidance.

My "Export to Excel" button code:



// cls, text, tooltip stuff
// ....

// button handler
// I have a variable called actual_records which holds the id's of the objects to export
// this is the information I want to pass back to the server

var connection = new Ext.BasicForm(Ext.get("xlsSend"));
connection.el.dom.action = 'export.php';
connection.el.dom.method = 'POST';
connection.el.dom.baseParams = Ext.encode(actual_records);
connection.el.dom.submit();


and then my grid.html file



// .... html > body ....

<iframe id="xlsLoad"></iframe>
<form id="xlsSend" target="xlsLoad"></form>


When I select a record and click the Export to Excel button a new download dialog DOES come up, however in firebug I don't see any POSTs or GETs being sent out. Is this normal behaviour?

Also, on the server side (using PHP), for me to read the data being passed to it (actual_records), it would be located under $_POST['???']. I don't think I'm adding the parameters to be passed properly.

Thanks for reading.

funcman
19 Jul 2007, 7:31 AM
Update:

I've tried a different method where the parameters are being sent properly, however the server's response doesn't bring up a download dialog. The response I get is the information inside of the excel document.

Here's what I'm doing:



var conn = new Ext.data.Connection();
conn.request({
method: 'POST',
url: 'export.php',
params: {data: Ext.encode(actual_records)}
});


and my server side code:



// $data holds the excel information

header("Content-type: application/x-msdownload");
header("Content-Disposition: attachment; filename=export-".date('m-d-y').".xls");
header("Pragma: no-cache");
header("Expires: 0");
print "$header\n$data";


Is it possible to bring up a download dialog using this method? Or should I continue with the form submit method.

Wolfgang
20 Jul 2007, 2:38 AM
Maybe this helps you:


if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Transfer-Encoding: binary");
header('Pragma: public');
header("Content-Length: ".strlen($data));
}
else
{
header('Content-Type: "'.$mime.'"');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header("Content-Transfer-Encoding: binary");
header('Expires: 0');
header('Pragma: no-cache');
header("Content-Length: ".strlen($data));
}

echo $data;


Note: i think your response is wrong


print "$header\n$data";

and should be like in my example: $echo $data or print $data.

taelons
29 Jul 2007, 7:36 PM
Hello funcman!

I have a same problem that the download dialog do not appear in Ext client side app
Do you work it out?



pagingCust.add('-', {
text: 'export',
tooltip: 'export to Excel',
cls: 'x-btn-text-icon excel',
handler:function()
{
var conn = new Ext.data.Connection();
conn.request({
method: 'POST',
url: '../getCustList.do?exportexcel=true&fieldList=' + fieldList
//params: { exportexcel: 'true', "fieldList": fieldList}
});
}
});


the followings is java code on server side that can bring up a download dialog in e
non-Ext app



response.setContentType( "application/octet-stream" );
response.setHeader( "Content-Disposition", "attachment; filename=exported.xls" );
HttpListMapping gam = ( HttpListMapping ) mapping;
try
{
OutputStream out = response.getOutputStream();
ExcelUtil.generateExcelFromSql( out, resultBuffer.get( "sql", 0 ).getStringValue(),
"exportedexcel", fieldList, request.getRealPath("/")+RequestUtil.getDefineXML(request)+gam.getXml() );
}
catch ( Exception e )
{
e.printStackTrace();
}

taelons
30 Jul 2007, 12:28 AM
It seem that neither Ext.form.Form nor Ext.data.Connection can download a excel file generated dynamically on server side in a Ext client app, so I use traditional method of putting a hidden <form> tag in html page



<div id="form" class="x-layout-inactive-content">
<form action="../getCustList.do?exportexcel=true" method="POST" name="groupForm">
<input type="hidden" name="fieldList"/>
</form>
</div>




pagingCust.add('-', {
text: 'export,
tooltip: 'export Excel',
cls: 'x-btn-text-icon excel',
handler:function()
{
document.groupForm.fieldList.value = fieldList;
document.groupForm.submit();
/*
var conn = new Ext.data.Connection();
conn.request({
method: 'POST',
url: '../getCustList.do?exportexcel=true&fieldList=' + fieldList
//params: { exportexcel: 'true', "fieldList": fieldList}
});
*/
}
});


It's even easier and work fine with server side java code!
Sometimes we should take leave of ext.

neenhouse
7 Jan 2008, 9:25 AM
pagingCust.add('-', {
text: 'export,
tooltip: 'export Excel',
cls: 'x-btn-text-icon excel',
handler:function()
{
document.groupForm.fieldList.value = fieldList;
document.groupForm.submit();
/*
var conn = new Ext.data.Connection();
conn.request({
method: 'POST',
url: '../getCustList.do?exportexcel=true&fieldList=' + fieldList
//params: { exportexcel: 'true', "fieldList": fieldList}
});
*/
}
});

I tried this method, and it doesn't work for me. The dom form doesn't seem to get the update because the submit sends no parameters. Does this work for anyone else?

AguilaLibre
28 Jan 2009, 2:07 PM
It did work for me, just make sure to add an "id" to the fieldList input since the example has only "name" and no Id. And the javascript is using GetElementById()...

jitu
2 Feb 2009, 11:22 PM
hello
I'm new in extjs
I want to show the progressBar while exporting a grid data insteade of download dilog.....
any help.......
regards..

jitu
5 Feb 2009, 2:03 AM
I want to export grid data into csv format I have a php for this But I want to use progressBar
instead of download dailog.
any guess...