将 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 " 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);
受 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
我正在尝试使用 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 " 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);
受 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