如何获取 kendo 网格中复制单元格的原始值

How to get the original value of a copied cell in kendo grid

如何在 kendo 网格中复制单元格时获取基础值?

我有以下代码

$(document).ready(function () {

                    $("#cellSelection").kendoGrid({
                        dataSource: {
                            data: orders,
                            pageSize: 6
                        },
                        selectable: "multiple cell",
                        allowCopy: true,
                        pageable: {
                            buttonCount: 5
                        },
                        scrollable: false,
                        navigatable: true,
                        columns: [
                            {
                                field: "ShipCountry",
                                title: "Ship Country",
                                width: 300
                            },
                            {
                                field: "Freight",
                                width: 300
                            },
                            {
                                field: "OrderDate",
                                title: "Order Date",
                                format: "{0:dd/MM/yyyy}"
                            }
                        ]
                    });

                    //events to capture when Ctrl + C is pressed
                    $("#cellSelection").bind('copy', function (e) {
                        var grid = $("#cellSelection").data("kendoGrid");
                        if (grid != null && grid.areaClipBoard != undefined) {
                            console.log("copied content is:");
                            console.log(grid.areaClipBoard.val());
                        }
                    });
                });

因此,当您复制单元格时,将复制单元格中可见的值。

比如说,如果您从网格中复制的值是 40.65,那么只有在 kendo 网格中将 allowCopy 设置为 true 时才会复制该值。但根据数据源的原始值是 40.6789。当按下 ctrl + c 时,我需要将原始值复制到剪贴板。

如你所见,我写了复制事件,它只是输出从网格复制的内容。有没有办法在按下 ctrl + c 时获取基础值?

这里是fiddlelink。 运行 fiddle 并打开开发人员工具和 select 几个单元格并复制它。您应该能够看到复制的内容。

如果您需要使用 40.6789 而不是 40.68 来显示值 我在下面的例子中执行甲酸...可能会帮助你

https://jsfiddle.net/svat3Len/4/

要获取所选行的数据,请使用:

grid.dataItem(grid.select());

在您的例子中,您使用的是单元格选择和 grid.dataItem returns null

这迫使您进入风景优美的路线。要获取该值,您需要:

  1. 从选定的单元格中找到选定的行。
  2. 获取该行的数据。
  3. 确定所选列。
  4. 使用列获取字段名称。
  5. 从行数据和字段名,终于可以找到原始值了。

所以把这些放在一起:

$("#cellSelection").bind('copy', function(e) {
  var grid = $("#cellSelection").data("kendoGrid");
  if (!grid) {
    return;
  }
  if (grid.areaClipBoard) {
    console.log("copied content is:", grid.areaClipBoard.val());
  }
  var cell = grid.select()[0];
  var row = cell.parentNode;
  var column = grid.columns[cell.cellIndex];
  var data = grid.dataItem(row);
  var cellData = data[column.field];
  console.log(cellData);    
});

关于此的几点注意事项:

  1. 我不认为我的错误处理是生产就绪的。
  2. 我只对第一个选定的单元格执行此操作。您实际上使用了 multiple cell,因此您可能应该迭代 grid.select 的结果并对每个结果执行此操作,通过制表符或其他方式连接。我不知道。您是想要多个单元格并进行复制的人。
  3. 如果您可以想象隐藏列,那么我认为我获取该列的方法不会奏效。我其实不知道你该怎么做。

感谢@Cobus Kruger 提供的解决方案。这是我的完整解决方案。

  1. 我们必须遍历网格中的选定项目并获取基础数据源值和 return 结果。
function getTSVFormat(grid) {
    var selected = grid.select();
    var delimeter = '\t';
    var allowCopy = grid.options.allowCopy;
    var onlyVisible = true;
    if ($.isPlainObject(allowCopy) && allowCopy.delimeter) {
        delimeter = allowCopy.delimeter;
    }
    var text = '';
    if (selected.length) {
        if (selected.eq(0).is('tr')) {
            selected = selected.find('td:not(.k-group-cell)');
        }
        if (onlyVisible) {
            selected.filter(':visible');
        }
        var result = [];
        var cellsOffset = grid.columns.length;
        var lockedCols = grid._isLocked() && lockedColumns(grid.columns).length;
        var inLockedArea = true;
        $.each(selected, function (idx, cell) {
            cell = $(cell);
            var tr = cell.closest('tr');
            var rowIndex = tr.index();
            var cellIndex = cell.index();
            if (onlyVisible) {
                cellIndex -= cell.prevAll(':hidden').length;
            }
            if (lockedCols && inLockedArea) {
                inLockedArea = $.contains(grid.lockedTable[0], cell[0]);
            }
            if (grid._groups() && inLockedArea) {
                cellIndex -= grid._groups();
            }
            cellIndex = inLockedArea ? cellIndex : cellIndex + lockedCols;
            if (cellsOffset > cellIndex) {
                cellsOffset = cellIndex;
            }
            var cellText = cell.text();

            var column = grid.columns[cellIndex];
            var data = grid.dataItem(tr);
            var cellData = data[column.field];

            if (!result[rowIndex]) {
                result[rowIndex] = [];
            }
            result[rowIndex][cellIndex] = cellData;

        });
        var rowsOffset = result.length;
        result = $.each(result, function (idx, val) {
            if (val) {
                result[idx] = val.slice(cellsOffset);
                if (rowsOffset > idx) {
                    rowsOffset = idx;
                }
            }
        });
        $.each(result.slice(rowsOffset), function (idx, val) {
            if (val) {
                text += val.join(delimeter) + '\r\n';
            } else {
                text += '\r\n';
            }
        });
    }
    return text;
}

注意上面的函数不是我自己写的。我查看了 kendo.all.js 文件并对其进行了调试并根据我自己的目的进行了自定义。

  1. 在您获得复制的文本后,我们必须在复制事件中调用它
$("#cellSelection").bind('copy', function (e) {
                    var grid = $("#cellSelection").data("kendoGrid");
                    var text = getTSVFormat(grid);

                    //add textarea if its not in yet
                    if (!grid.areaClipBoard) {
                        grid.areaClipBoard = $('<textarea />').css({
                            position: 'fixed',
                            top: '50%',
                            left: '50%',
                            opacity: 0,
                            width: 0,
                            height: 0
                        }).appendTo(grid.wrapper);
                    }

                    //overwrite the default clipboard content of kendo with our custom data source
                    grid.areaClipBoard.val(text);
                    //call copy to clipboard to copy the contents
                    copyToClipboard(text);
                });
  1. 正如您在复制事件中看到的那样,我们必须覆盖 areaClipBoard 属性 的内容才能获得我们的自定义文本。
  2. 将内容复制到 areaClipBoard 后,使用要复制到剪贴板的 html 调用 copyToClipBoard。
function copyToClipboard(html) {
                var textarea = document.createElement('textarea');
                $(textarea).addClass('k-spreadsheet-clipboard').val(html).appendTo(document.body).focus().select();
                document.execCommand('copy');
                $(textarea).remove();
            }

就是这样!您现在可以根据需要粘贴到任何 excel sheet。它将与您在网格中选择的内容具有完全相同的空间。