【问题标题】:Exporting jquery datatable to excel with additional rows is not working IE将 jquery 数据表导出到带有附加行的 Excel 不起作用 IE
【发布时间】:2017-01-05 12:36:52
【问题描述】:

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

$(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'
   })
 ]
 });
 });

【问题讨论】:

    标签: internet-explorer datatables export-to-excel datatable-buttons


    【解决方案1】:

    这里有解决方案。您必须使用 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 我还有一个问题。在我的数据表中,我有一列包含百分比值。导出时,十进制值会四舍五入。但我需要带有 % 符号的十进制值。我做了一些更改以保留十进制值。它在 Chrome 中运行良好,但在 IE 中运行良好。你能帮我解决这个问题吗?小提琴链接:jsfiddle.net/xevpdeo1/26
    • 您好,我之前有点忙无法回答,但这里有您的解决方案。
    • 它的工作就像一个魅力..!!感谢您的帮助@Jonatan
    【解决方案2】:

    正如@Jonatan Perez 所说,Internet Explorer 不支持 innerHTML,也不支持 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

    【讨论】:

    • 今天 cellXfs = styleSheet.childNodes[5];需要改为:cellXfs = styleSheet.childNodes[4];
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-12
    相关资源
    最近更新 更多