今天遇到一个excel下载乱码问题,从服务器上使用流下载方式,用jquery.ajax下载之后,再转成blob使用虚拟节点下载客户端。然后一直乱码。找了很多方法,包括服务器指定 response.setCharacterEncoding(“utf-8”); 客户端再使用 charset=utf-8 指定编码。再或者从 ms-excel 到修改为 octet-stream ,各种组合都无效。烦了一下午。终于找到了一篇博客 jQuery的ajax下载blob文件 ,很显然这篇博客被抄来抄去。也就不转载了,自己搜吧以后。这篇博客提供了一个思路,ajax在底层自动将数据转型为字符串,而且编码不被控制。这也就是为什么我自己制定编码都无效的原因,因为我没有指定ajax底层的编码方式。
旧代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| $.ajax({ type: method, data: JSON.stringify(data), url: "http://localhost:8096" + url, headers: { 'Content-Type': 'application/json' } }).done(function (data, status, jqXHR) { console.log(data instanceof Blob); var reader = new FileReader(); reader.readAsText(new Blob([data]), 'utf-8'); reader.onload = function (evt) { console.log(evt); const url = window.URL.createObjectURL(new Blob(['\uFEFF' + evt.target.result], {type: 'application/ms-excel;charset=utf-8'})); const link = document.createElement('a'); link.href = url; link.setAttribute('download', '名片印刷导出.xls'); document.body.appendChild(link); link.click(); URL.revokeObjectURL(link.href); document.body.removeChild(link); }; });
|
本着这个思路,就用 XMLHttpRequest 替代掉了 ajax ,没想到马上就解决了。真的是坑
有效的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| var url = "/businessCard/excelBusinessCard"; var method = "POST"; var data = { "applicantId": getUserId(), "pageNo": 1, "pageSize": 10000 }; data.token = getToken(); var xhr = new XMLHttpRequest(); xhr.open('POST', "http://localhost:8096" + url, true); xhr.setRequestHeader("Content-Type", 'application/json'); xhr.responseType = "blob";
xhr.onload = function () { if (this.status === 200) { var blob = this.response; var reader = new FileReader(); reader.readAsDataURL(blob); reader.onload = function (e) { var a = document.createElement('a'); a.download = 'data.xls'; a.href = e.target.result; $("body").append(a); a.click(); $(a).remove(); } } };
xhr.send(JSON.stringify(data));
|