Flex 2 – Export Datagrid To Excel

I recently came across the problem of exporting Datagrid data to an Excel sheet.

Research on the internet brought me to a post on cflex where an solution was presented for Flex < 2.
Together with a (half-visual) comment posted there I refactored the code so that it would be applicable to Flex 2 (And didn’t need to work through the clipboard, since in my opinion this would work only half the time (browser security)).

The following Actionscript code is used for converting the Datagrid to an Excel file and then passing it on to an external Excel exporter:

  1. <mx:Script>
  2. <![CDATA[
  3. /**
  4. * Simple script to convert a Datagrid to a HTML table and then
  5. * pass it on to an external excel exporter
  6. *
  7. * @author: S.Radovanovic (With help of Tracy Spratt through the post on
  8. * http://www.cflex.net/showFileDetails.cfm?ObjectID=298&Object=File&ChannelID=1)
  9. */
  10.  
  11. //Libs that are mostly used
  12. //(only a number are necessary for the datagrid conversion and export)
  13. import mx.controls.Alert;
  14. import mx.core.UIComponent;
  15. import mx.core.Container;
  16. import mx.events.ItemClickEvent;
  17. import mx.utils.ObjectProxy;
  18. import flash.errors.*;
  19. import flash.events.*;
  20. import flash.external.*;
  21. import flash.net.URLLoader;
  22. import flash.net.URLVariables;
  23. import flash.net.URLRequest;
  24.  
  25. //The location of the excel export file
  26. public var urlExcelExport:String = "/yourpath/excelexport.php";
  27.  
  28.  
  29. /**
  30. * Convert the datagrid to a html table
  31. * Styling etc. can be done externally
  32. *
  33. * @param: dg Datagrid Contains the datagrid that needs to be converted
  34. * @returns: String
  35. */
  36. private function convertDGToHTMLTable(dg:DataGrid):String {
  37. //Set default values
  38. var font:String = dg.getStyle('fontFamily');
  39. var size:String = dg.getStyle('fontSize');
  40. var str:String = '';
  41. var colors:String = '';
  42. var style:String = 'style="font-family:'+font+';font-size:'+size+'pt;"';
  43. var hcolor:Array;
  44.  
  45. //Retrieve the headercolor
  46. if(dg.getStyle("headerColor") != undefined) {
  47. hcolor = [dg.getStyle("headerColor")];
  48. } else {
  49. hcolor = dg.getStyle("headerColors");
  50. }
  51.  
  52. //Set the htmltabel based upon knowlegde from the datagrid
  53. str+= '<table width="'+dg.width+'"><thead><tr width="'+dg.width+'" style="background-color:#' +Number((hcolor[0])).toString(16)+'">';
  54.  
  55. //Set the tableheader data (retrieves information from the datagrid header
  56. for(var i:int = 0;i<dg.columns.length;i++) {
  57. colors = dg.getStyle("themeColor");
  58.  
  59. if(dg.columns[i].headerText != undefined) {
  60. str+="<th "+style+">"+dg.columns[i].headerText+"</th>";
  61. } else {
  62. str+= "<th "+style+">"+dg.columns[i].dataField+"</th>";
  63. }
  64. }
  65. str += "</tr></thead><tbody>";
  66. colors = dg.getStyle("alternatingRowColors");
  67.  
  68. //Loop through the records in the dataprovider and
  69. //insert the column information into the table
  70. for(var j:int =0;j<dg.dataProvider.length;j++) {
  71. str+="<tr width=\""+Math.ceil(dg.width)+"\">";
  72.  
  73. for(var k:int=0; k < dg.columns.length; k++) {
  74.  
  75. //Do we still have a valid item?
  76. if(dg.dataProvider.getItemAt(j) != undefined && dg.dataProvider.getItemAt(j) != null) {
  77.  
  78. //Check to see if the user specified a labelfunction which we must
  79. //use instead of the dataField
  80. if(dg.columns[k].labelFunction != undefined) {
  81. str += "<td width=\""+Math.ceil(dg.columns[k].width)+"\" "+style+">"+dg.columns[k].labelFunction(dg.dataProvider.getItemAt(j),dg.columns[k].dataField)+"</td>";
  82.  
  83. } else {
  84. //Our dataprovider contains the real data
  85. //We need the column information (dataField)
  86. //to specify which key to use.
  87. str += "<td width=\""+Math.ceil(dg.columns[k].width)+"\" "+style+">"+dg.dataProvider.getItemAt(j)[dg.columns[k].dataField]+"</td>";
  88. }
  89. }
  90. }
  91. str += "</tr>";
  92. }
  93. str+="</tbody></table>";
  94.  
  95. return str;
  96. }
  97.  
  98. /**
  99. * Load a specific datagrid into Excel
  100. * This method passes the htmltable string to an backend script which then
  101. * offers the excel download to the user.
  102. * The reason for not using a copy to clipboard and then javascript to
  103. * insert it into Excel is that this mostly will fail because of the user
  104. * setup (Webbrowser configuration).
  105. *
  106. * @params: dg Datagrid The Datagrid that will be loaded into Excel
  107. */
  108. private function loadDGInExcel(dg:DataGrid):void {
  109.  
  110. //Pass the htmltable in a variable so that it can be delivered
  111. //to the backend script
  112. var variables:URLVariables = new URLVariables();
  113. variables.htmltable = convertDGToHTMLTable(dg);
  114.  
  115. //Setup a new request and make sure that we are
  116. //sending the data through a post
  117. var u:URLRequest = new URLRequest(urlExcelExport);
  118. u.data = variables; //Pass the variables
  119. u.method = URLRequestMethod.POST; //Don't forget that we need to send as POST
  120.  
  121. //Navigate to the script
  122. //We can use _self here, since the script will through a filedownload header
  123. //which results in offering a download to the user (and still remaining in you Flex app.)
  124. navigateToURL(u,"_self");
  125. }
  126. ]]>
  127. </mx:Script>

