rainabba / jquery-table2excel

jQuery Plugin to export HTML tabled to Excel Spreadsheet Compatible Files
593 stars 666 forks source link

thanks! having some problems with IE #3

Closed benicillin closed 9 years ago

benicillin commented 9 years ago

hi rain. great plugin its working very well for me, however i cant seem to get this working in IE. im testing in IE version 11 and nothing happens when i click my export button. it works perfectly in chrome/firefox... i see someone posted an issue about using IE and about setting the file extension but i dont see that there was a clear resolution there. for your reference my table is named table2excel and the code im using is:
$("#Export").click(function () { $("#table2excel").table2excel({ // exclude CSS class exclude: ".filtered", name: "ProductReport" }); });

rainabba commented 9 years ago

Do you see any error in the console? Can you link me to that page, or a copy with dummy-data but showing the same behavior?

rainabba commented 9 years ago

On my system (Windows 8.1, IE 11), I'm prompted to open an associated app from the Windows Store (non exists) instead of save-as. This isn't something I can control and is just how the behavior is implemented in IE 11.

It does work in Chrome still though.

benicillin commented 9 years ago

rain its throwing an error in my console at column 1162 in ie 11, thats the line that starts with: b.location.href

rainabba commented 9 years ago

What is the error? Can you put a breakpoint there, inspect the 2 parameters and see if either is null?

benicillin commented 9 years ago

Yes. Please take a look here: http://test.vertican.com/Raintest

you will see the error. a and b are both undefined. it looks like its evaluating "this" to the button thats being clicked while i suspect you want "this" to evaluate to the table, not the button triggering the table2excel export command... but my javascript knowledge is limited so i maybe interpreting it wrong.

rainabba commented 9 years ago

I've resolved that error (did some other cleanup as well) and as far as I can tell, IE11 doesn't properly support/implement window.btoa() and that will prevent this from working in IE11. The behavior I observe is a prompt to open with an app in the windows store instead of downloading though so maybe it's not IE11 that's the issue, but that association. If you can disable that behavior, then perhaps it will work for you now.

Would love to know what you find and if you do discover a workaround, please do share here or add to the README.md and submit a pull request.

benicillin commented 9 years ago

yeah rain i just re-worked your code so this works in IE 11. i used blobs and an agent detect script to figure out what browser is being used. im not sure about versions other than IE 11 though. i wrote some fallback code for when blobs dont work and that works in IE as well, the only problem is that you cant choose the correct file extension so the fallback code will just save as a file with no file extension. however, thats better than not working at all...

probably better to pull but im a bit lazy so here is what i changed: (begins with a line i did not change, ends with a line i did not change so you know what you're looking at).

i format the fullTemplate up front because otherwise i do it three times. then i create a blob, turn fullTemplate into an array, and pass it to the blob and then save. in the alternate code, i use an iframe to write the fulltemplate code to, and then do a saveas for that iframe. the only part im not really sure about is how i return(sa) -- thats necessary for one line of code but im not sure its required for all of them (as i said before im not really a javascript guy)

        delete e.ctx.table;

        fullTemplate = e.format(fullTemplate, e.ctx);

        var ua = window.navigator.userAgent;
        var msie = ua.indexOf("MSIE ");

        if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./))      // If Internet Explorer
        {
            if (typeof Blob !== "undefined") {
                //use blobs if we can
                fullTemplate = [fullTemplate];
                //convert to array
                var blob1 = new Blob(fullTemplate, { type: 'text/html' });
                window.navigator.msSaveBlob(blob1, 'Download.xls');
                return (true);
            } else {
                //otherwise use the iframe and save
                //requires a blank iframe on page called txtArea1
                txtArea1.document.open("text/html", "replace");
                txtArea1.document.write(fullTemplate);
                txtArea1.document.close();
                txtArea1.focus();
                sa = txtArea1.document.execCommand("SaveAs", true, "Download.xls");
            }

        } else {
            sa = window.open(e.uri + e.base64(fullTemplate));
        }

        return (sa);

    }
};
rainabba commented 9 years ago

I see your laziness and match it ;) I've implemented this approach and done some quick testing.

benicillin commented 9 years ago

looks good. thanks for cleaning up what i did and thanks again for writing this in the first place.

benicillin commented 9 years ago

also, note that the IE fallback method requires an iframe to be on the page and named txtArea1 - may want to include that in documentation somewhere. im using this:

iframe id="txtArea1" style="display:none"

rainabba commented 9 years ago

Ahh. I tested in IE11 and didn't analyze the code that deeply so I missed that. Any reason that element cannot be created dynamically and must already exist in the page? If not, fork and gitter-done! :)

benicillin commented 9 years ago

ha i think i did it the right way this time by forking changing and then doing a pull request. it works without the iframe now, its dynamically generated. i had to comment out the iframe.focus line though as it was crashing IE for me... also i added back in the format of fullTemplate prior to passing it because it needs to be formatted under all three logic lines so rather do it once in code than three times in code. also i changed your extension to xls as xlsx will not open properly.

clholzin commented 9 years ago

I have a work-around for IE 5 and above. You will need bower.js and filesaver.js as dependencies. This solution prompts the user to save the file as .txt but you can change it to xls and save it. Works great. The bower.js will only prompt the user to this alternative way if it is IE 9 and below.

    if (bowser.msie && bowser.version >= 5) {
            if (bowser.msie) {

                if (bowser.version <= 9) {
                    alert('For IE 9 and below, Save Text file as .XLS.')
                }

                console.log('IE browser ' + bowser.version);
                var format = e.format(fullTemplate, e.ctx);
                saveTextAs(format, getFileName(e.settings));//alerts user to save txt file as xls

            } else {
                alert('IE 5 and lower not supported');
            }
        } else if (bowser.firefox || bowser.chrome || bowser.safari || bowser.iphone || bowser.android) {
            console.log(bowser.version);
            var format2 = e.format(fullTemplate, e.ctx);
            var blob = new Blob([format2], {type: "text/html"});
            saveAs(blob, getFileName(e.settings));//saves xls as usual for modern browsers

        }