Slickgrid,如何复制粘贴单元格到excel?

题:

我正在使用jqGrid来显示一个表。
但是,Internet Explorer 9和8的性能不佳,如果它必须显示超过20行…

我试过SlickGrid,它在Internet Explorer中的performance似乎对我来说好多了。

我唯一的问题,阻止我切换到SlickGrid的权利 – 现在是,与SlickGrid,你不能只复制粘贴一系列单元格从SlickGrid到正确的出色。

复制粘贴转换的单元格,所以列是行,行的列(好吧,我知道你可以转置回excel,但我不是平均最终用户。此外,必须这样做是烦人)…

用jqGrid,这个工作完美无瑕。
请注意,我明确不希望将数据输出为CSV / XLS / XLSX文件。

任何人都知道我可以如何使SlickGrid复制粘贴到Excel正确(非转置)的单元格?

看到这个插件: http : //labs.nereo.fr/slick.html

但是它有3个问题:A.不能粘贴到正确的位置B.粘贴到SlickGrid C时会破坏一个额外的单元格C.当源范围大于目的地时会出错

我做了一些修改来解决它们。 见下文:

(function ($) { // register namespace $.extend(true, window, { "Slick": { "CellExternalCopyManager": CellExternalCopyManager } }); function CellExternalCopyManager(options) { /* This manager enables users to copy/paste data from/to an external Spreadsheet application such as MS-Excel® or OpenOffice-Spreadsheet. Since it is not possible to access directly the clipboard in javascript, the plugin uses a trick to do it's job. After detecting the keystroke, we dynamically create a textarea where the browser copies/pastes the serialized data. options: copiedCellStyle : sets the css className used for copied cells. default : "copy-manager" dataItemColumnValueExtractor : option to specify a custom column value extractor function */ var _grid; var _self = this; var _copiedRanges; var _options = options || {}; var _copiedCellStyle = _options.copiedCellStyle || "copy-manager"; var keyCodes = { 'C':67, 'V':86 } function init(grid) { _grid = grid; _grid.onKeyDown.subscribe(handleKeyDown); } function destroy() { _grid.onKeyDown.unsubscribe(handleKeyDown); } function getDataItemValueForColumn(item, columnDef) { if (_options.dataItemColumnValueExtractor) { return _options.dataItemColumnValueExtractor(item, columnDef); } return item[columnDef.field]; } function setDataItemValueForColumn(item, columnDef, value) { if (_options.dataItemColumnValueSetter) { return _options.dataItemColumnValueSetter(item, columnDef, value); } return item[columnDef.field] = value; } function _createTextBox(innerText){ var ta = document.createElement('textarea'); ta.style.position = 'absolute'; ta.style.left = '-1000px'; ta.style.top = '-1000px'; ta.value = innerText; document.body.appendChild(ta); document.designMode = 'off'; ta.focus(); return ta; } function _decodeTabularData(_grid, ta){ var columns = _grid.getColumns(); var clipText = ta.value; var clipRows = clipText.split("\r\n"); var clippeds = []; document.body.removeChild(ta); for (var i=0; i<clipRows.length; i++) { if (clipRows[i]!="") // get rid of the last "" clippeds[i] = clipRows[i].split(String.fromCharCode(9)); // "\t" } var selectedCell = _grid.getActiveCell(); var activeRow = selectedCell.row + pageSize*pageNum;// getActiveCell.row starts from 0 for each page. var activeCell = selectedCell.cell; var desty = activeRow; var destx = activeCell; var data = _grid.getData().getItems(); for (var y = 0; y < clippeds.length; y++){ for (var x = 0; x < clippeds[y].length; x++){ var desty = activeRow + y; var destx = activeCell + x; if (desty < data.length && destx < grid.getColumns().length ) { data[desty][columns[destx].field] = clippeds[y][x]; if ( data[desty].hasOwnProperty('id')) changedIds.push(data[desty].id);// record changed id used by saving function } } } _grid.invalidate(); } function handleKeyDown(e, args) { var ranges; if (!_grid.getEditorLock().isActive()) { //ESC if (e.which == $.ui.keyCode.ESCAPE) { if (_copiedRanges) { e.preventDefault(); clearCopySelection(); _self.onCopyCancelled.notify({ranges: _copiedRanges}); _copiedRanges = null; } } if (e.which == keyCodes.C && (e.ctrlKey || e.metaKey)) { // CTRL + C ranges = _grid.getSelectionModel().getSelectedRanges(); if (ranges.length != 0) { _copiedRanges = ranges; markCopySelection(ranges); _self.onCopyCells.notify({ranges: ranges}); var columns = _grid.getColumns(); var clipText = "" ; for (var rg = 0; rg < ranges.length; rg++){ var range = ranges[rg]; for (var i=range.fromRow; i< range.toRow+1 ; i++){ var dt = _grid.getDataItem(i); for (var j=range.fromCell; j< range.toCell+1 ; j++){ if (j==range.fromCell) clipText = clipText.concat(getDataItemValueForColumn(dt, columns[j])); else clipText = clipText.concat("\t",getDataItemValueForColumn(dt, columns[j])); } clipText = clipText.concat("\r\n"); } } var ta = _createTextBox(clipText); $(ta).select(); setTimeout(function(){ document.body.removeChild(ta); }, 100); return false; } } if (e.which == keyCodes.V && (e.ctrlKey || e.metaKey)) { // CTRL + V var ta = _createTextBox(''); setTimeout(function(){ _decodeTabularData(_grid, ta); }, 100); return false; } } } function markCopySelection(ranges) { var columns = _grid.getColumns(); var hash = {}; for (var i = 0; i < ranges.length; i++) { for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) { hash[j] = {}; for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++) { hash[j][columns[k].id] = true; } } } _grid.setCellCssStyles(_copiedCellStyle, hash); } function clearCopySelection() { _grid.removeCellCssStyles(_copiedCellStyle); } $.extend(this, { "init": init, "destroy": destroy, "clearCopySelection": clearCopySelection, "onCopyCells": new Slick.Event(), "onCopyCancelled": new Slick.Event(), "onPasteCells": new Slick.Event() }); } })(jQuery); 

李东,谢谢! 你的代码帮了我,但我发现,functionhandleKeyDown是更快的labs.nereo.fr版本。

 (function ($) { // register namespace$.extend(true, window, { "Slick": { "CellExternalCopyManager": CellExternalCopyManager } }); function CellExternalCopyManager(options) { /* This manager enables users to copy/paste data from/to an external Spreadsheet application such as MS-Excel® or OpenOffice-Spreadsheet. Since it is not possible to access directly the clipboard in javascript, the plugin uses a trick to do it's job. After detecting the keystroke, we dynamically create a textarea where the browser copies/pastes the serialized data. options: copiedCellStyle : sets the css className used for copied cells. default : "copy-manager" dataItemColumnValueExtractor : option to specify a custom column value extractor function */ var _grid; var _self = this; var _copiedRanges; var _options = options || {}; var _copiedCellStyle = _options.copiedCellStyle || "copied"; var _clearCopyTI = 0; var keyCodes = { 'C':67, 'V':86 } function init(grid) { _grid = grid; _grid.onKeyDown.subscribe(handleKeyDown); } function destroy() { _grid.onKeyDown.unsubscribe(handleKeyDown); } function getDataItemValueForColumn(item, columnDef) { if (_options.dataItemColumnValueExtractor) { return _options.dataItemColumnValueExtractor(item, columnDef); } return item[columnDef.field]; } function setDataItemValueForColumn(item, columnDef, value) { if (_options.dataItemColumnValueSetter) { return _options.dataItemColumnValueSetter(item, columnDef, value); } return item[columnDef.field] = value; } function _createTextBox(innerText){ var ta = document.createElement('textarea'); ta.style.position = 'absolute'; ta.style.left = '-1000px'; ta.style.top = '-1000px'; ta.value = innerText; document.body.appendChild(ta); document.designMode = 'off'; /* Изменяем фокус на select. Сделали это, чтобы после каждого копирования скорость таблицы не уменьшалась (см. ниже). ta.focus(); */ ta.select() return ta; } function _decodeTabularData(_grid, ta){ var columns = _grid.getColumns(); var clipText = ta.value; var clipRows = clipText.split("\r\n"); var clippeds = []; document.body.removeChild(ta); for (var i=0; i<clipRows.length; i++) { if (clipRows[i]!="") // get rid of the last "" clippeds[i] = clipRows[i].split(String.fromCharCode(9)); // "\t" } var selectedCell = _grid.getActiveCell(); /* Переменную activeRow зануляем (что за переменные pageSize и PageNum - непонятно) var activeRow = selectedCell.row + pageSize*pageNum;// getActiveCell.row starts from 0 for each page. */ var activeRow = null; var activeCell = selectedCell.cell; var desty = activeRow; var destx = activeCell; var changedIds = []; // Устанавливаем переменную changedIds var data = _grid.getData().getItems(); for (var y = 0; y < clippeds.length; y++){ for (var x = 0; x < clippeds[y].length; x++){ var desty = activeRow + y; var destx = activeCell + x; if (desty < data.length && destx < grid.getColumns().length ) { data[desty][columns[destx].field] = clippeds[y][x]; if ( data[desty].hasOwnProperty('id')) changedIds.push(data[desty].id);// record changed id used by saving function } } } _grid.invalidate(); } function handleKeyDown(e, args) { var ranges; if (!_grid.getEditorLock().isActive() || _grid.getOptions().autoEdit) { if (e.which == keyCodes.ESC) { if (_copiedRanges) { e.preventDefault(); clearCopySelection(); _self.onCopyCancelled.notify({ranges: _copiedRanges}); _copiedRanges = null; } } if (e.which == keyCodes.C && (e.ctrlKey || e.metaKey)) { // CTRL + C ranges = _grid.getSelectionModel().getSelectedRanges(); if (ranges.length != 0) { _copiedRanges = ranges; markCopySelection(ranges); _self.onCopyCells.notify({ranges: ranges}); var columns = _grid.getColumns(); var clipText = ""; for (var rg = 0; rg < ranges.length; rg++){ var range = ranges[rg]; var clipTextRows = []; if (clipText == "" && _options.includeHeaderWhenCopying) { var clipTextHeaders = []; for (var j = range.fromCell; j < range.toCell + 1 ; j++) { if (columns[j].name.length > 0) clipTextHeaders.push(columns[j].name); } clipTextRows.push(clipTextHeaders.join("\t")); } for (var i=range.fromRow; i< range.toRow+1 ; i++){ var clipTextCells = []; var dt = _grid.getDataItem(i); for (var j=range.fromCell; j< range.toCell+1 ; j++){ clipTextCells.push(getDataItemValueForColumn(dt, columns[j])); } clipTextRows.push(clipTextCells.join("\t")); } clipText += clipTextRows.join("\r\n") + "\r\n"; } var ta = _createTextBox(clipText); return false; } } } } function markCopySelection(ranges) { var columns = _grid.getColumns(); var hash = {}; for (var i = 0; i < ranges.length; i++) { for (var j = ranges[i].fromRow; j <= ranges[i].toRow; j++) { hash[j] = {}; for (var k = ranges[i].fromCell; k <= ranges[i].toCell; k++) { // hash[j][columns[k].id] = true; // Применяем стиль для скопированных ячеек hash[j][columns[k].id] = _copiedCellStyle; } } } _grid.setCellCssStyles(_copiedCellStyle, hash); clearTimeout(_clearCopyTI); _clearCopyTI = setTimeout(function(){ _self.clearCopySelection(); }, 400); } function clearCopySelection() { _grid.removeCellCssStyles(_copiedCellStyle); } $.extend(this, { "init": init, "destroy": destroy, "clearCopySelection": clearCopySelection, "onCopyCells": new Slick.Event(), "onCopyCancelled": new Slick.Event(), "onPasteCells": new Slick.Event() }); } })(jQuery);