Download code

The code to export the data to Excel is fairly simple.
I’ve written it in PHP, but it can be written in any language.

  1. <?php
  2. /**
  3. * Export data, delivered in the POST, to excel.
  4. *
  5. * @author S.Radovanovic
  6. * @version $Id$
  7. */
  8. header('ETag: etagforie7download'); //IE7 requires this header
  9. header('Content-type: application/octet_stream');
  10. header('Content-disposition: attachment; filename="rapportage.xls"');
  11.  
  12. //Add html tags, so that excel can interpret it
  13. echo "<html>
  14. <body>
  15. ".stripslashes($_POST["htmltable"])."
  16. </body>
  17. </html>
  18. ";
  19. ?>

Download code

60 Responses to “Flex 2 – Export Datagrid To Excel”

  1. Jason says:

    UPDATE: POST variable to big resolved

    I increased the post variable limit and the script memory use limit in my php.ini file and could then export a 5,000 record dataset.

  2. Garra says:

    Jason;
    could you tell where did you modified php.ini for many rows?
    thanks.

    do yoy know if the version of the code here in site is the last one?

    thanks to tell me where could i find the last version of the code.
    thanks a lot
    regards
    Garra

  3. Garra says:

    For utf-8 charset you can do:

    /*
    echo ‘

    ‘.stripslashes($_POST["htmltable"]).’

    ‘;
    */

  4. Garra says:

    sorry, i think that last comment did not appear in good form, because of PHP code; but you can use content type for utf-8 charset

  5. Chetan says:

    Hello,
    Thanks a lot for the code!

    I was able to extend this solution for AdvancedDataGrid, will try to post it after some cleanup.

  6. mohd says:

    Hi everyone

    I tried using the given code with AdvanceDatagrid ….I received the follwing error

    Property getItemAt not found on mx.collections.HierarchicalCollectionView and there is no default value.”

    When I debug the program it seems like there is no property by name .getItemAt() for dataProvider of Advance DataGrid…………..

    Any one Pls……………..Help……….

  7. mohd says:

    Hi Chetan

    If you can pls upload the code ………..Thanks

  8. Sanjay says:

    @Chetan,

    Not really the code, but could u just give an idea as of how u did extend it for ADG .. obviously the code will save my efforts in case u publish the same. Thanks in advance.

  9. [...] In Flex 3, in order to upload a file you need a small script on the server (in Flex 4/Flash 10 the client is able to handle this locally). Included in the source you’ll find two PHP files: csvImport.php and csvExport.php. To support exporting the data from the DataGrid I’m leveraging a nice algorithm written by Sasa Radovanovic explained in this post. [...]

  10. Iwan P says:

    hi Chetan,

    how we modify

    /*
    echo ‘

    ‘.stripslashes($_POST["htmltable"]).’

    ‘;
    */

    to classic asp…
    pls, thank

Leave a Reply