开发者

EXTJs Export to excel in IE8

extjs Gridpanel Export to excel is working fine in both Firefox and 开发者_如何学编程Chrome but not IE (even IE8 also)

Please provide suggestions

Thanks in advance


I have compiled a sort of plugin for grids in ExtJS 4. It helps you to make both a printable version and Export to Excel. It exports exactly what you see and it works with column renderers as well. Include this script:

/**
 * Export grid data. Based on:
 * http://www.sencha.com/forum/showthread.php?125611-data-download-function-from-Grid-and-Chart
 * http://www123.ddo.jp/grid/array-grid.js
 * http://edspencer.net/2009/07/extuxprinter-printing-for-any-ext.html
 * @param {Object} opt (optional)
 *   format: 'html',
 *   headers: true,
 *   stylesheetPath: 'css/print.css'
*/
Ext.grid.GridPanel.prototype.exportData = function(opt){
    opt=opt||{};

    //Get the array of columns from a grid
    var me=this, columns=[], data=[];
    Ext.each(me.columns, function(col) {
        if (col.hidden != true && col.dataIndex) columns.push(col);
    });
    //Sometimes there's no colum header text (when using icons)
    Ext.each(columns, function(column) {
        if (!column.text || column.text == ' ') {
            column.text=column.dataIndex;
        }
    });

    //Build a useable array of store data for the XTemplate
    me.store.data.each(function(item) {
        var convertedData = {};

        //apply renderers from column model
        Ext.iterate(item.data, function(key, value) {
            Ext.each(columns, function(column) {
                if (column.dataIndex == key) {
                    if (column.renderer) {
                        if (column.xtype==='templatecolumn') {
                            convertedData[key] = column.renderer(value, {}, item);
                        } else {
                            convertedData[key] = column.renderer(value, undefined, undefined, undefined, columns.indexOf(column), undefined, me.view);
                        }
                    } else {
                        convertedData[key] =  value;
                    }
                    if (typeof convertedData[key]==='string') {
                        convertedData[key]=Ext.util.Format.htmlToText(convertedData[key]);
                    }
                    return false;
                }
            });
        });

        data.push(convertedData);
    });

    //generate finale template to be applied with the data
    var headings=[], body=[], str;
    if (opt.format==="html") {
        headings=opt.headers?new Ext.XTemplate(
            '<tr>',
              '<tpl for=".">',
                '<th>{text}</th>',
              '</tpl>',
            '</tr>'
        ).apply(columns):'';
        body=new Ext.XTemplate(
            '<tr>',
              '<tpl for=".">',
                '<td>\{{dataIndex}\}</td>',
              '</tpl>',
            '</tr>'
        ).apply(columns);

        var str=[
            '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">',
            '<html>',
              '<head>',
                '<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />',
                opt.stylesheetPath?'<link href="' + opt.stylesheetPath + '" rel="stylesheet" type="text/css" media="screen,print" />':'',
                me.title?'<title>' + me.title + '</title>':'',
              '</head>',
              '<body>',
                '<table>',
                Ext.String.format('{0}\n<tpl for=".">{1}\n</tpl>', headings, body),
                '</table>',
              '</body>',
            '</html>'
        ].join('\n');
    } else {
        Ext.each(columns, function(v) {
            headings.push(Ext.util.Format.htmlToText(v.text));
            body.push('{'+v.dataIndex+'}');
        });
        headings=opt.headers?headings.join('\t'):'';
        body    =body.join('\t');

        var str=Ext.String.format('{0}\n<tpl for=".">{1}\n</tpl>', headings, body);
    }

    //console.log('toText', columns, data, headings, body, str);
    return new Ext.XTemplate(str).apply(data);
};

Now, print a grid like so:

var html=grid.exportData({
    format: 'html',
    headers: true,
    stylesheetPath: 'resources/css/print.css'
});

var name = grid.getXType ? Ext.String.format("print_{0}_{1}", grid.getXType(), grid.id) : "print";

name=name.replace(/\W*/g, ''); //IE disallows spaces and other special characters in window name (the second argument). You need to remove them before passing as argument.

var win = window.open(undefined, name);
win.document.write(html);
win.document.close();
win.print();

An export to Excel requires that you export the grid to a tab delimited string. That string you post to the server (download.php)

var html=grid.exportData({
    format: 'txt',
    headers: true,
    stylesheetPath: 'resources/css/print.css'
});

var form = Ext.DomHelper.append(document.body, {
    tag: 'form',
    style: 'display:none',
    action: 'download.asp',
    method: 'post',
    cn:[{
        tag:'textarea',
        name:'body',
        html:html
    },{
        tag:'input',
        name:'filename',
        value: grid.title||'download'
    },{
        tag:'input',
        name:'extension',
        value:'xls'
    }]
});
form.submit();
document.body.removeChild(form);

Then download.php would needs to echo out the posted body. Use:

Content-Disposition=attachment;filename=file.xls
Content-Type=application/vnd.ms-excel

Now, your browser should show the prompt that asks you to save the xls file.


I made a small modification to the code in the library Ext.ux.Exporter, changing this:

this.getEl().child('a', true).href = 'data:application/vnd.ms-excel;base64,' + Ext.ux.Exporter[config.exportFunction](this.component, null, config);

by this:

var domA = this.getEl().child('a', true),
            string64 = Ext.ux.Exporter[config.exportFunction](this.component, null, config);

        domA.href = '#';
        domA.rel = string64;

        this.getEl().child('a').addListener( {
            'click':{
                fn: function(){
                    __exportExcel(this.getEl().child('a', true).rel);
                },
                scope: this
            }
        });

Then using the "dirty" function __exportExcel

__exportExcel = function(base64){

    Ext.DomHelper.useDom = true;
    var form = Ext.DomHelper.append('grid1', {
        tag:     'form',
        style: 'display:none',
        action: 'download.php',
        method: 'post',
        cn:[{
            tag:'textarea',
            name:'body',
            html: base64
        },{
            tag:'input',
            name:'filename',
            value: grid.title||'download'
        },{
            tag:'input',
            name:'extension',
            value:'xls'
        }]
    });
    form.submit();
    document.getElementById('grid1').removeChild(form);
    return false;
}

send the base64 string to php file download.php

<?php
header('Content-type: application/ms-excel');
header('Content-Disposition: attachment; filename=file.xls');

echo base64_decode($_POST['body']);

?>

with these changes work in both IE8 and other browsers.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