I have a similar question to this question(Javascript: Exporting large text/csv file crashes Google Chrome):
I am trying to save the data created by excelbuilder.js‘s EB.createFile()
function. If I put the file data as the href
attribute value of a link, it works. However, when data is big, it crashes Chrome browser. Code are like this:
//generate a temp <a /> tag var link = document.createElement("a"); link.href = 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + encodeURIComponent(data); link.style = "visibility:hidden"; link.download = fileName; document.body.appendChild(link); link.click(); document.body.removeChild(link);
My code to create the data using excelbuilder.js is like follows:
var artistWorkbook = EB.createWorkbook(); var albumList = artistWorkbook.createWorksheet({name: 'Album List'}); albumList.setData(originalData); artistWorkbook.addWorksheet(albumList); var data = EB.createFile(artistWorkbook);
As suggested by the answer of the similar question (Javascript: Exporting large text/csv file crashes Google Chrome), a blob needs to be created.
My problem is, what is saved in the file isn’t a valid Excel file that can be opened by Excel. The code that I use to save the blob
is like this:
var blob = new Blob( [data], {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,"} ); // Programatically create a link and click it: var a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = fileName; a.click();
If I replace the [data]
in the above code with [Base64.decode(data)]
, the contents in the file saved looks more like the expected excel data, but still cannot be opened by Excel.
Advertisement
Answer
I had the same problem as you. It turns out you need to convert the Excel data file to an ArrayBuffer.
var blob = new Blob([s2ab(atob(data))], { type: '' }); href = URL.createObjectURL(blob);
The s2ab (string to array buffer) method (which I got from https://github.com/SheetJS/js-xlsx/blob/master/README.md) is:
function s2ab(s) { var buf = new ArrayBuffer(s.length); var view = new Uint8Array(buf); for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF; return buf; }