Saturday, November 3, 2012

Grid to Excel export plugin for ExtJS 4

ExtJS has an excellent component Grid Panel to display well structured data. The Grid component may be able to fulfill customer's requirements in most of the cases, but once customer need to do customized calculation on the grid, the may need to export the grid data to their favorite tool, for example, Microsoft Excel, for further process.

With some investigation on internet, this requirement actually existed for a long time, there are 2 main thread on sencha forum:
The discussions have been there for 3 years, but neither of the works well so far, either because of compatibility issues on Ext.JS 4 or bugs in them. I'm not going to discuss more about details, but summarized the 3 ways:
  1. Leverage document data location: set document URL to BASE64 encoded data like: data:application/vnd.ms-excel;base64,... 
    • Pros: pure JavaScript side, no dependency on any 3rd party tools or objects.
    • Cons: the download file cannot be customized, and there are some limitations on encoding UTF-8 to BASE64
  2. Send request to server and generate data stream with specified file format on server.
    • Pros: still pure JavaScript on client side, and developer can choose the file name.
    • Cons: need some work on server side, the code here made it works on JSP.
  3. Use flash Downloadify to generate a file on the fly.
    • Pros: No server side work, user can choose the file name just like a normal download.
    • Cons: depends on flash object.
My version of Ext.ux.Exporter  actually forked the version who use Downloadify, and fixed some defects to make it works on ExtJS 4.1.1a. Here is the code to use it:

  • include script files in html file:
<script type="text/javascript" src="/extjs/src/ux/exporter/swfobject.js"></script>
<script type="text/javascript" src="/extjs/src/ux/exporter/downloadify.min.js"></script>
  • in docedItems list of grid panel, generally on a toolbar, add an item as follows::
{
    xtype: 'exporterbutton'
}
In my implementation, I didn't take time to resolve the excel format issue, instead I use CSV format as default format. What I need is not to keep the exact style when load. I need further processing on data, and a CSV file can fulfill my requirements perfectly.

8 comments:

  1. thx. I have used it successfully. But I have an question: how to change the download image button. I tried to change 'downloadImage' , but it seems not work. Then I try to change the Button.js, result as above. Another question: 'this.getDownloadImage() ' in Button.js where defined it? I can not find it. Please help me .

    ReplyDelete
    Replies
    1. the download image is defined in Button.js under the config

      Delete
  2. Hello, I have a problem if I try to add more than one button on the same window or project and does nothing.

    ReplyDelete
  3. Hi Mason. Thank you for the work, It works pretty good on Chrome and IE. I've been using the plugin like 3 months, yet got a few questions want to check with you.

    1. To show the check column or get rid of action column. I make some changes to the code to show true or false from the store instead of a mess of whole info for the image shown in the grid, but when I want to dig deeper like change to "X" or null in "Worksheet.js", it doesn't work, and I figure out that the "dateFormatString" in "Worksheet.js" doesn't change the time format as well, so I just modify the "Exporter.js" to show the whole store rather than the grid. Hope you may point a way out or give me some direction.

    2. Sometimes the image just disappears if you refresh the browser, and when you refresh again, you may notice the the position becomes white blank. I'm wondering whether you face the problem before or not. If you know the reason, plz let me know.

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. Is there a way to use the export functionality without the button?

    ReplyDelete
  6. hello Mason, this works for me in chrome but have issues in ie (v11) due to size of the url being too large (>2048) . so i keep hitting this wall "The data area passed to a system call is too small." any thoughts on a way to bypass this without a server side request?

    ReplyDelete