将 jquery 数据表导出到具有附加行的 excel 无法正常工作 IE

Exporting jquery datatable to excel with additional rows is not working IE

我正在尝试使用 jquery 导出按钮选项将数据 table 导出到 excel sheet。我想在 excel 文件中的 table 数据之前添加额外的行。我在 fiddle https://jsfiddle.net/xevpdeo1/17/ 做了一个类似的演示。它在 Chrome 和 Firefox 中工作正常,但在 IE 中不工作。在 IE 中,table 数据之前的附加行在导出后为空。有人可以帮我解决这个问题吗?提前致谢

$(document).ready(function() {
var xlsBuilder = {
filename: 'business-group-sharers-',
sheetName: 'business-group-sharers-',
customize: function(xlsx) {
  var sheet = xlsx.xl.worksheets['sheet1.xml'];
  var downrows = 4;
  var clRow = $('row', sheet);
  var msg;
  //update Row
  clRow.each(function() {
    var attr = $(this).attr('r');
    var ind = parseInt(attr);
    ind = ind + downrows;
    $(this).attr("r", ind);
  });

  // Update  row > c
  $('row c ', sheet).each(function() {
    var attr = $(this).attr('r');
    var pre = attr.substring(0, 1);
    var ind = parseInt(attr.substring(1, attr.length));
    ind = ind + downrows;
    $(this).attr("r", pre + ind);
  });

  function Addrow(index, data) {

    msg = '<row r="' + index + '">';
    for (var i = 0; i < data.length; i++) {
      var key = data[i].k;
      var value = data[i].v;
      msg += '<c t="inlineStr" r="' + key + index + '">';
      msg += '<is>';
      msg += '<t>' + value + '</t>';
      msg += '</is>';
      msg += '</c>';
    }
    msg += '</row>';
    return msg;
  }
  var r1 = Addrow(1, [{
    k: 'A',
    v: 'Export Date :'
  }, {
    k: 'B',
    v: '10-Jan-2017'
  }]);
  var r2 = Addrow(2, [{
    k: 'A',
    v: 'Account Name :'
  }, {
    k: 'B',
    v: 'Melvin'
  }]);
  var r3 = Addrow(3, [{
    k: 'A',
    v: 'Account Id :'
  }, {
    k: 'B',
    v: '021456321'
  }]);

  sheet.childNodes[0].childNodes[1].innerHTML = r1 + r2 + r3 + sheet.childNodes[0].childNodes[1].innerHTML;
},
exportOptions: {
  columns: [0, 1, 2, 3]
}
}
$('#example').DataTable({
 dom: 'Bfrtip',
 buttons: [
    $.extend(true, {}, xlsBuilder, {
      extend: 'excel'
   })
 ]
 });
 });

这里有解决方案。您必须使用 javascript 进行操作。 IE 不支持 innerHTML 属性

                     var sheet = xlsx.xl.worksheets['sheet1.xml'];
                       var numrows = 4;



                       //update Row
                       clR.each(function () {
                           var attr = $(this).attr('r');
                           var ind = parseInt(attr);
                           ind = ind + numrows;
                           $(this).attr("r", ind);
                       });

                       // Create row before data
                       $('row c ', sheet).each(function (index) {
                           var attr = $(this).attr('r');

                           var pre = attr.substring(0, 1);
                           var ind = parseInt(attr.substring(1, attr.length));
                           ind = ind + numrows;
                           $(this).attr("r", pre + ind);
                       });

                       function Addrow(index, data) {
                        var row = sheet.createElement('row');
                        row.setAttribute("r", index);               
                           for (i = 0; i < data.length; i++) {
                               var key = data[i].key;
                               var value = data[i].value;

                               var c  = sheet.createElement('c');
                               c.setAttribute("t", "inlineStr");
                               c.setAttribute("s", "2");
                               c.setAttribute("r", key + index);

                               var is = sheet.createElement('is');
                               var t = sheet.createElement('t');
                               var text = sheet.createTextNode(value)

                               t.appendChild(text);                                       
                               is.appendChild(t);
                               c.appendChild(is);

                               row.appendChild(c);                                                                                                                          
                           }

                           return row;
                       }


                       /*function Addrow(index, data) {
                           msg = '<row r="' + index + '">'
                           for (i = 0; i < data.length; i++) {
                               var key = data[i].key;
                               var value = data[i].value;
                               msg += '<c t="inlineStr" s="52"  r="' + key + index + '">';
                               msg += '<is>';
                               msg += '<t >' + value + '</t>';
                               msg += '</is>';
                               msg += '</c>';
                           }
                           msg += '</row>';
                           return msg;
                       }*/


                      var r1 = Addrow(1, [{ key: 'A', value: '' }, { key: 'B', value: '' }, { key: 'C', value: ''}]);
                      var r2 = Addrow(2, [{ key: 'A', value: '' }, { key: 'B', value: 'Report Date' }, { key: 'C', value: '' : '') }]);                           
                      var r3 = Addrow(3, [{ key: 'A', value: '' }, { key: 'B', value: ':' }, { key: 'C', value: '' }]);


                      var r4 = Addrow(4, [{ key: 'A', value: '' }, { key: 'B', value: '' }, { key: 'C', value: ''}]);             


                        var sheetData = sheet.getElementsByTagName('sheetData')[0];

                        sheetData.insertBefore(r4,sheetData.childNodes[0]);
                        sheetData.insertBefore(r3,sheetData.childNodes[0]);
                        sheetData.insertBefore(r2,sheetData.childNodes[0]);
                        sheetData.insertBefore(r1,sheetData.childNodes[0]);

