Kendo UI 网格 - Excel 使用隐藏列和自定义格式导出
Kendo UI Grid - Excel Export with hidden columns and custom formatting
我正在尝试使用网格组件的 built-in 支持导出到 excel,应用自定义单元格格式,如这些 Telerik 文档所示:
http://docs.telerik.com/kendo-ui/controls/data-management/grid/how-to/excel/cell-format
导出时使用 hard-coded 行/单元格索引的方法在导出显示先前隐藏列的网格时会出现一个相当明显的问题 - 重现的最佳方法是参考此 jsfiddle:
https://jsfiddle.net/3anqpnqt/1/
- 运行 fiddle
- 单击导出到 excel - 观察自定义数字格式
- 取消隐藏子类别列(使用列菜单)
- 单击导出到 excel - 观察第 2 列的自定义数字格式,现在是 'subcategory'
参考fiddle中的这段代码:
$("#grid").kendoGrid({
toolbar: ["excel"],
excel: {
fileName: "Grid.xlsx",
filterable: true
},
columns: [
{ field: "productName" },
{ field: "category" },
{ field: "subcategory", hidden: true },
{ field: "unitPrice"}
],
dataSource: [
{ productName: "Tea", category: "Beverages", subcategory: "Bev1", unitPrice: 1.5 },
{ productName: "Coffee", category: "Beverages", subcategory: "Bev2", unitPrice: 5.332 },
{ productName: "Ham", category: "Food", subcategory: "Food1", unitPrice: -2.3455 },
{ productName: "Bread", category: "Food", subcategory: "Food2", unitPrice: 6 }
],
columnMenu: true,
excelExport: function(e) {
var sheet = e.workbook.sheets[0];
for (var rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
var row = sheet.rows[rowIndex];
var numericFormat = "#,##0.00;[Red](#,##0.00);-";
for (var cellIndex = 0; cellIndex < row.cells.length; cellIndex++) {
var cell = row.cells[cellIndex];
if (row.type === "data") {
if (cellIndex == 2) { // how are we able to identify the column without using indexes?
cell.format = numericFormat;
cell.hAlign = "right";
}
}
}
}
}
});
我需要做的是将单元格识别为 'unitPrice' 并应用格式,但在 excelExport
处理程序中检查 object 模型不会给我任何方法来制作这个 link。在我的实际应用程序中,我有几种自定义格式要应用(百分比、n0、n2 等),所以它不像 $.isNumeric(cell.value)
或其他方式那么简单。
更新
我还需要解决方案来处理列/行组,它们会在 Excel 模型中生成额外的 header 行/列。
看起来第 [0] 行是 header 行,因此您可以尝试更改
if (cellIndex == 2) {
至
if (sheet.rows[0].cells[cellIndex].value == "unitPrice") {
编辑:
似乎适用于列组:https://jsfiddle.net/dwosrs0x/
更新:
工作表的object模型不是最清晰的。在我查看的各种场景中,第一行似乎确实是 "master" header 行。如果 unitPrice 不在分组中,这似乎有效。如果 unitPrice 在一个分组中,那么涉及组 header (row[1]) 的更复杂的事情可能是可能的。谜题是找出想要的列最终会占据什么位置。
var header = sheet.rows[0];
var upIndex = -1;
var upFound = false;
for (var cellIndex = 0; cellIndex < header.cells.length; cellIndex++) {
if ('colSpan' in header.cells[cellIndex])
upIndex = upIndex + header.cells[cellIndex].colSpan;
else
upIndex = upIndex + 1;
if (header.cells[cellIndex].value == "unitPrice") { // wot we want
upFound = true;
break;
}
}
for (var rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
var row = sheet.rows[rowIndex];
if (row.type === "data" && upFound) {
var cell = row.cells[upIndex];
cell.format = numericFormat;
cell.hAlign = "right";
}
}
fiddle 与组 - https://jsfiddle.net/dwosrs0x/4/
fiddle 带有简单的网格(以证明它仍然有效)- https://jsfiddle.net/gde4nr0y/1/
这绝对有 "bodge" 的味道。
我正在尝试使用网格组件的 built-in 支持导出到 excel,应用自定义单元格格式,如这些 Telerik 文档所示:
http://docs.telerik.com/kendo-ui/controls/data-management/grid/how-to/excel/cell-format
导出时使用 hard-coded 行/单元格索引的方法在导出显示先前隐藏列的网格时会出现一个相当明显的问题 - 重现的最佳方法是参考此 jsfiddle:
https://jsfiddle.net/3anqpnqt/1/
- 运行 fiddle
- 单击导出到 excel - 观察自定义数字格式
- 取消隐藏子类别列(使用列菜单)
- 单击导出到 excel - 观察第 2 列的自定义数字格式,现在是 'subcategory'
参考fiddle中的这段代码:
$("#grid").kendoGrid({
toolbar: ["excel"],
excel: {
fileName: "Grid.xlsx",
filterable: true
},
columns: [
{ field: "productName" },
{ field: "category" },
{ field: "subcategory", hidden: true },
{ field: "unitPrice"}
],
dataSource: [
{ productName: "Tea", category: "Beverages", subcategory: "Bev1", unitPrice: 1.5 },
{ productName: "Coffee", category: "Beverages", subcategory: "Bev2", unitPrice: 5.332 },
{ productName: "Ham", category: "Food", subcategory: "Food1", unitPrice: -2.3455 },
{ productName: "Bread", category: "Food", subcategory: "Food2", unitPrice: 6 }
],
columnMenu: true,
excelExport: function(e) {
var sheet = e.workbook.sheets[0];
for (var rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
var row = sheet.rows[rowIndex];
var numericFormat = "#,##0.00;[Red](#,##0.00);-";
for (var cellIndex = 0; cellIndex < row.cells.length; cellIndex++) {
var cell = row.cells[cellIndex];
if (row.type === "data") {
if (cellIndex == 2) { // how are we able to identify the column without using indexes?
cell.format = numericFormat;
cell.hAlign = "right";
}
}
}
}
}
});
我需要做的是将单元格识别为 'unitPrice' 并应用格式,但在 excelExport
处理程序中检查 object 模型不会给我任何方法来制作这个 link。在我的实际应用程序中,我有几种自定义格式要应用(百分比、n0、n2 等),所以它不像 $.isNumeric(cell.value)
或其他方式那么简单。
更新
我还需要解决方案来处理列/行组,它们会在 Excel 模型中生成额外的 header 行/列。
看起来第 [0] 行是 header 行,因此您可以尝试更改
if (cellIndex == 2) {
至
if (sheet.rows[0].cells[cellIndex].value == "unitPrice") {
编辑:
似乎适用于列组:https://jsfiddle.net/dwosrs0x/
更新:
工作表的object模型不是最清晰的。在我查看的各种场景中,第一行似乎确实是 "master" header 行。如果 unitPrice 不在分组中,这似乎有效。如果 unitPrice 在一个分组中,那么涉及组 header (row[1]) 的更复杂的事情可能是可能的。谜题是找出想要的列最终会占据什么位置。
var header = sheet.rows[0];
var upIndex = -1;
var upFound = false;
for (var cellIndex = 0; cellIndex < header.cells.length; cellIndex++) {
if ('colSpan' in header.cells[cellIndex])
upIndex = upIndex + header.cells[cellIndex].colSpan;
else
upIndex = upIndex + 1;
if (header.cells[cellIndex].value == "unitPrice") { // wot we want
upFound = true;
break;
}
}
for (var rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
var row = sheet.rows[rowIndex];
if (row.type === "data" && upFound) {
var cell = row.cells[upIndex];
cell.format = numericFormat;
cell.hAlign = "right";
}
}
fiddle 与组 - https://jsfiddle.net/dwosrs0x/4/
fiddle 带有简单的网格(以证明它仍然有效)- https://jsfiddle.net/gde4nr0y/1/
这绝对有 "bodge" 的味道。