最近项目要js实现将数据导出excel文件,网上很多插件实现~~那个开心呀,谁知道后面数据量达到上万条时出问题:浏览器不仅卡死,导出的excel文件一直提示网络失败。。。。

debug调试发现var excel拼接的table字符串,超出了var的长度限制;幸好网上有前辈的解决方案~~~膜拜ing

参考网址:https://blog.csdn.net/b7410852963/article/details/51197552

需要自己去理解下 JavaScript Blob对象

/***导出excel文件
//例子:
var data = [{ userName: 'lily', age: 28, job: "teacher", city: "广州" },{ userName: 'lucy', age: 19, job: "doctor", city: "深圳" }];
if (data == '')return;
var title = [{ userName: '姓名' }, { job: '工作' }, { age: '年龄' }, { city: '城市' }]; 
toExcel("dataExport", data, title); 
***/

/***toExcel:
 * FileName文件名
 * JSONData导出的数据
 * ShowLabel表头
 */
var DownloadEvt = null; 
function toExcel(FileName, JSONData, ShowLabel) {
    var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;

    var docData = new StringBuffer();
    
    // Header 
    var innerHTML = new StringBuffer();
    docData.append('<table><thead>');
    for (var i = 0; i < ShowLabel.length; i++) {
      for (var key in ShowLabel[i]) {
        innerHTML.append('<td>' + ShowLabel[i][key] + '</td>\r');
      }
    }
    docData.append('<tr>\r' + innerHTML.toString() + '</tr>');
    docData.append('</thead><tbody>');

    // Row Vs Column
    for (var i = 0; i < arrData.length; i++) {
      var tdRow = new StringBuffer();
        for (var y = 0; y < ShowLabel.length; y++) {
            for (var k in ShowLabel[y]) {
                if (ShowLabel[y].hasOwnProperty(k)) {
                  tdRow.append('<td style="vnd.ms-excel.numberformat:@">' + (arrData[i][k] === null ? '' : arrData[i][k]) + '</td>\r');
                }
            }
        }
        docData.append('<tr>\r' + tdRow.toString() + '</tr>');
    }

    docData.append('</tbody></table>');

    console.log("docData:",docData);

    var docFile = new StringBuffer();

    docFile.append('<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40">');
    docFile.append('<meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8">');
    docFile.append("<head>");
    docFile.append("<!--[if gte mso 9]>");
    docFile.append("<xml>");
    docFile.append("<x:ExcelWorkbook>");
    docFile.append("<x:ExcelWorksheets>");
    docFile.append("<x:ExcelWorksheet>");
    docFile.append("<x:Name>");
    docFile.append("{worksheet}");
    docFile.append("</x:Name>");
    docFile.append("<x:WorksheetOptions>");
    docFile.append("<x:DisplayGridlines/>");
    docFile.append("</x:WorksheetOptions>");
    docFile.append("</x:ExcelWorksheet>");
    docFile.append("</x:ExcelWorksheets>");
    docFile.append("</x:ExcelWorkbook>");
    docFile.append("</xml>");
    docFile.append("<![endif]-->");
    docFile.append("</head>");
    docFile.append("<body>");
    for (var i = 0; i < docData.content.length; i++) {
        docFile.append(docData.content[i].toString());
    }
    // docFile.append( docData.toString());  
    docFile.append("</body>");
    docFile.append("</html>");

    console.log('docFile:',docFile);

    try {
      console.log('111111111')
        var blob = new Blob(docFile.content, {
            type: 'application/vnd.ms-excel;charset=UTF-8;'
        });
        console.log("blob.size===" + blob.size);
        saveAs(blob, FileName + '.xlsx');
    } catch (e) {
      console.log('22222222222')
        downloadFile(FileName + '.xlsx',
            'data:application/vnd.ms-excel;base64,',
            docFile.toString());
    }
}

function StringBuffer() {  
    this.content = new Array;  
  }  
  StringBuffer.prototype.append = function(str) {  
    this.content.push(str);  
  }  
  StringBuffer.prototype.prepend = function(str) {  
    this.content.unshift(str);  
  }  
  StringBuffer.prototype.toString = function() {  
    return this.content.join("");  
  }  

