@syncfusion/ej2-spreadsheet
Version:
Feature-rich JavaScript Spreadsheet (Excel) control with built-in support for selection, editing, formatting, importing and exporting to Excel
1,059 lines (1,058 loc) • 46.8 kB
JavaScript
import { isNullOrUndefined, isUndefined, Internationalization } from '@syncfusion/ej2-base';
import { getCell, isHiddenRow, isHiddenCol, getSheet, isFilterHidden, getColumn } from '../base/index';
import { getSwapRange, getRangeIndexes, setAutoFill, getFillInfo, getSheetIndexFromAddress, workbookLocale, workbookReadonlyAlert, isHeightCheckNeeded, applyCellFormat } from './../common/index';
import { checkIsFormula, getColumnHeaderText, isNumber, updateCFModel, isCustomDateTime } from './../index';
import { updateCell, intToDate, dateToInt, applyCF } from './../common/index';
import { checkDateFormat, parseFormulaArgument, wrapEvent, getUpdatedFormula } from '../common/index';
import { checkIsNumberAndGetNumber } from '../common/internalization';
/**
* WorkbookAutoFill module allows to perform auto fill functionalities.
*/
var WorkbookAutoFill = /** @class */ (function () {
/**
* Constructor for the workbook AutoFill module.
*
* @param {Workbook} parent - Specifies the workbook.
* @private
*/
function WorkbookAutoFill(parent) {
this.parent = parent;
this.addEventListener();
}
WorkbookAutoFill.prototype.getFillInfo = function (options) {
var l10n = this.parent.serviceLocator.getService(workbookLocale);
var val = '';
var isStringType = true;
var fillType = 'CopyCells';
var disableItems = [];
var isVFill = ['Down', 'Up'].indexOf(options.direction) > -1;
var data = this.getRangeData({ range: options.dataRange, sheetIdx: this.parent.activeSheetIndex });
var len = data.join().replace(/,/g, '').length;
var i = this.isRange(options.dataRange) && len ? data.length : 1;
while (i--) {
val = data[i] && !isNullOrUndefined(data[i].value) ? data[i].value : '';
if (isNumber(val) || checkIsFormula(val) || isNumber(val[val.length - 1])) {
isStringType = false;
fillType = this.parent.autoFillSettings.fillType;
break;
}
}
if (!len || isStringType) {
disableItems.push(l10n.getConstant('FillSeries'));
fillType = (options.fillType === 'FillSeries') ? fillType : options.fillType;
}
if (!isVFill || (isVFill && options.dataRange[1] !== options.dataRange[3])) {
disableItems.push('Flash Fill'); // for flash fill option
}
return { fillType: fillType, disableItems: disableItems };
};
WorkbookAutoFill.prototype.isRange = function (range) {
return range && (range[0] !== range[2] || range[1] !== range[3]);
};
WorkbookAutoFill.prototype.autoFill = function (options) {
if (!options.dataRange || !options.fillRange || !options.direction || !this.parent.allowEditing ||
(this.parent.getActiveSheet().isProtected && options.isLockedCell)) {
return;
}
var dataRangeIndices = getSwapRange(getRangeIndexes(options.dataRange));
var fillRangeIndices = getSwapRange(getRangeIndexes(options.fillRange));
var autoFillOptions = {
dataRange: dataRangeIndices, fillRange: fillRangeIndices, direction: options.direction, fillType: options.fillType || this.fillInfo.fillType, dataSheetIndex: getSheetIndexFromAddress(this.parent, options.dataRange),
fillSheetIndex: getSheetIndexFromAddress(this.parent, options.fillRange), cells: options.cells
};
this.fillInfo = this.getFillInfo({ dataRange: dataRangeIndices, fillRange: fillRangeIndices, fillType: options.fillType,
direction: options.direction });
this.fillInfo.fillType = options.isFillOptClick ? options.fillType : this.fillInfo.fillType;
switch (options.fillType) {
case 'FillSeries':
case 'FillWithoutFormatting':
this.fillSeries(autoFillOptions);
break;
case 'CopyCells':
case 'FillFormattingOnly':
this.copyCells(autoFillOptions);
break;
}
};
WorkbookAutoFill.prototype.fillSeries = function (options) {
var val;
var plen;
var patterns;
var patrn;
var pRanges;
var patrnRange;
var fillRange;
var data;
var nextStringValue;
var match;
var temp;
var dlen;
var j;
var k;
var l;
var tlen;
var tot;
var hasRef;
var cells;
var clen;
var cellIdx;
var cellProps = {};
var i = 0;
var prevCellData;
var dateVal;
var dateObj;
var dataSheetIndex = isUndefined(options.dataSheetIndex) ? this.parent.activeSheetIndex : options.dataSheetIndex;
var dataSheet = getSheet(this.parent, dataSheetIndex);
var fillSheetIndex;
var activeSheet;
if (isUndefined(options.fillSheetIndex)) {
fillSheetIndex = this.parent.activeSheetIndex;
activeSheet = true;
}
else {
fillSheetIndex = options.fillSheetIndex;
activeSheet = fillSheetIndex === this.parent.activeSheetIndex;
}
var fillSheet = getSheet(this.parent, fillSheetIndex);
var dminr = options.dataRange[0];
var dminc = options.dataRange[1];
var dmaxr = options.dataRange[2];
var dmaxc = options.dataRange[3];
var fminr = options.fillRange[0];
var fminc = options.fillRange[1];
var fmaxr = options.fillRange[2];
var fmaxc = options.fillRange[3];
var isVFill = ['Down', 'Up'].indexOf(options.direction) > -1;
var isReverseFill = ['Up', 'Left'].indexOf(options.direction) > -1;
var len = isVFill ? dmaxc - dminc : dmaxr - dminr;
var fillWithFrmt = options.fillType === 'FillSeries';
var prop;
var cfRefreshAll;
var cancel;
var cf = dataSheet.conditionalFormats && dataSheet.conditionalFormats.length &&
[].slice.call(dataSheet.conditionalFormats);
var cfRule = [];
var applyWrapToOuterCells = activeSheet && this.applyWrapToOuterCells(fillSheet);
var isRowHeightCheck = options.fillType !== 'FillWithoutFormatting' && activeSheet && isVFill;
while (i <= len) {
pRanges = this.updateFillValues(isVFill, dminr, dminc, dmaxr, dmaxc, fminr, fminc, fmaxr, fmaxc, i);
patrnRange = pRanges.patternRange;
fillRange = pRanges.fillRange;
patterns = this.getPattern(patrnRange, { isReverseFill: isReverseFill, isVFill: isVFill }, dataSheetIndex);
data = this.getRangeData({ range: patrnRange, sheetIdx: dataSheetIndex });
if (!isVFill) {
data = this.getRangeData({ range: patrnRange, sheetIdx: dataSheetIndex }, true);
}
var isRefFormula = false;
if (data[0] && data[0].formula && data[0].formula.match(/=[A-Za-z]+\(([^:]+):([^:]+)\)/)) {
isRefFormula = true;
}
dlen = data.length;
for (var l_1 = 0; l_1 < dlen; l_1++) {
if (data[l_1] && data[l_1].isReadOnly) {
this.parent.notify(workbookReadonlyAlert, null);
return;
}
}
if (!patterns || !patterns.length) {
return;
}
plen = patterns.length;
cells = this.getSelectedRange(fillSheet, { rowIndex: fillRange[0], colIndex: fillRange[1] }, { rowIndex: fillRange[2],
colIndex: fillRange[3] });
clen = cells.length;
if (isReverseFill) {
cells = cells.reverse();
patterns = patterns.reverse();
patterns = this.ensurePattern(patterns);
data = data.reverse();
}
j = 0;
while (j < clen) {
cellIdx = cells[j];
patrn = patterns[j % plen];
if (isNumber(patrn)) {
patrn = patterns[patrn];
}
l = j % dlen;
switch (patrn['type']) {
case 'number':
case 'date':
patrn = patrn;
if (patrn.isStartWithMonth && dlen === 1) {
dateVal = intToDate(patrn.regVal.a);
dateObj = new Date(dateVal);
dateVal.setMonth(dateVal.getMonth() + (patrn.regVal.b * patrn.i));
if (dateObj.getDate() > 28 && dateObj.getDate() !== dateVal.getDate()) {
dateObj.setDate(1);
dateObj.setMonth(dateObj.getMonth() + (patrn.regVal.b * patrn.i));
dateObj.setDate(new Date(dateObj.getFullYear(), dateObj.getMonth() + 1, 0).getDate());
dateVal = dateObj;
}
val = dateToInt(dateVal).toString();
}
else {
val = (this.round(patrn['regVal'].a + (patrn['regVal'].b * patrn['i']), 5)).toString();
if (patrn.val) {
match = (typeof (patrn.val[0]) === 'string') && patrn.val[0].match(/^0+/);
if (match) {
nextStringValue = this.getNextFormattedValue(patrn.val[0], Number(val));
}
}
}
if (patrn.dataVal) {
if (patrn.copy === undefined && !match) {
patrn.copy = patrn.val.length > 2;
if (patrn.copy) {
for (var m = 2; m < patrn.val.length; m++) {
patrn.copy = Math.abs(this.round(patrn['regVal'].a + (patrn['regVal'].b * m), 5)) !==
patrn.val[m];
if (patrn.copy) {
break;
}
}
}
}
val = patrn.copy ? (data[l] && !isNullOrUndefined(data[l].value) ? data[l].value : '') :
(patrn.start ? Math.abs(Number(val)) + patrn.dataVal :
(match ? patrn.dataVal + nextStringValue : patrn.dataVal + Math.abs(Number(val))));
}
if (isReverseFill) {
patrn['i']--;
}
else {
patrn['i']++;
}
break;
case 'string':
// eslint-disable-next-line no-case-declarations
var newVal = patrn['i'] % patrn['val'].length;
val = patrn['val'][newVal];
patrn['i']++;
break;
case 'formula':
hasRef = false;
val = '=';
k = 0;
tlen = patrn['val'].length;
while (k < tlen) {
temp = patrn['val'][k];
if (typeof temp === 'object') {
hasRef = true;
tot = this.round(temp['a'] + (temp['b'] * patrn['i']), 5);
if (tot < 1) {
val += '#REF!';
if (isRefFormula) {
k = tlen - 1;
val += patrn['val'][k];
}
}
else {
val += isVFill ? temp['c'] + (temp['b'] ? tot : '$' + tot) : (temp['b'] ? getColumnHeaderText(tot) : temp['c'].substring(0, temp['c'].search(/\d/)) + '$' + getColumnHeaderText(tot)) + temp['c'].trim();
}
}
else {
val += temp;
}
k++;
}
if (hasRef && isReverseFill) {
patrn['i']--;
}
else {
patrn['i']++;
}
break;
case 'time':
val = (patrn['regVal'].a + (patrn['regVal'].b * patrn['i'])).toString();
if (Number(val) < 0 && isReverseFill) {
val = ((patrn['regVal'].a + Math.ceil(Math.abs(patrn['i'] / 24))) + (patrn['regVal'].b * patrn['i'])).toString();
}
if (isReverseFill) {
patrn['i']--;
}
else {
patrn['i']++;
}
break;
}
prevCellData = getCell(cellIdx.rowIndex, cellIdx.colIndex, fillSheet, false, true);
if (prevCellData && prevCellData.isReadOnly) {
this.parent.notify(workbookReadonlyAlert, null);
return;
}
if (fillWithFrmt) {
Object.assign(cellProps, data[l], null, true);
}
else {
if (options.fillType === 'FillWithoutFormatting' && data[l] && data[l].hyperlink) {
cellProps.hyperlink = data[l].hyperlink;
cellProps.style = { textDecoration: 'none', color: 'inherit' };
}
else {
cellProps.style = prevCellData.style;
}
cellProps.format = prevCellData.format;
cellProps.wrap = prevCellData.wrap;
cellProps.rowSpan = prevCellData.rowSpan;
cellProps.colSpan = prevCellData.colSpan;
}
if (data[l] && data[l].validation) {
cellProps.validation = Object.assign({}, data[l].validation);
var currIdx = [cellIdx.rowIndex, cellIdx.colIndex, cellIdx.rowIndex, cellIdx.colIndex];
var prevIdx = [options.dataRange[0], options.dataRange[1], options.dataRange[2], options.dataRange[3]];
var sheet = this.parent.sheets[this.parent.activeSheetIndex];
var updatedValue = getUpdatedFormula(currIdx, prevIdx, sheet, this.parent, { formula: cellProps.validation.value1 });
cellProps.validation.value1 = updatedValue;
if (cellProps.validation.value2 !== '') {
updatedValue = getUpdatedFormula(currIdx, prevIdx, sheet, this.parent, { formula: cellProps.validation.value2 });
cellProps.validation.value2 = updatedValue;
}
}
var isFormula = checkIsFormula(val);
if (isFormula) {
cellProps.formula = val;
}
if (val !== '0' || (val === '0' && options.fillType !== 'FillWithoutFormatting')) {
cellProps.value = isFormula && this.parent.calculationMode === 'Manual' ?
(data[l] ? data[l].value : '0') : val;
}
if (!isNullOrUndefined(cellProps.notes)) {
delete cellProps.notes;
}
prop = { cell: cellProps, rowIdx: cellIdx.rowIndex, colIdx: cellIdx.colIndex, valChange: true, uiRefresh: activeSheet,
pvtExtend: true, skipFormatCheck: true, fillType: options.fillType };
if (activeSheet && !isHiddenRow(fillSheet, cellIdx.rowIndex) && !isHiddenCol(fillSheet, cellIdx.colIndex)) {
prop.td = this.parent.getCell(cellIdx.rowIndex, cellIdx.colIndex);
if (prop.td) {
prop.uiRefresh = true;
}
}
cancel = updateCell(this.parent, fillSheet, prop, options.cells);
if (!cancel) {
if (activeSheet) {
applyWrapToOuterCells(prop);
}
if (cf && !cfRefreshAll) {
cfRefreshAll = prop.isFormulaDependent;
if (!cfRefreshAll) {
updateCFModel(cf, cfRule, cellIdx.rowIndex, cellIdx.colIndex, options.dataRange, options.fillRange, dataSheet);
}
}
if (isRowHeightCheck && cellProps.style && isHeightCheckNeeded(cellProps.style)) {
this.parent.notify(applyCellFormat, {
rowIdx: cellIdx.rowIndex, colIdx: cellIdx.colIndex, style: cellProps.style,
lastCell: true, isHeightCheckNeeded: true, onActionUpdate: true, manualUpdate: true
});
}
}
cellProps = {};
j++;
}
i++;
}
if (cfRule.length || cfRefreshAll) {
this.parent.notify(applyCF, { cfModel: !cfRefreshAll && cfRule, refreshAll: cfRefreshAll, isAction: true, isEdit: true });
}
};
WorkbookAutoFill.prototype.copyCells = function (options) {
var i = 0;
var j;
var k;
var patrnRange;
var fillRange;
var pRanges;
var data;
var dlen;
var cells;
var clen;
var cellProperty = {};
var cellIdx;
var dMinR = options.dataRange[0];
var dMinC = options.dataRange[1];
var dMaxR = options.dataRange[2];
var dMaxC = options.dataRange[3];
var fMinR = options.fillRange[0];
var fMinC = options.fillRange[1];
var fMaxR = options.fillRange[2];
var fMaxC = options.fillRange[3];
var isVFill = ['Down', 'Up'].indexOf(options.direction) > -1;
var isReverseFill = ['Up', 'Left'].indexOf(options.direction) > -1;
var len = isVFill ? dMaxC - dMinC : dMaxR - dMinR;
var dataSheetIndex = isUndefined(options.dataSheetIndex) ? this.parent.activeSheetIndex : options.dataSheetIndex;
var dataSheet = getSheet(this.parent, dataSheetIndex);
var fillSheetIndex;
var activeSheet;
if (isUndefined(options.fillSheetIndex)) {
activeSheet = true;
fillSheetIndex = this.parent.activeSheetIndex;
}
else {
activeSheet = options.fillSheetIndex === this.parent.activeSheetIndex;
fillSheetIndex = options.fillSheetIndex;
}
var fillSheet = getSheet(this.parent, fillSheetIndex);
var formatOnly = options.fillType === 'FillFormattingOnly';
var prevCellData;
var cfRefreshAll;
var prop;
var cf = dataSheet.conditionalFormats && dataSheet.conditionalFormats.length &&
[].slice.call(dataSheet.conditionalFormats);
var cancel;
var applyWrapToOuterCells = activeSheet && this.applyWrapToOuterCells(fillSheet);
var cfRule = [];
var isRowHeightCheck = activeSheet && isVFill;
while (i <= len) {
pRanges = this.updateFillValues(isVFill, dMinR, dMinC, dMaxR, dMaxC, fMinR, fMinC, fMaxR, fMaxC, i);
patrnRange = pRanges.patternRange;
fillRange = pRanges.fillRange;
data = this.getRangeData({ range: patrnRange, sheetIdx: dataSheetIndex });
dlen = data.length;
for (var m = 0; m < dlen; m++) {
if (data[m] && data[m].isReadOnly) {
this.parent.notify(workbookReadonlyAlert, null);
return;
}
}
cells = this.getSelectedRange(fillSheet, { rowIndex: fillRange[0], colIndex: fillRange[1] }, { rowIndex: fillRange[2], colIndex: fillRange[3] });
clen = cells.length;
j = 0;
if (isReverseFill) {
cells = cells.reverse();
}
while (j < clen) {
k = j % dlen;
cellIdx = cells[j];
if (formatOnly) {
prevCellData = getCell(cellIdx.rowIndex, cellIdx.colIndex, fillSheet);
}
Object.assign(cellProperty, data[k], null, true);
if (formatOnly) {
cellProperty.value = prevCellData.value;
cellProperty.formula = prevCellData.formula;
if (!isNullOrUndefined(cellProperty.notes)) {
delete cellProperty.notes;
}
if (cellProperty.validation) {
delete cellProperty.validation;
}
}
if (cellProperty && cellProperty.isReadOnly) {
this.parent.notify(workbookReadonlyAlert, null);
return;
}
if (!isNullOrUndefined(cellProperty.notes) && !isNullOrUndefined(cellProperty.isNoteEditable)) {
delete cellProperty.notes;
delete cellProperty.isNoteEditable;
}
prop = { cell: cellProperty, rowIdx: cellIdx.rowIndex, colIdx: cellIdx.colIndex, valChange: true,
pvtExtend: true, fillType: options.fillType };
if (activeSheet && !isHiddenRow(fillSheet, cellIdx.rowIndex) && !isHiddenCol(fillSheet, cellIdx.colIndex)) {
prop.td = this.parent.getCell(cellIdx.rowIndex, cellIdx.colIndex);
prop.uiRefresh = !!prop.td;
}
cancel = updateCell(this.parent, fillSheet, prop, options.cells);
if (!cancel) {
if (activeSheet) {
applyWrapToOuterCells(prop);
}
if (cf && !cfRefreshAll) {
cfRefreshAll = prop.isFormulaDependent;
if (!cfRefreshAll) {
updateCFModel(cf, cfRule, cellIdx.rowIndex, cellIdx.colIndex, options.dataRange, options.fillRange, dataSheet);
}
}
if (isRowHeightCheck && cellProperty.style && isHeightCheckNeeded(cellProperty.style)) {
this.parent.notify(applyCellFormat, {
rowIdx: cellIdx.rowIndex, colIdx: cellIdx.colIndex, style: cellProperty.style,
lastCell: true, isHeightCheckNeeded: true, onActionUpdate: true, manualUpdate: true
});
}
}
cellProperty = {};
j++;
}
i++;
}
if (cfRule.length || cfRefreshAll) {
this.parent.notify(applyCF, { cfModel: !cfRefreshAll && cfRule, refreshAll: cfRefreshAll, isAction: true, isEdit: true });
}
};
WorkbookAutoFill.prototype.applyWrapToOuterCells = function (sheet) {
var _this = this;
var viewTopIdx;
var viewLeftIdx;
var frozenRow = this.parent.frozenRowCount(sheet);
var frozenCol = this.parent.frozenColCount(sheet);
var viewport = this.parent.viewport;
if (viewport) {
viewTopIdx = viewport.topIndex + frozenRow;
viewLeftIdx = viewport.leftIndex + frozenCol;
}
var wrapArgs;
return function (options) {
if (!options.td && getCell(options.rowIdx, options.colIdx, sheet, false, true).wrap && ((options.rowIdx >= frozenRow &&
options.rowIdx < viewTopIdx) || (options.colIdx >= frozenCol && options.colIdx < viewLeftIdx))) {
if (!wrapArgs) {
wrapArgs = { range: null, wrap: true, sheet: sheet, initial: true, outsideViewport: true };
}
wrapArgs.range = [options.rowIdx, options.colIdx, options.rowIdx, options.colIdx];
_this.parent.notify(wrapEvent, wrapArgs);
}
};
};
WorkbookAutoFill.prototype.updateFillValues = function (isVFill, dminr, dminc, dmaxr, dmaxc, fminr, fminc, fmaxr, fmaxc, i) {
var pStart;
var pEnd;
var fStart;
var fEnd;
if (isVFill) {
pStart = { rowIndex: dminr, colIndex: dminc + i };
pEnd = { rowIndex: dmaxr, colIndex: dminc + i };
fStart = { rowIndex: fminr, colIndex: fminc + i };
fEnd = { rowIndex: fmaxr, colIndex: fminc + i };
}
else {
pStart = { rowIndex: dminr + i, colIndex: dminc };
pEnd = { rowIndex: dminr + i, colIndex: dmaxc };
fStart = { rowIndex: fminr + i, colIndex: fminc };
fEnd = { rowIndex: fminr + i, colIndex: fmaxc };
}
var patternRange = [pStart.rowIndex, pStart.colIndex, pEnd.rowIndex, pEnd.colIndex];
var fillRange = [fStart.rowIndex, fStart.colIndex, fEnd.rowIndex, fEnd.colIndex];
return { patternRange: patternRange, fillRange: fillRange };
};
WorkbookAutoFill.prototype.getDataPattern = function (range, sheetIdx) {
var val;
var numValue;
var type;
var i = 0;
var obj = { val: null,
type: null };
var patrn = [];
var data = this.getRangeData({
range: range, sheetIdx: isUndefined(sheetIdx) ? this.parent.activeSheetIndex
: sheetIdx
});
var dlen = data.length;
var isStartNum;
var isDateStartsWithMonth;
if (dlen) {
var count = void 0;
var dataVal = void 0;
var format = void 0;
var isNumVal = void 0;
var minusOperator = function (data) {
return !isStartNum && data && data[data.length - 1] === '-' ? data.slice(0, data.length - 1) : data;
};
while (i < dlen) {
isDateStartsWithMonth = false;
if (data[i]) {
if (data[i].formula && checkIsFormula(data[i].formula)) {
val = data[i].formula;
type = 'formula';
}
else {
val = isNullOrUndefined(data[i].value) ? '' : data[i].value;
var option = {};
format = data[i].format;
isNumVal = isNumber(val);
if (format && isCustomDateTime(format, true, option) && val !== '') {
type = option.type;
if (val && !isNumVal) {
var dateEventArgs = { value: val, updatedVal: val, cell: data[i] };
this.parent.notify(checkDateFormat, dateEventArgs);
if (dateEventArgs.isDate || dateEventArgs.isTime) {
data[i].value = val = dateEventArgs.updatedVal;
}
else {
type = 'string';
}
}
isDateStartsWithMonth = type === 'date' && format.toLowerCase().startsWith('mmm');
}
else {
type = isNumVal ? 'number' : 'string';
}
}
}
else {
val = '';
type = 'string';
}
dataVal = '';
if (type === 'string') {
isStartNum = false;
if (isNumber(val[0])) {
count = 0;
do {
count++;
} while (isNumber(val[count]));
if (val[count] === ' ') {
isStartNum = true;
type = 'number';
dataVal = val.slice(count, val.length);
val = Number(val.slice(0, count));
}
}
val = val;
if (!isStartNum && isNumber(val[val.length - 1])) {
count = 1;
do {
count++;
} while (isNumber(val[val.length - count]));
type = 'number';
count -= 1;
dataVal = val.slice(0, val.length - count);
numValue = val.slice(val.length - count, val.length);
val = numValue.match(/^0+/) ? numValue : Number(numValue);
if (obj.dataVal && obj.dataVal !== dataVal && obj.dataVal === minusOperator(dataVal)) {
dataVal = obj.dataVal;
}
}
}
if (i === 0) {
obj = { val: [val], type: type, isStartWithMonth: isDateStartsWithMonth };
if (dataVal) {
obj.dataVal = dataVal;
obj.start = isStartNum;
}
}
else if (type === obj.type && (!obj.dataVal || minusOperator(obj.dataVal) === minusOperator(dataVal))) {
obj.val.push(val);
}
else {
patrn.push(obj);
obj = { val: [val], type: type };
if (dataVal) {
obj.dataVal = dataVal;
obj.start = isStartNum;
}
}
i++;
}
patrn.push(obj);
return patrn;
}
else {
return [{ val: null, type: null }];
}
};
WorkbookAutoFill.prototype.getPredictionValue = function (args, isTime) {
var i = 0;
var sumx = 0;
var sumy = 0;
var sumxy = 0;
var sumxx = 0;
var a = 0;
var b = 0;
var n = args.length;
while (i < n) {
sumx = sumx + i;
sumy = sumy + Number(args[i]);
sumxy = sumxy + (i * Number(args[i]));
sumxx = sumxx + (i * i);
i++;
}
if (!isTime) {
a = this.round(((sumy * sumxx) - (sumx * sumxy)) / ((n * sumxx) - (sumx * sumx)), 5);
b = this.round(((n * sumxy) - (sumx * sumy)) / ((n * sumxx) - (sumx * sumx)), 5);
}
else {
a = ((sumy * sumxx) - (sumx * sumxy)) / ((n * sumxx) - (sumx * sumx));
b = ((n * sumxy) - (sumx * sumy)) / ((n * sumxx) - (sumx * sumx));
}
return { a: a, b: b };
};
WorkbookAutoFill.prototype.getPattern = function (range, options, sheetIdx) {
var j;
var idx;
var temp;
var regVal;
var diff;
var len;
var i = 0;
var pattern = [];
var patrns = this.getDataPattern(range, sheetIdx);
var plen = patrns.length;
var patrn;
if (patrns) {
while (i < plen) {
patrn = patrns[i];
switch (patrn.type) {
case 'number':
case 'date':
idx = pattern.length;
len = patrn.val.length;
diff = options.isReverseFill ? -1 : len;
if (len === 1) {
var newVal = parseFloat(patrn.val[0]) + 1;
if (typeof (patrn.val[0]) === 'string' && patrn.val[0].match(/^0+/)) {
patrn.val.push(this.getNextFormattedValue(patrn.val[0], newVal));
}
else {
patrn.val.push(newVal);
}
}
regVal = this.getPredictionValue(patrn.dataVal ? patrn.val.slice(0, 2) : patrn.val);
temp = { regVal: regVal, type: patrn.type, i: diff, isStartWithMonth: patrn.isStartWithMonth };
if (patrn.dataVal) {
temp.dataVal = patrn.dataVal;
temp.val = patrn.val;
temp.start = patrn.start;
}
pattern.push(temp);
j = 1;
while (j < len) {
pattern.push(idx);
j++;
}
break;
case 'string':
idx = pattern.length;
temp = { val: patrn.val, type: patrn.type, i: 0 };
pattern.push(temp);
j = 1;
len = patrn.val.length;
while (j < len) {
pattern.push(idx);
j++;
}
break;
case 'formula':
len = patrn.val.length;
patrn = this.getFormulaPattern(patrn.val, options);
diff = options.isReverseFill ? -1 : len;
if (patrn.isInPattern) {
idx = pattern.length;
temp = { val: patrn.val, type: 'formula', i: diff };
pattern.push(temp);
j = 1;
while (j < len) {
pattern.push(idx);
j++;
}
}
else {
j = 0;
diff = options.isReverseFill ? -1 : 1;
while (j < len) {
pattern.push({ val: patrn.val[j], type: 'formula', i: diff });
j++;
}
}
break;
case 'time':
idx = pattern.length;
len = patrn.val.length;
diff = options.isReverseFill ? -1 : len;
if (len === 1) {
var oldTimeVal = intToDate(patrn.val[0]);
var patrnVal = Number(patrn.val[0]);
var isTimeOnly = patrnVal >= 0 && patrnVal < 1;
var newTimeVal = dateToInt(new Date(oldTimeVal.getTime() + 60 * 60000), true, isTimeOnly);
patrn.val.push(newTimeVal);
}
regVal = this.getPredictionValue(patrn.val, true);
temp = { regVal: regVal, type: patrn.type, i: diff };
pattern.push(temp);
j = 1;
while (j < len) {
pattern.push(idx);
j++;
}
break;
default:
break;
}
i++;
}
return pattern;
}
else {
return [{ regVal: null }];
}
};
WorkbookAutoFill.prototype.getNextFormattedValue = function (value, numValue) {
var val = new Internationalization().formatNumber(Math.abs(numValue), { minimumIntegerDigits: value.length, useGrouping: false });
var numeArgs = checkIsNumberAndGetNumber({ value: val }, this.parent.locale);
return numeArgs.isNumber ? numeArgs.value : val;
};
WorkbookAutoFill.prototype.isCellReference = function (text) {
return /^[a-z]{1,3}\d{1,7}$/gi.test(text) ? 'relative' : (/^\$[a-z]{1,3}\$\d{1,7}$/gi.test(text) ? 'absolute' : (/^((\$[a-z]{1,3})\d{1,7}|[a-z]{1,3}(\$\d{1,7}))$/gi.test(text) ? 'mixed' : false));
};
WorkbookAutoFill.prototype.round = function (value, round) {
return Number(Math.round(parseFloat(value + 'e' + round)) + 'e-' + round) || Number(value);
};
WorkbookAutoFill.prototype.getRangeData = function (options, isVFill) {
var arr = [];
var sheet = isUndefined(options.sheetIdx) ? this.parent.getActiveSheet() : getSheet(this.parent, options.sheetIdx);
var minR = options.range[0];
var minC = options.range[1];
var maxR = options.range[2];
var maxC = options.range[3];
var minCol = minC;
var cell;
var column;
while (minR <= maxR) {
if (isHiddenRow(sheet, minR)) {
minR++;
continue;
}
minC = minCol;
while (minC <= maxC) {
if (isHiddenCol(sheet, minC)) {
minC++;
continue;
}
cell = getCell(minR, minC, sheet);
if (isVFill) {
cell = Object.assign({}, getCell(minR, minC, sheet));
column = Object.assign({}, getColumn(sheet, minC));
if (cell && !cell.validation) {
if (column && column.validation) {
cell.validation = Object.assign({}, getColumn(sheet, minC).validation);
var currIdx = [minR, minC, minR, minC];
var prevIdx = [0, minC, 0, minC];
var updateVal = getUpdatedFormula(currIdx, prevIdx, sheet, this.parent, { formula: column.validation.value1 });
cell.validation.value1 = updateVal;
if (cell.validation.value2 !== '') {
updateVal = getUpdatedFormula(currIdx, prevIdx, sheet, this.parent, { formula: column.validation.value2 });
cell.validation.value2 = updateVal;
}
}
}
}
arr.push(cell);
minC++;
}
minR++;
}
return arr;
};
WorkbookAutoFill.prototype.getFormulaPattern = function (data, options) {
var j;
var temp;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
var patrn;
var patrns = [];
var i = 0;
var len = data.length;
var cRfrType;
var eventArgs = {};
while (i < len) {
eventArgs.formula = data[i];
this.parent.notify(parseFormulaArgument, eventArgs);
patrns.push(eventArgs.formulaArr);
i++;
}
var isInPatrn = this.isInPattern(patrns, options.isVFill);
if (isInPatrn) {
patrn = patrns[0];
i = patrn.length;
while (i--) {
temp = patrn[i];
cRfrType = this.isCellReference(temp);
if (cRfrType && (cRfrType !== 'absolute')) {
patrn[i] = this.getCellRefPrediction(temp, options, null, cRfrType);
}
}
return { isInPattern: isInPatrn, val: patrn };
}
else {
i = 0;
while (i < len) {
patrn = patrns[i];
j = patrn.length;
while (j--) {
temp = patrn[j];
cRfrType = this.isCellReference(temp.trim());
if (cRfrType && (cRfrType !== 'absolute')) {
patrns[i][j] = this.getCellRefPrediction(temp, options, len, cRfrType);
}
}
i++;
}
return { isInPattern: isInPatrn, val: patrns };
}
};
WorkbookAutoFill.prototype.generateColCount = function (text) {
var colCount = 0;
for (var i = 0; i < text.length; i++) {
var charValue = text.charCodeAt(i) - 64;
colCount = colCount * 26 + charValue;
}
return colCount;
};
WorkbookAutoFill.prototype.getCellRefPrediction = function (text, options, length, rfrType) {
text = text.toUpperCase();
var eStr = '';
var aRegx = new RegExp('[a-z$]', 'gi');
var nRegx = new RegExp('[0-9$]', 'g');
var str = options.isVFill ? text.replace(nRegx, eStr) : text.replace(aRegx, eStr);
var temp = options.isVFill ? Number(text.replace(aRegx, eStr)) :
this.generateColCount(text.replace(nRegx, eStr).trim());
var dollarPosition = null;
var arr = [temp];
var isColAbslt = text[0] === '$';
if (!isColAbslt && text.includes('$') && text.trim()[0] === '$') {
for (var idx = 1; idx < text.length; idx++) {
if (text[idx] === '$') {
dollarPosition = idx;
isColAbslt = true;
break;
}
}
}
if (length && length !== 1) {
arr.push(temp + length);
}
else {
arr.push(temp + 1);
}
temp = this.getPredictionValue(arr);
if (rfrType && (rfrType === 'mixed')) {
if (isColAbslt === options.isVFill) {
if (dollarPosition) {
str = str.substring(0, dollarPosition) + '$' + str.substring(dollarPosition);
}
else {
str = '$' + str;
}
}
else {
temp['b'] = 0;
}
}
temp['c'] = str;
return temp;
};
WorkbookAutoFill.prototype.isInPattern = function (patrn, isVFill) {
var oldPatrn;
var olen;
var newPatrn;
var nlen;
var oldStr;
var newStr;
var oldInt;
var newInt;
var eStr = '';
var i = 0;
var j = 1;
var plen = patrn.length;
var nregx = new RegExp('[0-9$]', 'g');
var aregx = new RegExp('[a-z$]', 'gi');
if (plen === 1) {
return false;
}
while (j < plen) {
oldPatrn = patrn[i];
newPatrn = patrn[j];
olen = oldPatrn.length;
nlen = newPatrn.length;
if (olen !== nlen) {
return false;
}
else {
while (olen--) {
oldStr = oldPatrn[olen];
newStr = newPatrn[olen];
if (this.isCellReference(oldStr) === this.isCellReference(newStr)) {
if (isVFill) {
oldInt = Number(oldStr.replace(aregx, eStr));
newInt = Number(newStr.replace(aregx, eStr));
}
else {
oldInt = this.generateColCount(oldStr.replace(nregx, eStr));
newInt = this.generateColCount(newStr.replace(nregx, eStr));
}
if (oldInt !== newInt - 1) {
return false;
}
}
else if (oldStr !== newStr) {
return false;
}
}
}
i++;
j++;
}
return true;
};
WorkbookAutoFill.prototype.ensurePattern = function (patterns) {
var patrn;
var idx = -1;
var i = patterns.length;
while (i--) {
patrn = patterns[i];
if (typeof (patrn) === 'object') {
idx = i;
if (patrn.type === 'string') {
patrn.val = patrn.val.reverse();
}
}
else {
patterns[i] = idx;
}
}
return patterns;
};
WorkbookAutoFill.prototype.getSelectedRange = function (sheet, startcell, endcell) {
var i;
var k;
var l;
var arr = [];
var range = getSwapRange([startcell.rowIndex, startcell.colIndex, endcell.rowIndex, endcell.colIndex]);
i = range[0];
var j = range[2];
while (i <= j) {
if (isFilterHidden(sheet, i)) {
i++;
continue;
}
k = range[1];
l = range[3];
while (k <= l) {
arr.push({ rowIndex: i, colIndex: k });
k++;
}
i++;
}
return arr;
};
WorkbookAutoFill.prototype.getFillType = function (args) {
args.fillType = this.fillInfo.fillType;
args.disableItems = this.fillInfo.disableItems;
return args;
};
WorkbookAutoFill.prototype.addEventListener = function () {
this.parent.on(setAutoFill, this.autoFill, this);
this.parent.on(getFillInfo, this.getFillType, this);
};
/**
* Destroy workbook AutoFill module.
*
* @returns {void} - destroy the workbook AutoFill module.
*/
WorkbookAutoFill.prototype.destroy = function () {
this.removeEventListener();
this.parent = null;
};
WorkbookAutoFill.prototype.removeEventListener = function () {
if (!this.parent.isDestroyed) {
this.parent.off(setAutoFill, this.autoFill);
this.parent.off(getFillInfo, this.getFillType);
}
};
/**
* Get the workbook AutoFill module name.
*
* @returns {string} - Return the string.
*/
WorkbookAutoFill.prototype.getModuleName = function () {
return 'workbookautofill';
};
return WorkbookAutoFill;
}());
export { WorkbookAutoFill };