UNPKG

@syncfusion/ej2-spreadsheet

Version:

Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel

1,045 lines (1,044 loc) 131 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; // eslint-disable-next-line @typescript-eslint/triple-slash-reference /// <reference path='../../workbook/base/workbook-model.d.ts'/> import { Property, NotifyPropertyChanges, Event, isUndefined, attributes } from '@syncfusion/ej2-base'; import { addClass, removeClass, Complex, formatUnit, L10n, isNullOrUndefined, Browser } from '@syncfusion/ej2-base'; import { detach, select, closest, setStyleAttribute, EventHandler } from '@syncfusion/ej2-base'; import { mouseDown, spreadsheetDestroyed, keyUp, clearViewer, refreshSheetTabs, positionAutoFillElement, readonlyAlert, deInitProperties, isColumnRange, isRowRange, findDlg } from '../common/index'; import { performUndoRedo, overlay, createImageElement, deleteImage, removeHyperlink } from '../common/index'; import { sheetNameUpdate, updateUndoRedoCollection, getUpdateUsingRaf, setAutoFit } from '../common/index'; import { actionEvents, keyDown, enableFileMenuItems, hideToolbarItems, updateAction } from '../common/index'; import { colWidthChanged, rowHeightChanged, hideRibbonTabs, addFileMenuItems, getSiblingsHeight } from '../common/index'; import { defaultLocale, locale, setResize, initiateFilterUI, clearFilter, focus, removeDesignChart } from '../common/index'; import { ribbon, formulaBar, sheetTabs, formulaOperation, addRibbonTabs } from '../common/index'; import { addContextMenuItems, removeContextMenuItems, enableContextMenuItems, selectRange, addToolbarItems } from '../common/index'; import { cut, copy, paste, dialog, editOperation, activeSheetChanged, refreshFormulaDatasource } from '../common/index'; import { Render } from '../renderer/render'; import { Scroll, VirtualScroll, Edit, CellFormat, Selection, KeyboardNavigation, KeyboardShortcut, WrapText } from '../actions/index'; import { Clipboard, ShowHide, UndoRedo, SpreadsheetHyperlink, Resize, Insert, Delete, FindAndReplace, Merge, AutoFill, SpreadsheetNote } from '../actions/index'; import { ProtectSheet } from '../actions/index'; import { click, hideFileMenuItems } from '../common/index'; import { Dialog, ActionEvents, Overlay } from '../services/index'; import { ServiceLocator } from '../../workbook/services/index'; import { getColumnsWidth, getSheetIndex, WorkbookHyperlink } from './../../workbook/index'; import { getCellAddress, getColumnHeaderText, getSwapRange, getSheetIndexFromAddress, isReadOnlyCells, updateSortCollection } from './../../workbook/common/index'; import { afterHyperlinkCreate, getColIndex, setLinkModel } from './../../workbook/index'; import { WorkbookInsert, WorkbookDelete, WorkbookMerge } from './../../workbook/index'; import { getSheetNameFromAddress, DataBind, beforeHyperlinkCreate } from './../../workbook/index'; import { sortComplete, dataSourceChanged, isHiddenRow, isHiddenCol } from './../../workbook/index'; import { getSheetIndexFromId, WorkbookEdit, WorkbookOpen, WorkbookSave, WorkbookCellFormat, WorkbookSort, getSheet } from './../../workbook/index'; import { findKeyUp, refreshRibbonIcons, hideShow } from './../../workbook/index'; import { Workbook } from '../../workbook/base/workbook'; import { getRequiredModules, ScrollSettings, enableToolbarItems } from '../common/index'; import { SelectionSettings, getStartEvent, enableRibbonTabs, getDPRValue } from '../common/index'; import { createSpinner, showSpinner, hideSpinner } from '@syncfusion/ej2-popups'; import { setRowHeight, getRowsHeight, getColumnWidth, getRowHeight, getCell, setColumn, setCell, setRow } from './../../workbook/base/index'; import { getRangeIndexes, getIndexesFromAddress, getCellIndexes, WorkbookNumberFormat, WorkbookFormula } from '../../workbook/index'; import { Ribbon, FormulaBar, SheetTabs, Open, ContextMenu, Save, NumberFormat, Formula } from '../integrations/index'; import { Sort, Filter, SpreadsheetImage, SpreadsheetChart } from '../integrations/index'; import { getColumn, getRow, WorkbookFilter, refreshInsertDelete } from '../../workbook/index'; import { fltrPrevent } from '@syncfusion/ej2-grids'; import { DataValidation, spreadsheetCreated, showAggregate } from './../index'; import { WorkbookDataValidation, WorkbookConditionalFormat, WorkbookFindAndReplace, WorkbookAutoFill } from '../../workbook/actions/index'; import { findAllValues, getFormattedCellObject } from './../../workbook/common/index'; import { ConditionalFormatting } from '../actions/conditional-formatting'; import { WorkbookImage, WorkbookChart, updateView, focusChartBorder } from '../../workbook/index'; import { WorkbookProtectSheet, isImported } from '../../workbook/index'; import { contentLoaded, completeAction, freeze, refreshOverlayElem, insertDesignChart } from '../common/index'; import { beginAction, sheetsDestroyed, workbookFormulaOperation, getRangeAddress } from './../../workbook/common/index'; import { updateScroll, clearCopy, clearUndoRedoCollection, clearChartBorder, propertyChange } from '../common/index'; import { Print } from '../renderer/print'; /** * Represents the Spreadsheet component. * * ```html * <div id='spreadsheet'></div> * <script> * let spreadsheetObj = new Spreadsheet(); * spreadsheetObj.appendTo('#spreadsheet'); * </script> * ``` */ var Spreadsheet = /** @class */ (function (_super) { __extends(Spreadsheet, _super); /** * Constructor for creating the widget. * * @param {SpreadsheetModel} options - Configures Spreadsheet options. * @param {string|HTMLElement} element - Element to render Spreadsheet. */ function Spreadsheet(options, element) { var _this = _super.call(this, options) || this; /** * Array to store multiple rafIds on intial rendering. * * @hidden */ _this.rafIds = []; /** @hidden */ _this.viewport = { rowCount: 0, colCount: 0, height: 0, topIndex: 0, leftIndex: 0, width: 0, bottomIndex: 0, rightIndex: 0, beforeFreezeHeight: 0, beforeFreezeWidth: 0, scaleX: 1, scaleY: 1 }; _this.needsID = true; Spreadsheet_1.Inject(Ribbon, FormulaBar, SheetTabs, Selection, Edit, KeyboardNavigation, KeyboardShortcut, Clipboard, DataBind, Open, ContextMenu, Save, NumberFormat, CellFormat, Formula, WrapText, WorkbookEdit, WorkbookOpen, WorkbookSave, WorkbookCellFormat, WorkbookNumberFormat, WorkbookFormula, Sort, WorkbookSort, Resize, UndoRedo, WorkbookFilter, Filter, SpreadsheetHyperlink, WorkbookHyperlink, Insert, Delete, WorkbookInsert, WorkbookDelete, DataValidation, WorkbookDataValidation, Print, ProtectSheet, WorkbookProtectSheet, FindAndReplace, WorkbookFindAndReplace, Merge, WorkbookMerge, SpreadsheetImage, ConditionalFormatting, WorkbookImage, WorkbookConditionalFormat, SpreadsheetChart, WorkbookChart, AutoFill, WorkbookAutoFill, SpreadsheetNote); if (element) { _this.appendTo(element); } return _this; } Spreadsheet_1 = Spreadsheet; /** * To get cell element. * * @param {number} rowIndex - specify the rowIndex. * @param {number} colIndex - specify the colIndex. * @param {HTMLTableElement} row - specify the row. * @returns {HTMLElement} - Get cell element * @hidden */ Spreadsheet.prototype.getCell = function (rowIndex, colIndex, row) { var td; if (this.insideViewport(rowIndex, colIndex)) { if (!row) { row = this.getRow(rowIndex, null, colIndex); } colIndex = this.getViewportIndex(colIndex, true); td = row ? row.cells[colIndex] : row; } return td; }; /** * Get cell element. * * @param {number} index - specify the index. * @param {HTMLTableElement} table - specify the table. * @param {number} colIdx - specify the column index. * @returns {HTMLTableRowElement} - Get cell element * @hidden */ Spreadsheet.prototype.getRow = function (index, table, colIdx) { if (!table) { var sheet = this.getActiveSheet(); var frozenRow = this.frozenRowCount(sheet); var frozenCol = this.frozenColCount(sheet); if (isNullOrUndefined(colIdx) || index > frozenRow - 1 && colIdx > frozenCol - 1) { table = this.getContentTable(); } else { table = index < frozenRow && colIdx < frozenCol ? this.sheetModule.getSelectAllTable() : (index < frozenRow ? this.getColHeaderTable() : this.getRowHeaderTable()); } } index = this.getViewportIndex(index); return table ? table.rows[index] : null; }; /** * To get hidden row/column count between two specified index. * * Set `layout` as `columns` if you want to get column hidden count. * * @param {number} startIndex - specify the startIndex. * @param {number} endIndex - specify the endIndex. * @param {string} layout - specify the layout. * @param {SheetModel} sheet - specify the sheet. * @returns {number} - To get hidden row/column count between two specified index. * @hidden */ Spreadsheet.prototype.hiddenCount = function (startIndex, endIndex, layout, sheet) { if (layout === void 0) { layout = 'rows'; } if (sheet === void 0) { sheet = this.getActiveSheet(); } var count = 0; var rowColModel; for (var i = startIndex; i <= endIndex; i++) { rowColModel = sheet["" + layout][i]; if (rowColModel && rowColModel.hidden) { count++; } } return count; }; /** * To get row/column viewport index. * * @param {number} index - specify the index. * @param {boolean} isCol - specify the bool value. * @returns {number} - To get row/column viewport index. * @hidden */ Spreadsheet.prototype.getViewportIndex = function (index, isCol) { var sheet = this.getActiveSheet(); var frozenCol = this.frozenColCount(sheet); var frozenRow = this.frozenRowCount(sheet); if (isCol) { if (frozenCol) { var leftIndex = getCellIndexes(sheet.topLeftCell)[1]; if (index < frozenCol) { index -= this.hiddenCount(leftIndex, index, 'columns'); index -= leftIndex; return index + 1; } else { index -= this.hiddenCount(this.viewport.leftIndex + frozenCol, index, 'columns'); index -= (this.viewport.leftIndex + frozenCol); return index; } } else { index -= this.hiddenCount(this.viewport.leftIndex, index, 'columns'); index -= this.viewport.leftIndex; } } else { if (frozenRow) { var topIndex = getCellIndexes(sheet.topLeftCell)[0]; if (index < frozenRow) { index -= this.hiddenCount(topIndex, index); index -= topIndex; return index + 1; } else { index -= this.hiddenCount(this.viewport.topIndex + frozenRow, index); index -= (this.viewport.topIndex + frozenRow); return index; } } else { index -= this.hiddenCount(this.viewport.topIndex, index); index -= this.viewport.topIndex; } } return index; }; /** * To initialize the services; * * @returns {void} - To initialize the services. * @hidden */ Spreadsheet.prototype.preRender = function () { _super.prototype.preRender.call(this); this.serviceLocator = new ServiceLocator; this.initServices(); }; Spreadsheet.prototype.initServices = function () { this.serviceLocator.register(locale, new L10n(this.getModuleName(), defaultLocale, this.locale)); this.serviceLocator.register(dialog, new Dialog(this)); this.serviceLocator.register(actionEvents, new ActionEvents(this)); this.serviceLocator.register(overlay, new Overlay(this)); }; /** * To Initialize the component rendering. * * @returns {void} - To Initialize the component rendering. * @hidden */ Spreadsheet.prototype.render = function () { _super.prototype.render.call(this); this.element.setAttribute('tabindex', '0'); this.renderModule = new Render(this); this.renderSpreadsheet(); this.wireEvents(); if (this.created && !this.refreshing) { if (this.created.observers) { if (this.created.observers.length > 0) { var observerObject = { observers: this.created.observers }; if (this.isAngular) { observerObject = { observers: this.created.observers, currentObservers: this.created.observers }; this.created.currentObservers = []; } this.createdHandler = observerObject; this.created.observers = []; } } else { this.createdHandler = this.created; this.setProperties({ created: undefined }, true); } } }; Spreadsheet.prototype.renderSpreadsheet = function () { if (this.cssClass) { addClass([this.element], this.cssClass.split(' ')); } if (this.enableRtl) { this.element.classList.add('e-rtl'); } this.setHeight(); this.setWidth(); createSpinner({ target: this.element }, this.createElement); if (this.cssClass && this.cssClass.indexOf('e-mobile-view') === -1 && this.isMobileView()) { this.element.classList.add('e-mobile-view'); } if (Browser.isDevice) { this.element.classList.add('e-device'); } this.sheetModule = this.serviceLocator.getService('sheet'); if (this.allowScrolling) { this.scrollModule = new Scroll(this); } if (this.scrollSettings.enableVirtualization) { new VirtualScroll(this); } this.renderModule.render(); new ShowHide(this); }; /** * By default, Spreadsheet shows the spinner for all its actions. To manually show spinner you this method at your needed time. * * {% codeBlock src='spreadsheet/showSpinner/index.md' %}{% endcodeBlock %} * * @returns {void} - shows spinner */ Spreadsheet.prototype.showSpinner = function () { showSpinner(this.element); }; /** * To hide showed spinner manually. * * {% codeBlock src='spreadsheet/hideSpinner/index.md' %}{% endcodeBlock %} * * @returns {void} - To hide showed spinner manually. */ Spreadsheet.prototype.hideSpinner = function () { hideSpinner(this.element); }; /** * To protect the particular sheet. * * {% codeBlock src='spreadsheet/protectSheet/index.md' %}{% endcodeBlock %} * * @param {number | string} sheet - Specifies the sheet to protect. * @param {ProtectSettingsModel} protectSettings - Specifies the protect sheet options. * @default { selectCells: 'false', formatCells: 'false', formatRows: 'false', formatColumns:'false', insertLink:'false' } * @param {string} password - Specifies the password to protect. * @returns {void} - To protect the particular sheet. */ Spreadsheet.prototype.protectSheet = function (sheet, protectSettings, password) { _super.prototype.protectSheet.call(this, sheet, protectSettings, password); }; /** * To unprotect the particular sheet. * * {% codeBlock src='spreadsheet/unprotectSheet/index.md' %}{% endcodeBlock %} * * @param {number | string} sheet - Specifies the sheet name or index to Unprotect. * @returns {void} - To unprotect the particular sheet. */ Spreadsheet.prototype.unprotectSheet = function (sheet) { _super.prototype.unprotectSheet.call(this, sheet); }; /** * To find the specified cell value. * * {% codeBlock src='spreadsheet/find/index.md' %}{% endcodeBlock %} * * @param {FindOptions} args - Specifies the replace value with find args to replace specified cell value. * @param {string} args.value - Specifies the value to be find. * @param {string} args.mode - Specifies the value to be find within sheet or workbook. * @param {string} args.searchBy - Specifies the value to be find by row or column. * @param {boolean} args.isCSen - Specifies the find match with case sensitive or not. * @param {boolean} args.isEMatch - Specifies the find match with entire match or not. * @param {string} args.findOpt - Specifies the next or previous find match. * @param {number} args.sheetIndex - Specifies the current sheet to find. * @default { mode: 'Sheet', searchBy: 'By Row', isCSen: 'false', isEMatch:'false' } * @returns {void} - To find the specified cell value. */ Spreadsheet.prototype.find = function (args) { var activeCell = this.getActiveSheet().activeCell; _super.prototype.findHandler.call(this, args); if (!args.isAction) { if (activeCell !== this.getActiveSheet().activeCell) { return this.getActiveSheet().name + '!' + this.getActiveSheet().activeCell; } else { return null; } } }; /** * To replace the specified cell value. * * {% codeBlock src='spreadsheet/replace/index.md' %}{% endcodeBlock %} * * @param {FindOptions} args - Specifies the replace value with find args to replace specified cell value. * @param {string} args.replaceValue - Specifies the replacing value. * @param {string} args.replaceBy - Specifies the value to be replaced for one or all. * @param {string} args.value - Specifies the value to be replaced * @returns {void} - To replace the specified cell value. */ Spreadsheet.prototype.replace = function (args) { if (args.showDialog) { this.notify(findDlg, args); } else { args = { value: args.value, mode: args.mode ? args.mode : 'Sheet', isCSen: args.isCSen ? args.isCSen : false, isEMatch: args.isEMatch ? args.isEMatch : false, searchBy: args.searchBy ? args.searchBy : 'By Row', replaceValue: args.replaceValue, replaceBy: args.replaceBy, sheetIndex: isUndefined(args.sheetIndex) ? this.activeSheetIndex : args.sheetIndex, findOpt: args.findOpt ? args.findOpt : '' }; _super.prototype.replaceHandler.call(this, args); } }; /** * To Find All the Match values Address within Sheet or Workbook. * * {% codeBlock src='spreadsheet/findAll/index.md' %}{% endcodeBlock %} * * @param {string} value - Specifies the value to find. * @param {string} mode - Specifies the value to be find within Sheet/Workbook. * @param {boolean} isCSen - Specifies the find match with case sensitive or not. * @param {boolean} isEMatch - Specifies the find match with entire match or not. * @param {number} sheetIndex - Specifies the sheetIndex. If not specified, it will consider the active sheet. * @returns {string[]} - To Find All the Match values Address within Sheet or Workbook. */ Spreadsheet.prototype.findAll = function (value, mode, isCSen, isEMatch, sheetIndex) { mode = mode ? mode : 'Sheet'; sheetIndex = sheetIndex < this.sheets.length ? sheetIndex : this.activeSheetIndex; isCSen = isCSen ? isCSen : false; isEMatch = isEMatch ? isEMatch : false; var findCollection = []; var findAllArguments = { value: value, mode: mode, sheetIndex: sheetIndex, isCSen: isCSen, isEMatch: isEMatch, findCollection: findCollection }; this.notify(findAllValues, findAllArguments); return findCollection; }; /** * Used to navigate to cell address within workbook. * * {% codeBlock src='spreadsheet/goTo/index.md' %}{% endcodeBlock %} * * @param {string} address - Specifies the cell address you need to navigate. * You can specify the address in two formats, * `{sheet name}!{cell address}` - Switch to specified sheet and navigate to specified cell address. * `{cell address}` - Navigate to specified cell address with in the active sheet. * @returns {void} - Used to navigate to cell address within workbook. */ Spreadsheet.prototype.goTo = function (address) { if (!this.allowScrolling) { this.selectRange(address); return; } if (address.includes('!')) { var idx = getSheetIndex(this, getSheetNameFromAddress(address)); if (idx === undefined) { return; } if (idx !== this.activeSheetIndex) { var selectRange_1 = address.substring(address.lastIndexOf('!') + 1); var activeCell = selectRange_1.split(':')[0]; var sheet_1 = this.sheets[idx]; this.setSheetPropertyOnMute(sheet_1, 'activeCell', activeCell); this.setSheetPropertyOnMute(sheet_1, 'selectedRange', selectRange_1); var cellIndex = getCellIndexes(activeCell); if (sheet_1.frozenColumns || sheet_1.frozenRows) { var topLeftCell = getCellIndexes(sheet_1.topLeftCell); if (!((sheet_1.frozenRows && cellIndex[0] < topLeftCell[0]) || (sheet_1.frozenColumns && cellIndex[1] < topLeftCell[1]))) { var frozenRow_1 = this.frozenRowCount(sheet_1); var frozenCol_1 = this.frozenColCount(sheet_1); var curCell = []; var paneCell = []; var paneTopLeftCell = getCellIndexes(sheet_1.paneTopLeftCell); if (frozenRow_1) { curCell.push(topLeftCell[0]); if (cellIndex[0] >= frozenRow_1) { paneCell.push(cellIndex[0]); } else { paneCell.push(paneTopLeftCell[0]); } } else { curCell.push(cellIndex[0]); paneCell.push(cellIndex[0]); } if (frozenCol_1) { curCell.push(topLeftCell[1]); if (cellIndex[1] >= frozenCol_1) { paneCell.push(cellIndex[1]); } else { paneCell.push(paneTopLeftCell[1]); } } else { curCell.push(cellIndex[1]); paneCell.push(cellIndex[1]); } this.setSheetPropertyOnMute(sheet_1, 'topLeftCell', getCellAddress(curCell[0], curCell[1])); this.setSheetPropertyOnMute(sheet_1, 'paneTopLeftCell', getCellAddress(paneCell[0], paneCell[1])); } } else { if (cellIndex[0] < this.viewport.rowCount) { cellIndex[0] = 0; } if (cellIndex[1] < this.viewport.colCount) { cellIndex[1] = 0; } this.updateTopLeftCell(cellIndex[0], cellIndex[1], null, sheet_1); } this.activeSheetIndex = idx; this.dataBind(); return; } } var indexes = getRangeIndexes(address); var sheet = this.getActiveSheet(); var frozenRow = this.frozenRowCount(sheet); var frozenCol = this.frozenColCount(sheet); var insideDomCount = this.insideViewport(indexes[0], indexes[1]); if (insideDomCount) { this.selectRange(address); var viewportIndexes = getCellIndexes(sheet.paneTopLeftCell); var viewportSize = this.viewport.height; if (this.allowScrolling) { viewportSize -= this.getScrollElement().parentElement.getBoundingClientRect().height; } var threshold = 0; var lastRowIdx = 0; if (frozenRow) { var topLeftIndexes = getCellIndexes(sheet.topLeftCell); for (var i = topLeftIndexes[0]; i < frozenRow; i++) { threshold += getRowHeight(sheet, i); if (threshold > viewportSize) { lastRowIdx = i; break; } } } if (lastRowIdx === 0) { for (var i = viewportIndexes[0]; i <= this.viewport.bottomIndex; i++) { threshold += getRowHeight(sheet, i); if (threshold > viewportSize) { lastRowIdx = i; break; } else if (i === this.viewport.bottomIndex) { lastRowIdx = this.viewport.bottomIndex; } } } viewportIndexes[2] = lastRowIdx; var lastColIdx = 0; threshold = 0; viewportSize = this.viewport.width - this.sheetModule.getScrollSize(); if (frozenCol) { var topLeftIndexes = getCellIndexes(sheet.topLeftCell); for (var i = topLeftIndexes[1]; i < frozenCol; i++) { threshold += getColumnWidth(sheet, i); if (threshold > viewportSize) { lastColIdx = i; break; } } } if (lastColIdx === 0) { for (var i = viewportIndexes[1]; i <= this.viewport.rightIndex; i++) { threshold += getColumnWidth(sheet, i); if (threshold > viewportSize) { lastColIdx = i; break; } else if (i === this.viewport.rightIndex) { lastColIdx = this.viewport.rightIndex; } } } viewportIndexes[3] = lastColIdx; if (indexes[0] >= viewportIndexes[0] && indexes[0] < viewportIndexes[2] && indexes[1] >= viewportIndexes[1] && indexes[1] < viewportIndexes[3]) { return; } if (frozenRow || frozenCol) { viewportIndexes = [].concat(getCellIndexes(sheet.topLeftCell), [frozenRow, viewportIndexes[3]]); if (indexes[0] >= viewportIndexes[0] && indexes[0] < viewportIndexes[2] && indexes[1] >= viewportIndexes[1] && indexes[1] < viewportIndexes[3]) { return; } viewportIndexes[2] = lastRowIdx; viewportIndexes[3] = frozenCol; if (indexes[0] >= viewportIndexes[0] && indexes[0] < viewportIndexes[2] && indexes[1] >= viewportIndexes[1] && indexes[1] < viewportIndexes[3]) { return; } } } var content = this.getMainContent().parentElement; var vTrack; var cVTrack; var offset; var vWidth; var vHeight; var scrollableSize; if (indexes[0] === frozenRow) { offset = 0; } else { offset = getRowsHeight(sheet, frozenRow, indexes[0] - 1, true); if (this.scrollSettings.enableVirtualization) { scrollableSize = offset + this.getContentTable().getBoundingClientRect().height; vHeight = parseFloat(content.querySelector('.e-virtualtrack').style.height); if (scrollableSize > vHeight) { scrollableSize += 10; vTrack = content.querySelector('.e-virtualtrack'); vTrack.style.height = scrollableSize + "px"; getUpdateUsingRaf(function () { vTrack.style.height = vHeight + "px"; }); } } } content.scrollTop = offset; content = this.element.getElementsByClassName('e-scroller')[0]; if (indexes[1] === frozenCol) { offset = 0; } else { offset = getColumnsWidth(sheet, frozenCol, indexes[1] - 1, true); if (this.scrollSettings.enableVirtualization) { scrollableSize = offset + this.getContentTable().getBoundingClientRect().width; vWidth = parseFloat(content.querySelector('.e-virtualtrack').style.width); if (scrollableSize > vWidth) { scrollableSize += 10; vTrack = content.querySelector('.e-virtualtrack'); vTrack.style.width = scrollableSize + "px"; cVTrack = this.getColumnHeaderContent().querySelector('.e-virtualtrack'); cVTrack.style.width = scrollableSize + "px"; vTrack = this.getMainContent().querySelector('.e-virtualtrack'); vTrack.style.width = scrollableSize + "px"; getUpdateUsingRaf(function () { vTrack.style.width = vWidth + "px"; cVTrack.style.width = vWidth + "px"; }); } } } content.scrollLeft = offset; if (!insideDomCount) { this.selectRange(address); } }; /** * @hidden * @param {number} rowIndex - Specifies the row index. * @param {number} colIndex - Specifies the column index. * @returns {boolean} - Specifies the boolean value. */ Spreadsheet.prototype.insideViewport = function (rowIndex, colIndex) { var sheet = this.getActiveSheet(); if (sheet.frozenRows || sheet.frozenColumns) { var frozenRow = this.frozenRowCount(sheet); var frozenCol = this.frozenColCount(sheet); var indexes = getCellIndexes(sheet.topLeftCell); return ((rowIndex >= indexes[0] && rowIndex < frozenRow) || (rowIndex >= this.viewport.topIndex + frozenRow && rowIndex <= this.viewport.bottomIndex)) && ((colIndex >= indexes[1] && colIndex < frozenCol) || (colIndex >= this.viewport.leftIndex + frozenCol && colIndex <= this.viewport.rightIndex)); } else { return rowIndex >= this.viewport.topIndex && rowIndex <= this.viewport.bottomIndex && colIndex >= this.viewport.leftIndex && colIndex <= this.viewport.rightIndex; } }; /** * Used to resize the Spreadsheet. * * {% codeBlock src='spreadsheet/resize/index.md' %}{% endcodeBlock %} * * @returns {void} - Used to resize the Spreadsheet. */ Spreadsheet.prototype.resize = function () { this.renderModule.setSheetPanelSize(); if (this.scrollSettings.enableVirtualization) { this.renderModule.refreshSheet(false, true); } }; /** * To cut the specified cell or cells properties such as value, format, style etc... * * {% codeBlock src='spreadsheet/cut/index.md' %}{% endcodeBlock %} * * @param {string} address - Specifies the range address to cut. * @returns {Promise<Object>} - To cut the specified cell or cells properties such as value, format, style etc... */ Spreadsheet.prototype.cut = function (address) { var promise = new Promise(function (resolve) { resolve((function () { })()); }); this.notify(cut, address ? { range: getIndexesFromAddress(address), sId: this.sheets[getSheetIndex(this, getSheetNameFromAddress(address))] ? this.sheets[getSheetIndex(this, getSheetNameFromAddress(address))].id : this.getActiveSheet().id, promise: promise, invokeCopy: true, isPublic: true } : { promise: promise, invokeCopy: true, isPublic: true }); return promise; }; /** * To copy the specified cell or cells properties such as value, format, style etc... * * {% codeBlock src='spreadsheet/copy/index.md' %}{% endcodeBlock %} * * @param {string} address - Specifies the range address. * @returns {Promise<Object>} - To copy the specified cell or cells properties such as value, format, style etc... */ Spreadsheet.prototype.copy = function (address) { var promise = new Promise(function (resolve) { resolve((function () { })()); }); this.notify(copy, address ? { range: getIndexesFromAddress(address), sId: this.sheets[getSheetIndex(this, getSheetNameFromAddress(address))] ? this.sheets[getSheetIndex(this, getSheetNameFromAddress(address))].id : this.getActiveSheet().id, promise: promise, invokeCopy: true, isPublic: true } : { promise: promise, invokeCopy: true, isPublic: true }); return promise; }; /** * This method is used to paste the cut or copied cells in to specified address. * * {% codeBlock src='spreadsheet/paste/index.md' %}{% endcodeBlock %} * * @param {string} address - Specifies the cell or range address. * @param {PasteSpecialType} type - Specifies the type of paste. * @returns {void} - used to paste the cut or copied cells in to specified address. */ Spreadsheet.prototype.paste = function (address, type) { this.notify(paste, { range: address ? getIndexesFromAddress(address) : address, sIdx: address ? getSheetIndex(this, getSheetNameFromAddress(address)) : address, type: type, isAction: true, isInternal: true }); }; /** * To update the action which need to perform. * * {% codeBlock src='spreadsheet/updateAction/index.md' %}{% endcodeBlock %} * * @param {string} options - It describes an action and event args to perform. * @param {string} options.action - specifies an action. * @param {string} options.eventArgs - specifies an args to perform an action. * @returns {void} - To update the action which need to perform. */ Spreadsheet.prototype.updateAction = function (options) { updateAction(options, this); }; Spreadsheet.prototype.setHeight = function () { if (this.height) { if (this.height.toString().indexOf('%') > -1) { this.element.style.minHeight = '400px'; } this.element.style.height = formatUnit(this.height); } }; Spreadsheet.prototype.setWidth = function () { if (this.width) { if (this.width.toString().indexOf('%') > -1 || this.width === 'auto') { this.element.style.minWidth = '300px'; } this.element.style.width = formatUnit(this.width); } }; /** * Set the width of column. * * {% codeBlock src='spreadsheet/setColWidth/index.md' %}{% endcodeBlock %} * * @param {number} width - To specify the width * @param {number} colIndex - To specify the colIndex * @param {number} sheetIndex - To specify the sheetIndex * @returns {void} - Set the width of column. */ Spreadsheet.prototype.setColWidth = function (width, colIndex, sheetIndex) { if (width === void 0) { width = 64; } if (colIndex === void 0) { colIndex = 0; } var sheet = isNullOrUndefined(sheetIndex) ? this.getActiveSheet() : this.sheets[sheetIndex]; if (sheet && (!sheet.isProtected || sheet.protectSettings.formatColumns)) { var mIndex_1 = colIndex; var colWidth_1 = (typeof width === 'number') ? width + 'px' : width; colIndex = isNullOrUndefined(colIndex) ? getCellIndexes(sheet.activeCell)[1] : colIndex; var setColModel = function () { getColumn(sheet, mIndex_1).width = parseInt(colWidth_1, 10) > 0 ? parseInt(colWidth_1, 10) : 0; sheet.columns[mIndex_1].customWidth = true; }; var frozenCol = this.frozenColCount(sheet); if (sheet.id === this.getActiveSheet().id) { if ((colIndex >= this.viewport.leftIndex + frozenCol && colIndex <= this.viewport.rightIndex) || (frozenCol && colIndex < frozenCol)) { colIndex = this.getViewportIndex(colIndex, true); var eleWidth = getColumnWidth(sheet, mIndex_1, null, true); var threshold = getDPRValue(parseInt(colWidth_1, 10)) - eleWidth; if (threshold < 0 && eleWidth < -(threshold)) { threshold = -eleWidth; } setColModel(); this.notify(colWidthChanged, { threshold: threshold, colIdx: mIndex_1, checkWrapCell: true }); setResize(mIndex_1, colIndex, colWidth_1, true, this); } else { var oldWidth = getColumnWidth(sheet, colIndex); var threshold = void 0; if (parseInt(colWidth_1, 10) > 0) { threshold = -(oldWidth - parseInt(colWidth_1, 10)); } else { threshold = -oldWidth; } setColModel(); this.notify(colWidthChanged, { threshold: threshold, colIdx: colIndex }); } this.notify(positionAutoFillElement, null); } else { setColModel(); } } }; /** * Set the height of row. * * {% codeBlock src='spreadsheet/setRowHeight/index.md' %}{% endcodeBlock %} * * @param {number} height - Specifies height needs to be updated. If not specified, it will set the default height 20. * @param {number} rowIndex - Specifies the row index. If not specified, it will consider the first row. * @param {number} sheetIndex - Specifies the sheetIndex. If not specified, it will consider the active sheet. * @param {boolean} edited - Specifies the boolean value. * @param {boolean} skipCustomRow - When this parameter is enabled, the method will skip updating the row height if it has already been modified and its 'customHeight' property is set to true. * @returns {void} - Set the height of row. */ Spreadsheet.prototype.setRowHeight = function (height, rowIndex, sheetIndex, edited, skipCustomRow) { if (height === void 0) { height = 20; } if (rowIndex === void 0) { rowIndex = 0; } var sheet = isNullOrUndefined(sheetIndex) ? this.getActiveSheet() : this.sheets[sheetIndex]; if (sheet) { var mIndex_2 = rowIndex; rowIndex = isNullOrUndefined(rowIndex) ? getCellIndexes(sheet.activeCell)[0] : rowIndex; if (skipCustomRow && sheet.rows[rowIndex] && sheet.rows[rowIndex].customHeight) { return; } var rowHeight_1 = (typeof height === 'number') ? height + 'px' : height; var setRowModel = function () { setRowHeight(sheet, mIndex_2, parseInt(rowHeight_1, 10) > 0 ? parseInt(rowHeight_1, 10) : 0); sheet.rows[mIndex_2].customHeight = true; }; if (sheet.id === this.getActiveSheet().id) { var frozenRow = this.frozenRowCount(sheet); if ((rowIndex >= this.viewport.topIndex + frozenRow && rowIndex <= this.viewport.bottomIndex) || (frozenRow && rowIndex < frozenRow)) { rowIndex = this.getViewportIndex(mIndex_2); var eleHeight = getRowHeight(sheet, mIndex_2, true); var threshold = getDPRValue(parseInt(rowHeight_1, 10)) - eleHeight; if (threshold < 0 && eleHeight < -(threshold)) { threshold = -eleHeight; } setRowModel(); this.notify(rowHeightChanged, { threshold: threshold, rowIdx: mIndex_2, isCustomHgt: true }); if (isNullOrUndefined(edited)) { edited = false; } if (!edited) { setResize(mIndex_2, rowIndex, rowHeight_1, false, this); edited = false; } } else { var oldHeight = getRowHeight(sheet, rowIndex); var threshold = void 0; if (parseInt(rowHeight_1, 10) > 0) { threshold = -(oldHeight - parseInt(rowHeight_1, 10)); } else { threshold = -oldHeight; } setRowModel(); this.notify(rowHeightChanged, { threshold: threshold, rowIdx: mIndex_2 }); } this.notify(positionAutoFillElement, null); } else { setRowModel(); } } }; /** * Allows you to set the height to the single or multiple rows. * * @param {number} height - Specifies the height for row. * @param {string[]} ranges - Specifies the row range to set the height. If the sheet name is not specified then height will apply to * the rows in the active sheet. Possible values are * * Single row range: ['2'] or ['2:2'] * * Multiple rows range: ['1:100'] * * Multiple rows with discontinuous range - ['1:10', '15:25', '30:40'] * * Multiple rows with different sheets - ['Sheet1!1:50', 'Sheet2!1:50', 'Sheet3!1:50']. * @param {boolean} skipCustomRows - When this parameter is enabled, it will skip updating the heights of rows where the height has already been modified, and its 'customHeight' property is set to true. * @returns {void} */ Spreadsheet.prototype.setRowsHeight = function (height, ranges, skipCustomRows) { if (height === void 0) { height = 20; } if (!ranges) { ranges = [1 + ":" + (this.getActiveSheet().usedRange.rowIndex + 1)]; } this.setSize(height, ranges, function (idx) { return Number(idx) - 1; }, this.setRowHeight.bind(this), skipCustomRows); }; /** * Allows you to set the width to the single or multiple columns. * * @param {number} width - Specifies the width for column. * @param {string[]} ranges - Specifies the column range to set the width. If the sheet name is not specified then width will apply to * the column in the active sheet. Possible values are * * Single column range: ['F'] or ['F:F'] * * Multiple columns range: ['A:F'] * * Multiple columns with discontinuous range - ['A:C', 'G:I', 'K:M'] * * Multiple columns with different sheets - ['Sheet1!A:H', 'Sheet2!A:H', 'Sheet3!A:H']. * @returns {void} */ Spreadsheet.prototype.setColumnsWidth = function (width, ranges) { if (width === void 0) { width = 64; } if (!ranges) { ranges = ["A:" + getColumnHeaderText(this.getActiveSheet().usedRange.colIndex + 1)]; } this.setSize(width, ranges, function (headerText) { return getColIndex(headerText); }, this.setColWidth.bind(this)); }; Spreadsheet.prototype.setSize = function (width, ranges, getIndex, updateSize, skipCustomRows) { var _this = this; var sheetIdx; var rangeArr; var sheetName; var startIdx; var endIdx; ranges.forEach(function (range) { if (range.includes('!')) { sheetName = range.substring(0, range.lastIndexOf('!')); sheetIdx = getSheetIndex(_this, sheetName); range = range.substring(range.lastIndexOf('!') + 1); } else { sheetIdx = _this.activeSheetIndex; } if (range.includes(':')) { rangeArr = range.split(':'); startIdx = getIndex(rangeArr[0]); endIdx = getIndex(rangeArr[1]); } else { startIdx = endIdx = getIndex(range); } for (var idx = startIdx; idx <= endIdx; idx++) { updateSize(width, idx, sheetIdx, false, skipCustomRows); } }); }; /** * This method is used to autofit the range of rows or columns * * {% codeBlock src='spreadsheet/autoFit/index.md' %}{% endcodeBlock %} * * @param {string} range - range of rows or columns that needs to be autofit. * * @returns {void} - used to autofit the range of rows or columns * ```html * <div id='Spreadsheet'></div> * ``` * ```typescript * let spreadsheet = new Spreadsheet({ * allowResizing: true * ... * }, '#Spreadsheet'); * spreadsheet.autoFit('A:D'); // Auto fit from A to D columns * Spreadsheet.autoFit('1:4'); // Auto fit from 1 to 4 rows * * ``` */ Spreadsheet.prototype.autoFit = function (range) { var sheetIdx; if (range.indexOf('!') !== -1) { sheetIdx = getSheetIndex(this, range.substring(0, range.lastIndexOf('!'))); range = range.substring(range.lastIndexOf('!') + 1); } var values = this.getIndexes(range); var startIdx = values.startIdx; var endIdx = values.endIdx; var isCol = values.isCol; var maximumColInx = isCol ? getColIndex('XFD') : 1048576; if (startIdx <= maximumColInx) { if (endIdx > maximumColInx) { endIdx = maximumColInx; } } else { return; } for (startIdx; startIdx <= endIdx; startIdx++) { this.notify(setAutoFit, { idx: startIdx, isCol: isCol, sheetIdx: sheetIdx }); } }; /** * @hidden * @param {string} range - specify the range. * @returns {number | boolean} - to get the index. * */ Spreadsheet.prototype.getIndexes = function (range) { var startIsCol; var endIsCol; var start; var end; if (range.indexOf(':') !== -1) { var starttoend = range.split(':'); start = starttoend[0]; end = starttoend[1]; } else { start = range; end = range; } if (!isNullOrUndefined(start)) { var startValues = this.getAddress(start); start = startValues.address; startIsCol = startValues.isCol; } if (!isNullOrUndefined(end)) { var endValues = this.getAddress(end); end = endValues.address; endIsCol = endValues.isCol; } var isCol = startIsCol === true && endIsCol === true ? true : false; var startIdx = isCol ? getColIndex(start.toUpperCase()) : parseInt(start, 10); var endIdx = isCol ? getColIndex(end.toUpperCase()) : parseInt(end, 10); return { startIdx: startIdx, endIdx: endIdx, isCol: isCol }; }; Spreadsheet.prototype.getAddress = function (address) { var isCol; if (address.substring(0, 1).match(/\D/g)) { isCol = true; address = address.replace(/[0-9]/g, ''); return { address: address, isCol: isCol }; } else if (address.substring(0, 1).match(/[0-9]/g) && address.match(/\D/g)) { return { address: '', isCol: false }; } else { address = (parseInt(address, 10) - 1).toString(); return { address: address, isCol: isCol }; } }; /** * To add the hyperlink in the cell * * {% codeBlock src='spreadsheet/addHyperlink/index.md' %}{% endcodeBlock %} * * @param {string | HyperlinkModel} hyperlink - to specify the hyperlink