function saveAs(blob, filename) {

    var type = blob.type;
    var force_saveable_type = 'application/octet-stream';
    if (type && type != force_saveable_type) { // 强制下载,而非在浏览器中打开  
        var slice = blob.slice || blob.webkitSlice || blob.mozSlice;
        blob = slice.call(blob, 0, blob.size, force_saveable_type);
    }

    var url = URL.createObjectURL(blob);
    var save_link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
    save_link.href = url;
    save_link.download = filename;

    console.log('save_link:',save_link);

    var event = document.createEvent('MouseEvents');
    event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    save_link.dispatchEvent(event);
    URL.revokeObjectURL(url);
}

function downloadFile(filename, header, data) {  
  
    var ua = window.navigator.userAgent;  
    if (ua.indexOf("MSIE ") > 0 || !!ua.match(/Trident.*rv\:11\./)) {  
      // Internet Explorer (<= 9) workaround by Darryl (https://github.com/dawiong/tableExport.jquery.plugin)  
      // based on sampopes answer on http://stackoverflow.com/questions/22317951  
      // ! Not working for json and pdf format !  
      var frame = document.createElement("iframe");  

      if (frame) {  
        document.body.appendChild(frame);  
        frame.setAttribute("style", "display:none");  
        frame.contentDocument.open("txt/html", "replace");  
        frame.contentDocument.write(data);  
        frame.contentDocument.close();  
        frame.focus();  

        frame.contentDocument.execCommand("SaveAs", true, filename);  
        document.body.removeChild(frame);  
      }  
    }  
    else {  
      var DownloadLink = document.createElement('a');  

      if (DownloadLink) {  
        DownloadLink.style.display = 'none';  
        DownloadLink.download = filename;  
          
        console.log((header + base64encode(data)).length);  
          
        if (header.toLowerCase().indexOf("base64,") >= 0)  
          DownloadLink.href = header + base64encode(data);  
            
           
        else  
          DownloadLink.href = encodeURIComponent(header + data);  

        document.body.appendChild(DownloadLink);  

        if (document.createEvent) {  
          if (DownloadEvt == null)  
            DownloadEvt = document.createEvent('MouseEvents');  

          DownloadEvt.initEvent('click', true, false);  
          DownloadLink.dispatchEvent(DownloadEvt);  
        }  
        else if (document.createEventObject)  
          DownloadLink.fireEvent('onclick');  
        else if (typeof DownloadLink.onclick == 'function')  
            
          DownloadLink.onclick();  

        /*document.body.removeChild(DownloadLink);*/  
      }  
    }  
  }


  function base64encode(input) {  
    var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";  
    var output = "";  
    var chr1, chr2, chr3, enc1, enc2, enc3, enc4;  
    var i = 0;  
    input = utf8Encode(input);  
    while (i < input.length) {  
      chr1 = input.charCodeAt(i++);  
      chr2 = input.charCodeAt(i++);  
      chr3 = input.charCodeAt(i++);  
      enc1 = chr1 >> 2;  
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);  
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);  
      enc4 = chr3 & 63;  
      if (isNaN(chr2)) {  
        enc3 = enc4 = 64;  
      } else if (isNaN(chr3)) {  
        enc4 = 64;  
      }  
      output = output +  
              keyStr.charAt(enc1) + keyStr.charAt(enc2) +  
              keyStr.charAt(enc3) + keyStr.charAt(enc4);  
    }  
    return output;  
  }  

  function utf8Encode(string) {  
    string = string.replace(/\x0d\x0a/g, "\x0a");  
    var utftext = "";  
    for (var n = 0; n < string.length; n++) {  
      var c = string.charCodeAt(n);  
      if (c < 128) {  
        utftext += String.fromCharCode(c);  
      }  
      else if ((c > 127) && (c < 2048)) {  
        utftext += String.fromCharCode((c >> 6) | 192);  
        utftext += String.fromCharCode((c & 63) | 128);  
      }  
      else {  
        utftext += String.fromCharCode((c >> 12) | 224);  
        utftext += String.fromCharCode(((c >> 6) & 63) | 128);  
        utftext += String.fromCharCode((c & 63) | 128);  
      }  
    }  
    return utftext;  
  }  

 

posted on 2018-04-26 15:52  阿梅M  阅读(1495)  评论(0编辑  收藏  举报