这里有其他问题的解决方案

  $(document).ready(function() {
  var xlsBuilder = {    filename: 'business-group-sharers-',
    sheetName: 'business-group-sharers-',
    customize: function(xlsx) {
    var sheet = xlsx.xl.worksheets['sheet1.xml'];

    var cellsColumnE = sheet.querySelectorAll('row c[r^="E"]');

    for(var i=1; i < cellsColumnE.length; i++){
        var attr = cellsColumnE[i].getAttribute('r');

        cellsColumnE[i].removeAttribute('s');
        cellsColumnE[i].setAttribute('t', "inlineStr");

        var value = (parseFloat(cellsColumnE[i].getElementsByTagName('v')[0].textContent) * 100) .toFixed(2);       
        var is = sheet.createElement('is');
        var t = sheet.createElement('t');
        var text = sheet.createTextNode(value + "%");

        cellsColumnE[i].removeChild(cellsColumnE[i].lastChild);

        t.appendChild(text);
        is.appendChild(t);
        cellsColumnE[i].appendChild(is);                 
    }

    },
    exportOptions: {
      columns: [0, 1, 2, 3, 5]
    }
  }
  $('#example').DataTable({
    dom: 'Bfrtip',
    buttons: [
      $.extend(true, {}, xlsBuilder, {
        extend: 'excel'
      })
    ]
  });
});

正如@Jonatan Perez 所说,Internet Explorer 不支持 innerHTML, nor insertAdjacentHTML。并且可能会出现其他其他问题。

总而言之,你必须从这个切换:

// Get the sheet objects
var sSh = xlsx.xl['styles.xml'];
var styleSheet = sSh.childNodes[0];
numFmts = styleSheet.childNodes[0];
cellXfs = styleSheet.childNodes[5];
var sheet = xlsx.xl.worksheets['sheet1.xml'];

// Set a custom format ID
var formatID = 300;

// Create a custom number format (percent). Note that using &quot; instead of \" in the format code does not work for Internet Explorer!
var newNumberFormat = '<numFmt formatCode="0.0" numFmtId="' + formatID + '"/>';
// Create a custom style based on this number format (bold centered rounded)
var newStyle =
    '<xf numFmtId="' + formatID + '" fontId="2" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1">horizontal="center" />>';

// Append the new format next to the other ones
numFmts.innerHTML += newNumberFormat;
// Append the style next to the other ones
cellXfs.childNodes[5].innerHTML += newStyle;

// Use the new style on cell A1
$('c[r=A1]', sheet).attr('s', cellXfs.length);

为此:

// Get the sheet objects
var sSh = xlsx.xl['styles.xml'];
var styleSheet = sSh.childNodes[0];
numFmts = styleSheet.childNodes[0];
cellXfs = styleSheet.childNodes[5];
var sheet = xlsx.xl.worksheets['sheet1.xml'];

// Set a custom format ID
var formatID = 300;

/// In what follows, use "createElementNS" everytime the attribute has an uppercase letter; otherwise, Chrome and Firefox will break the XML by lowercasing it

// Using this instead of "" (required for Excel 2007+, not for 2003)
var ns = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
// Create a custom number format
var newNumberFormat = document.createElementNS(ns, "numFmt");
newNumberFormat.setAttribute("numFmtId", formatID);
newNumberFormat.setAttribute("formatCode", "0.0");
// Append the new format next to the other ones
numFmts.appendChild(newNumberFormat);

// Create a custom style
var lastStyleNum = $('cellXfs xf', sSh).length - 1;
var styleNum = lastStyleNum + 1;
var newStyle = document.createElementNS(ns, "xf");
// Customize style
newStyle.setAttribute("numFmtId", formatID);
newStyle.setAttribute("fontId", 2);
newStyle.setAttribute("fillId", 0);
newStyle.setAttribute("borderId", 0);
newStyle.setAttribute("applyFont", 1);
newStyle.setAttribute("applyFill", 1);
newStyle.setAttribute("applyBorder", 1);
newStyle.setAttribute("xfId", 0);
newStyle.setAttribute("applyNumberFormat", 1);
// Alignment (optional)
var align = document.createElementNS(ns, "alignment");
align.setAttribute("horizontal", "center");
newStyle.appendChild(align);
// Append the style next to the other ones
cellXfs.appendChild(newStyle);

// Use the new style on "Age" column
$('row:not(:eq(1)) c[r^=D]', sheet).attr('s', styleNum);

LIVE DEMO

受 DataTables.net 论坛中 Raghul 和 rf1234 启发的解决方案:
https://www.datatables.net/forums/discussion/comment/116614/#Comment_116641
https://datatables.net/forums/discussion/36045/excel-export-add-rows-and-data#Comment_103911

同样基于以下 SO 答案:
Keep uppercase using attr() with jquery (case sensitive)
Create XML DOM Element while keeping case sensitivity