1. #1
    Ext User
    Join Date
    Jul 2009
    Posts
    37
    Vote Rating
    0
    DarkStarDS is on a distinguished road

      0  

    Question [SOLVED] Download data from variable with a browser prompt

    [SOLVED] Download data from variable with a browser prompt


    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 :

    Code:
    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 :

    PHP Code:
    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 !

  2. #2
    Sencha User BitPoet's Avatar
    Join Date
    Sep 2008
    Location
    Bavaria
    Posts
    277
    Vote Rating
    1
    BitPoet is on a distinguished road

      0  

    Default


    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.

  3. #3
    Ext User
    Join Date
    Jul 2009
    Posts
    37
    Vote Rating
    0
    DarkStarDS is on a distinguished road

      0  

    Default


    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.

  4. #4
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    89
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    Simple extension:
    Code:
    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:
    Code:
    {
      id: 'report',
      xtype: 'ux.report'
    }
    and use:
    Code:
    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)

  5. #5
    Ext User
    Join Date
    Jul 2009
    Posts
    37
    Vote Rating
    0
    DarkStarDS is on a distinguished road

      0  

    Default


    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 :
    Code:
    {
      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 ?

  6. #6
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    89
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    Anywhere in your layout will do.

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

  7. #7
    Ext User
    Join Date
    Jul 2009
    Posts
    37
    Vote Rating
    0
    DarkStarDS is on a distinguished road

      0  

    Default


    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

  8. #8
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    89
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    Are you sure that all your headers are correct?

    The most important one has a ';' too many:
    Code:
    header( "Content-Disposition: attachment; filename=\"test.csv\";" );

  9. #9
    Ext User
    Join Date
    Jul 2009
    Posts
    37
    Vote Rating
    0
    DarkStarDS is on a distinguished road

      0  

    Default


    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 !

  10. #10
    Sencha User
    Join Date
    Nov 2009
    Posts
    3
    Vote Rating
    0
    esparqui is on a distinguished road

      0  

    Default Method POST

    Method POST


    In this case, the parameters are sent by method GET. How could I send the parameters byt POST using this?

    Thank.