Generate an Excel File from an Ext JS 4 Grid or Store!

(updated on March 19, 2014 to support grouped grids)
(updated on April 3, 2014 to support Microsoft Internet Explorer)
(updated on Nov 16, 2014 to fix various issues with grouping)

Recently I was tasked with building an application whereby the user could export report data contained within a grid to Microsoft Excel. Under normal circumstances, I would have used a server-side approach using ColdFusion’s robust functionality. However, in this particular case, we were using .NET and frankly, I wanted the middleware developer on the project to stay focused on building the core .NET CRUD webservices that were required for the project.

Image

Much to my surprise, after spending a good amount of time googling for a solution, there didn’t seem to be a really dead-simple implementation of a Grid to Excel method for Ext JS 4.

There were several Ext 3 examples available, however. So I ported and enhanced one that I found out there for your enjoyment.

Here’s the result, which I implemented as an override to the grid control. Calling it’s rather quite simple. Just invoke the grid’s downloadExcelXml() method.

 {
   xtype: 'button',
   flex: 1,
   text: 'Download to Excel',
   handler: function(b, e) {
     b.up('grid').downloadExcelXml();
   }
 }

Converting over the Ext 3 code and enhancing it to supply a suggested filename using a new Google Chrome trick, wasn’t quite so simple:

Ext.define('MyApp.view.override.Grid', {
    override: 'Ext.grid.GridPanel',
    requires: 'Ext.form.action.StandardSubmit',

    /*
        Kick off process
    */

    downloadExcelXml: function(includeHidden, title) {

        if (!title) title = this.title;

        var vExportContent = this.getExcelXml(includeHidden, title);

        var location = 'data:application/vnd.ms-excel;base64,' + Base64.encode(vExportContent);

        /* 
          dynamically create and anchor tag to force download with suggested filename 
          note: download attribute is Google Chrome specific
        */

        if (!Ext.isChrome) {
            var gridEl = this.getEl();

            var el = Ext.DomHelper.append(gridEl, {
                tag: "a",
                download: title + "-" + Ext.Date.format(new Date(), 'Y-m-d Hi') + '.xls',
                href: location
            });

            el.click();

            Ext.fly(el).destroy();

        } else {

            var form = this.down('form#uploadForm');
            if (form) {
                form.destroy();
            }
            form = this.add({
                xtype: 'form',
                itemId: 'uploadForm',
                hidden: true,
                standardSubmit: true,
                url: 'http://webapps.figleaf.com/dataservices/Excel.cfc?method=echo&mimetype=application/vnd.ms-excel&filename=' + escape(title + ".xls"),
                items: [{
                    xtype: 'hiddenfield',
                    name: 'data',
                    value: vExportContent
                }]
            });

            form.getForm().submit();

        }
    },

    /*

        Welcome to XML Hell
        See: http://msdn.microsoft.com/en-us/library/office/aa140066(v=office.10).aspx
        for more details

    */
    getExcelXml: function(includeHidden, title) {

        var theTitle = title || this.title;

        var worksheet = this.createWorksheet(includeHidden, theTitle);
        var totalWidth = this.columnManager.columns.length;

        return ''.concat(
            '<?xml version="1.0"?>',
            '<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:html="http://www.w3.org/TR/REC-html40">',
            '<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"><Title>' + theTitle + '</Title></DocumentProperties>',
            '<OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office"><AllowPNG/></OfficeDocumentSettings>',
            '<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">',
            '<WindowHeight>' + worksheet.height + '</WindowHeight>',
            '<WindowWidth>' + worksheet.width + '</WindowWidth>',
            '<ProtectStructure>False</ProtectStructure>',
            '<ProtectWindows>False</ProtectWindows>',
            '</ExcelWorkbook>',

            '<Styles>',

            '<Style ss:ID="Default" ss:Name="Normal">',
            '<Alignment ss:Vertical="Bottom"/>',
            '<Borders/>',
            '<Font ss:FontName="Calibri" x:Family="Swiss" ss:Size="12" ss:Color="#000000"/>',
            '<Interior/>',
            '<NumberFormat/>',
            '<Protection/>',
            '</Style>',

            '<Style ss:ID="title">',
            '<Borders />',
            '<Font ss:Bold="1" ss:Size="18" />',
            '<Alignment ss:Horizontal="Center" ss:Vertical="Center" ss:WrapText="1" />',
            '<NumberFormat ss:Format="@" />',
            '</Style>',

            '<Style ss:ID="headercell">',
            '<Font ss:Bold="1" ss:Size="10" />',
            '<Alignment ss:Horizontal="Center" ss:WrapText="1" />',
            '<Interior ss:Color="#A3C9F1" ss:Pattern="Solid" />',
            '</Style>',


            '<Style ss:ID="even">',
            '<Interior ss:Color="#CCFFFF" ss:Pattern="Solid" />',
            '</Style>',


            '<Style ss:ID="evendate" ss:Parent="even">',
            '<NumberFormat ss:Format="yyyy-mm-dd" />',
            '</Style>',


            '<Style ss:ID="evenint" ss:Parent="even">',
            '<Numberformat ss:Format="0" />',
            '</Style>',

            '<Style ss:ID="evenfloat" ss:Parent="even">',
            '<Numberformat ss:Format="0.00" />',
            '</Style>',

            '<Style ss:ID="odd">',
            '<Interior ss:Color="#CCCCFF" ss:Pattern="Solid" />',
            '</Style>',

            '<Style ss:ID="groupSeparator">',
            '<Interior ss:Color="#D3D3D3" ss:Pattern="Solid" />',
            '</Style>',

            '<Style ss:ID="odddate" ss:Parent="odd">',
            '<NumberFormat ss:Format="yyyy-mm-dd" />',
            '</Style>',

            '<Style ss:ID="oddint" ss:Parent="odd">',
            '<NumberFormat Format="0" />',
            '</Style>',

            '<Style ss:ID="oddfloat" ss:Parent="odd">',
            '<NumberFormat Format="0.00" />',
            '</Style>',


            '</Styles>',
            worksheet.xml,
            '</Workbook>'
        );
    },

    /*

        Support function to return field info from store based on fieldname

    */

    getModelField: function(fieldName) {

        var fields = this.store.model.getFields();
        for (var i = 0; i < fields.length; i++) {
            if (fields[i].name === fieldName) {
                return fields[i];
            }
        }
    },

    /*
        
        Convert store into Excel Worksheet

    */
    generateEmptyGroupRow: function(dataIndex, value, cellTypes, includeHidden) {


        var cm = this.columnManager.columns;
        var colCount = cm.length;
        var rowTpl = '<Row ss:AutoFitHeight="0"><Cell ss:StyleID="groupSeparator" ss:MergeAcross="{0}"><Data ss:Type="String"><html:b>{1}</html:b></Data></Cell></Row>';
        var visibleCols = 0;

        // rowXml += '<Cell ss:StyleID="groupSeparator">'

        for (var j = 0; j < colCount; j++) {
            if (cm[j].xtype != 'actioncolumn' && (cm[j].dataIndex != '') && (includeHidden || !cm[j].hidden)) {
                // rowXml += '<Cell ss:StyleID="groupSeparator"/>';
                visibleCols++;
            }
        }

        // rowXml += "</Row>";

        return Ext.String.format(rowTpl, visibleCols - 1, value);
    },


    createWorksheet: function(includeHidden, theTitle) {
        // Calculate cell data types and extra class names which affect formatting
        var cellType = [];
        var cellTypeClass = [];
        var cm = this.columnManager.columns;

        var totalWidthInPixels = 0;
        var colXml = '';
        var headerXml = '';
        var visibleColumnCountReduction = 0;
        var colCount = cm.length;
        for (var i = 0; i < colCount; i++) {
            if (cm[i].xtype != 'actioncolumn' && (cm[i].dataIndex != '') && (includeHidden || !cm[i].hidden)) {
                var w = cm[i].getEl().getWidth();
                totalWidthInPixels += w;

                if (cm[i].text === "") {
                    cellType.push("None");
                    cellTypeClass.push("");
                    ++visibleColumnCountReduction;
                } else {
                    colXml += '<Column ss:AutoFitWidth="1" ss:Width="' + w + '" />';
                    headerXml += '<Cell ss:StyleID="headercell">' +
                        '<Data ss:Type="String">' + cm[i].text + '</Data>' +
                        '<NamedCell ss:Name="Print_Titles"></NamedCell></Cell>';


                    var fld = this.getModelField(cm[i].dataIndex);
                    switch (fld.type.type) {
                        case "int":
                            cellType.push("Number");
                            cellTypeClass.push("int");
                            break;
                        case "float":
                            cellType.push("Number");
                            cellTypeClass.push("float");
                            break;

                        case "bool":

                        case "boolean":
                            cellType.push("String");
                            cellTypeClass.push("");
                            break;
                        case "date":
                            cellType.push("DateTime");
                            cellTypeClass.push("date");
                            break;
                        default:
                            cellType.push("String");
                            cellTypeClass.push("");
                            break;
                    }
                }
            }
        }
        var visibleColumnCount = cellType.length - visibleColumnCountReduction;

        var result = {
            height: 9000,
            width: Math.floor(totalWidthInPixels * 30) + 50
        };

        // Generate worksheet header details.

        // determine number of rows
        var numGridRows = this.store.getCount() + 2;
        if (!Ext.isEmpty(this.store.groupField) || this.store.groupers.items.length > 0) {
            numGridRows = numGridRows + this.store.getGroups().length;
        }

        // create header for worksheet
        var t = ''.concat(
            '<Worksheet ss:Name="' + theTitle + '">',

            '<Names>',
            '<NamedRange ss:Name="Print_Titles" ss:RefersTo="=\'' + theTitle + '\'!R1:R2">',
            '</NamedRange></Names>',

            '<Table ss:ExpandedColumnCount="' + (visibleColumnCount + 2),
            '" ss:ExpandedRowCount="' + numGridRows + '" x:FullColumns="1" x:FullRows="1" ss:DefaultColumnWidth="65" ss:DefaultRowHeight="15">',
            colXml,
            '<Row ss:Height="38">',
            '<Cell ss:MergeAcross="' + (visibleColumnCount - 1) + '" ss:StyleID="title">',
            '<Data ss:Type="String" xmlns:html="http://www.w3.org/TR/REC-html40">',
            '<html:b>' + theTitle + '</html:b></Data><NamedCell ss:Name="Print_Titles">',
            '</NamedCell></Cell>',
            '</Row>',
            '<Row ss:AutoFitHeight="1">',
            headerXml +
            '</Row>'
        );

        // Generate the data rows from the data in the Store
        var groupVal = "";
        var groupField = "";
        if (this.store.groupers.keys.length > 0) {
            groupField = this.store.groupers.keys[0];
        }
        for (var i = 0, it = this.store.data.items, l = it.length; i < l; i++) {

            if (!Ext.isEmpty(groupField)) {
                if (groupVal != this.store.getAt(i).get(groupField)) {
                    groupVal = this.store.getAt(i).get(groupField);
                    t += this.generateEmptyGroupRow(groupField, groupVal, cellType, includeHidden);
                }
            }
            t += '<Row>';
            var cellClass = (i & 1) ? 'odd' : 'even';
            r = it[i].data;
            var k = 0;
            for (var j = 0; j < colCount; j++) {
                if (cm[j].xtype != 'actioncolumn' && (cm[j].dataIndex != '') && (includeHidden || !cm[j].hidden)) {
                    var v = r[cm[j].dataIndex];
                    if (cellType[k] !== "None") {
                        t += '<Cell ss:StyleID="' + cellClass + cellTypeClass[k] + '"><Data ss:Type="' + cellType[k] + '">';
                        if (cellType[k] == 'DateTime') {
                            t += Ext.Date.format(v, 'Y-m-d');
                        } else {
                            t += v;
                        }
                        t += '</Data></Cell>';
                    }
                    k++;
                }
            }
            t += '</Row>';
        }

        result.xml = t.concat(
            '</Table>',
            '<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">',
            '<PageLayoutZoom>0</PageLayoutZoom>',
            '<Selected/>',
            '<Panes>',
            '<Pane>',
            '<Number>3</Number>',
            '<ActiveRow>2</ActiveRow>',
            '</Pane>',
            '</Panes>',
            '<ProtectObjects>False</ProtectObjects>',
            '<ProtectScenarios>False</ProtectScenarios>',
            '</WorksheetOptions>',
            '</Worksheet>'
        );
        return result;
    }
});

The server-side code used to echo the generated spreadsheet back to the browser and force a “download” operation is the following:

<cfcomponent>

 <cffunction name="echo" access="remote" returntype="void">

 <cfargument name="mimetype" type="string" required="no" default="text/html">
 <cfargument name="filename" type="string" required="yes">
 <cfargument name="data" type="string" required="no" default="">

 <cfif isdefined("form.data")>
 <cfset arguments.data = form.data>
 </cfif>

 <cfheader name="Content-Disposition" value="attachment; filename=#arguments.filename#">

 <cfcontent type="#arguments.mimetype#"><cfoutput>#arguments.data#</cfoutput>

 </cffunction>

</cfcomponent>

Note that the ColdFusion-based “echo” webservice is available for evaluation/testing purposes only. No warranty or level of service is expressed or implied.

You can play around with the code on Sencha Fiddle:
https://fiddle.sencha.com/#fiddle/17j

Go check it out!

83 thoughts on “Generate an Excel File from an Ext JS 4 Grid or Store!

  1. Jonathan

    Great work ! I have grouped columns (e.g Personal data has 3 columns name, age, address ) … would it be posible to show them in the excel file ?

    can you point me in the right direction?

    Reply
  2. Jonathan

    Hi, I ‘ve implemented this UX but I have a big problem it just doesn’t work in IE at all not even IE10.

    The message error is: “the data area passed to a system call is too small”

    And the lines that seems to cause the error are :

    el.click();

    Ext.fly(el).destroy();

    Any ideas ?

    Reply
  3. Jonathan Caballero

    Sdrucker,

    I have a doubt about the ux…

    I have a ‘datecloumn ‘ in my grid with a ‘format’ config to render dates in a specific way, but that is breaking the generation of the Excel file …

    Are ‘datecolum’ supported ? is ‘format’ config supported ?

    Thank you in advance.

    Reply
    1. FĂ¡tima

      Hi Jonathan…. do you know if the datecolumn are supported yet? The error is <>, and the codeline is ” t += v.format(‘Y-m-d’); “, where “v” is datetime (example: Mon Feb 03 2014 00:00:00 GMT+0000 (Hora estĂ¡ndar GMT))… thanks!

      Reply
  4. Steve Steele

    Steve,

    It works great, one suggestion would be to change this.columns to this.getView().getGridColumns() so excel would match the user’s current view (moved/hidden columns or sorting) instead of the default view.

    Thanks for the help!

    Reply
  5. benny

    hello,
    i’m new in working with ExtJs and need this export-function for a project.
    is it possible to create a button out of the toolbar from grid to call the ‘export to excel’-function? i tried this in sencha-fiddle, but didn’t work. Who can help me?

    Reply
    1. sdrucker Post author

      I’ve been busy with client work. Haven’t had a chance to look at it. The general consensus is that there’s no fix for IE (other than posting the data back to an app server and have the app server transmit it back to the browser)

      Reply
  6. Kiran

    Thanks for sharing the code. Do you know what is the alternative to ‘download’ attribute so it would work in IE?

    var el = Ext.DomHelper.append(gridEl, {
    tag : “a”,
    download: title + “-” + Ext.Date.format(new Date(), ‘Y-m-d Hi’) + ‘.xls’,
    href: location
    });

    I am assuming it is due to ‘download’ attribute, or some one else pointed out it was a limitation on how much data that we can put in ‘href in IE.

    Reply
  7. arun

    Please tell me how to export grouped columns data grid in existing export example. i want to change any modification in that code r what?…..Please reply that..

    Reply
  8. mattlink03

    anyone have the solution for the IE and safari; and a solution for the templatecolumns and grouped columns, anyone keep working with this features?

    Reply
  9. Jonathan Caballero @code4jhon

    I’ve abondoned trying to generate an Excel from an ExtJs grid but I think there are some work arounds pretty helpful (IMO):

    1.- Copy the content of your STORE (not grid) to clipboard and paste it to Excel.http://www.rahulsingla.com/blog/2010/03/extjs-copy-gridpanel-content-to-clipboard

    2.- Print your Grid to an html page (for printting porpouses) and copy & paste to Excel http://loianegroner.com/2011/09/extjs-4-grid-printer-plugin/

    3.- Simply make your server generate a CSV

    best regards

    Reply
  10. Pingback: Generate an Excel File from an Ext JS 4 Grid or Store (Version 1.1) | Druck-I.T.

    1. sdrucker Post author

      Yes, I’ve implemented it in Architect.

      All you need to do is add an application loader config to point to an Ext.ux folder, e.g.:

      Ext.Loader.setConfig({
      enabled: true,
      paths: {
      ‘Ext.ux’: ‘app/ux’
      }
      });

      And then reference the override from your application’s REQUIRES property.

      Reply
  11. Arnold Villasanta

    Thanks for the share Steve. It works.

    One thing I noticed is that the grouping name always takes what is defined in the STORE (groupfield). I have a 40-column grid with 5 fields are group-enabled. Whatever field I choose to be the GROUPING field, the xsl file always uses the one defined in the STORE.
    Is there a way to make the group name as what is currently selected in the GridPanel?

    Reply
    1. Arnold Villasanta

      Hi Steve,

      I’ve created some changes in the createWorksheet().
      The changes enables the function to look into the Grid’s grouping at runtime, rather than referencing the Store’s groupfield. (I used store.groupers.first().property).
      I also created 2 variables, groupPreLabel and groupLabel to replace the Store’s group template (groupTpl) at some point.

      Here is the complete createWorksheet() code:

      // Calculate cell data types and extra class names which affect formatting
      var cellType = [];
      var cellTypeClass = [];
      var cm = this.columns;

      var totalWidthInPixels = 0;
      var colXml = ”;
      var headerXml = ”;
      var visibleColumnCountReduction = 0;
      var colCount = cm.length;

      // Arnold – for Group Label correction (1)
      var groupPreLabel = ”;
      var groupLabel = ”;
      // -end (1

      for (var i = 0; i < colCount; i++) {

      //Arnold – for Group Label correction (2)
      if (!Ext.isEmpty(this.store.groupers.first().property)) {
      if (this.store.groupers.first().property == cm[i].dataIndex) {
      groupPreLabel = cm[i].text + ": ";
      console.log('Group Pre Label = ' + cm[i].text);
      }
      }
      // – end (2)

      if (cm[i].xtype != 'actioncolumn' && (cm[i].dataIndex !== '') && (includeHidden || !cm[i].hidden)) {
      var w = cm[i].getEl().getWidth();
      totalWidthInPixels += w;

      if (cm[i].text === "") {
      cellType.push("None");
      cellTypeClass.push("");
      ++visibleColumnCountReduction;
      } else {
      colXml += '’;
      headerXml += ” +
      ” + cm[i].text + ” +
      ”;

      var fld = this.getModelField(cm[i].dataIndex);
      switch (fld.type.type) {
      case “int”:
      cellType.push(“Number”);
      cellTypeClass.push(“int”);
      break;
      case “float”:
      cellType.push(“Number”);
      cellTypeClass.push(“float”);
      break;

      case “bool”:

      case “boolean”:
      cellType.push(“String”);
      cellTypeClass.push(“”);
      break;
      case “date”:
      cellType.push(“DateTime”);
      cellTypeClass.push(“date”);
      break;
      default:
      cellType.push(“String”);
      cellTypeClass.push(“”);
      break;
      }
      }
      }
      }
      var visibleColumnCount = cellType.length – visibleColumnCountReduction;

      var result = {
      height: 9000,
      width: Math.floor(totalWidthInPixels * 30) + 50
      };

      // Generate worksheet header details.

      // determine number of rows
      var numGridRows = this.store.getCount() + 2;

      //Arnold – for Group Label correction (3)
      //if (!Ext.isEmpty(this.store.groupField)) {
      if (!Ext.isEmpty(this.store.groupers.first().property)) {
      // end (3)
      numGridRows = numGridRows + this.store.getGroups().length;
      }

      // create header for worksheet
      var t = ”.concat(
      ”,

      ”,
      ”,
      ”,

      ”,
      colXml,
      ”,
      ”,
      ”,
      ” + theTitle + ”,
      ”,
      ”,
      ”,
      headerXml +

      );

      // Generate the data rows from the data in the Store
      var groupVal = “”;

      for (var i = 0, it = this.store.data.items, l = it.length; i < l; i++) {

      //Arnold – for Group Label correction (4)
      //if (!Ext.isEmpty(this.store.groupField)) {
      if (!Ext.isEmpty(this.store.groupers.first().property)) {

      //if (groupVal != this.store.getAt(i).get(this.store.groupField)) {
      // groupVal = this.store.getAt(i).get(this.store.groupField);
      if (groupVal != this.store.getAt(i).get(this.store.groupers.first().property)) {
      groupVal = this.store.getAt(i).get(this.store.groupers.first().property);

      //t += this.generateEmptyGroupRow(this.store.groupField, groupVal, cellType, includeHidden);
      groupLabel = groupPreLabel + groupVal;
      console.log('Group Label = ' + groupLabel);
      t += this.generateEmptyGroupRow(this.store.groupers.first().property, groupLabel, cellType, includeHidden);
      //end (4)
      }
      }
      t += '’;
      var cellClass = (i & 1) ? ‘odd’ : ‘even’;
      r = it[i].data;
      var k = 0;
      for (var j = 0; j < colCount; j++) {
      if (cm[j].xtype != 'actioncolumn' && (cm[j].dataIndex !== '') && (includeHidden || !cm[j].hidden)) {
      var v = r[cm[j].dataIndex];
      if (cellType[k] !== "None") {
      t += '’;
      if (cellType[k] == ‘DateTime’) {
      t += Ext.Date.format(v, ‘Y-m-d’);
      } else {
      t += v;
      }
      t += ”;
      }
      k++;
      }
      }
      t += ”;
      }

      result.xml = t.concat(
      ”,
      ”,
      ‘0’,
      ”,
      ”,
      ”,
      ‘3’,
      ‘2’,
      ”,
      ”,
      ‘False’,
      ‘False’,
      ”,

      );
      return result;

      Reply
      1. Arnold Villasanta

        Please replace:
        if (!Ext.isEmpty(this.store.groupers.first().property)) {
        with:
        if (!Ext.isEmpty(this.store.groupers.first())) {

        The first one is undefined (.property)

        Thanks.

  12. michhasi

    Hi. sometimes, I couldn’t connect with internet. in that time, impossible download excel file in IE10.

    How can I download excel file, when I couldn’t connect internet.

    Reply
    1. arnold villasana

      In your ‘local’ computer/server, copy/paste the code for the download request callback (provided by the author)… or create your own in php/java. The remote site/page provided by author has a disclaimer for service guarantee and is intended only for testing.

      Reply
  13. Madhan Kumar

    It is not working in IE11. I am getting this in console of IE.

    (Error showing in console: The data area passed to a system call is too small)

    Reply
    1. Madhan Kumar

      In chrome version Version 35.0.1916.114 m. Downloaded Excel file name has ‘download’ not getting the actual file name.

      Reply
    1. sdrucker Post author

      Why are you loading that many records into a store?

      My guess is that you’re overflowing the browser’s ability to handle that much generated XML. You’ll need to look at using a server-side solution for large-scale spreadsheet generation. Try looking at POI: http://poi.apache.org/

      Reply
  14. Vikram

    can we import the renderer function value in excel ??

    e.g.:-
    renderer: function renderTip(value, metadata, dataRecord) {
    if (value > 100) {
    return value = value.substr( parseInt( value.lastIndexOf( “AB=” ) ) + 3 ); return value;;
    } else {
    return value;
    }
    },

    Reply
  15. Steve

    Hi Sdrucker Could you please help me export to excel with multi columns grouping, thanks in advance

    Reply
  16. Pingback: ExtJs4 Producing an Excel document from javascript in IE gets me:”the information area passed to some method call is too little” | CodersDiscuss.com

  17. Thomas SJ

    If you want to download excel with column order in view(screen) need change like below.
    var cm = this.columns; => car cm = this.getView().getGridColumns();

    Reply
  18. vmrao

    Very nice article. Can the server-side code to echo the download file be updated to use JSP ? If anyone has already converted the ColdFusion code to JSP, can you please post here.

    Reply
  19. Austin.Kim

    I finally was able to implement your code and is working great!

    Only thing I need is GroupSummary part. Would you be able to guide me where to modify so GroupSummary is included in this plugin?

    Btw, thanks for ExtJS 5 meetup!

    Reply
  20. Shrek.W

    Good work! Have you ever come across with showing check columns in excel? It is nasty if you have a check column to show in excel file.

    Reply
  21. Andrew

    I need to be able to export to xlsx format. From what I can tell the formats are very different. Is there anyway to export the grid as an xlsx or maybe convert to xlsx programmatically?

    Reply
    1. sdrucker Post author

      .xslx is essentially a .zip file that contains xml documents. It’s not something that you can really create very easily using client-side JavaScript. If I had that as a client requirement, I’d implement a server-side solution using functionality built into ColdFusion (cfspreadsheet/cfzip) or POI (http://poi.apache.org/)

      Reply
  22. Oxii

    Hi, Thanks for your post and demo
    I followed your instructions but then at [var location = ‘data:application/vnd.ms-excel;base64,’ + Base64.encode(vExportContent);] I get this error: [Base64 is not defined] If replace it with [var location = ‘data:application/vnd.ms-excel;base64,’;] I get an empty excel file. Any idea?

    Reply
  23. newjsnewjs

    Double click the generated .xls file from MSFT Excel 2007, gives a initial message “The file you are trying to open .. is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source….” Click Yes, the file opens file. Is there a way to get around with this? Thanks! It’s a beautiful implementation, saved me a lot of time.

    Reply
  24. newjs

    Double click the generated xls file, get a warning message. “The file you are trying to open, ‘name.ext’, is in a different format than specified by the file extension. Verify that the file is not corrupted and is from a trusted source before opening the file. Do you want to open the file now?” Click Yes, opens fine. Is there a way to get around with it? Thanks!

    Reply
  25. felix822

    Thanks for sharing this code! I’m also getting the Excel warning file. How hard would it be to create a CSV file instead of and XLS with this code?

    Reply
      1. akonisiya

        Sir sdrucker, i tried your Upgraded code for ExtJS 5. it is good and working but it would be open only in LibreOffice excel..there was an error when i open it in MSExcel2007++. what should i do for this? need help..thanks

  26. akonisiya

    the downloaded file is in 1997-2003 excel type. i want to change the type format to MicrosoftExcel2013. it is possible Mr. Druck?

    Reply
    1. sdrucker Post author

      The ColdFusion code has been provided. It looks like WordPress had escaped some of the code, so I’ve fixed that.
      All it’s doing is just transmitting the data received from “data” form post and sending it back to the browser with a custom http header.

      Reply
  27. Sam the Eagle

    Hi, works very nice, I do have one question though; Is there any way to get the grid all rows, if I have lets say a grid with 500 rows in total and I show only 30 per page, now I get only 30 with this approach, how can I get them all?

    Reply
  28. Samuel Mikey Martin

    Hey guys, I would like to know if there is a possibility to create multiple sheets within an excel sheet. I have been able to download an excel with a sheet. Not sure on how to do for multiple sheets?

    Reply
  29. Samuel Mikey Martin

    Hey Guys, Is there any possibility to have more than one sheet? I’m able to download an excel with one sheet and I would like to download more sheets? Any suggestions

    Reply
  30. Rakin

    Many thanks. I have implemented it and it works fantastic.
    Now, how could I export grid data to PDF in the same manner ? I

    Reply

Leave a reply to Austin.Kim Cancel reply