产品一张表luckysheet前端代码库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2854 lines
96 KiB

import Store from "../store";
import { replaceHtml, getObjType, chatatABC } from "../utils/util";
import { getSheetIndex, getluckysheet_select_save } from "../methods/get";
import locale from "../locale/locale";
import formula from './formula';
import func_methods from "./func_methods";
import tooltip from "./tooltip";
import json from "./json";
import editor from "./editor";
import luckysheetformula from './formula';
import cleargridelement from './cleargridelement';
import { genarate, update } from './format';
import { setAccuracy } from "./setdata";
import { orderbydata } from "./sort";
import { rowlenByRange } from "./getRowlen";
import { getdatabyselection, getcellvalue } from "./getdata";
import { luckysheetrefreshgrid, jfrefreshgrid, jfrefreshgrid_rhcw } from "./refresh";
import { luckysheetDeleteCell, luckysheetextendtable, luckysheetdeletetable } from "./extend";
import { isRealNull, valueIsError, isRealNum, isEditMode, hasPartMC } from "./validate";
import server from "../controllers/server";
import selection from "../controllers/selection";
import luckysheetConfigsetting from "../controllers/luckysheetConfigsetting";
import luckysheetFreezen from "../controllers/freezen";
import luckysheetsizeauto from '../controllers/resize';
import sheetmanage from '../controllers/sheetmanage';
import { luckysheet_searcharray } from "../controllers/sheetSearch";
import { selectIsOverlap } from '../controllers/select';
import { sheetHTML } from '../controllers/constant';
const IDCardReg = /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i;
/**
* 获取单元格的值
* @param {Number} row 单元格所在行数从0开始的整数0表示第一行
* @param {Number} column 单元格所在列数从0开始的整数0表示第一列
* @param {Object} options 可选参数
* @param {String} options.type 单元格的值类型可以设置为原始值"v"或者显示值"m"默认值为'v',表示获取单元格的实际值
* @param {Number} options.order 工作表索引默认值为当前工作表索引
*/
export function getCellValue(row, column, options = {}) {
if (row == null && column == null) {
return tooltip.info('Arguments row or column cannot be null or undefined.', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
type = 'v',
order = curSheetOrder
} = { ...options };
let targetSheetData = Store.luckysheetfile[order].data;
let cellData = targetSheetData[row][column];
let return_v;
if(getObjType(cellData) == "object"){
return_v = cellData[type];
if (type == "f" && return_v != null) {
return_v = formula.functionHTMLGenerate(return_v);
}
else if(type == "f") {
return_v = cellData["v"];
}
else if(cellData && cellData.ct && cellData.ct.fa == 'yyyy-MM-dd') {
return_v = cellData.m;
}
}
if(return_v == undefined){
return_v = null;
}
return return_v;
}
/**
* 设置单元格的值
*
* 关键点如果设置了公式则需要更新公式链insertUpdateFunctionGroup如果设置了不是公式判断之前是公式则需要清除公式delFunctionGroup
*
* @param {Number} row 单元格所在行数从0开始的整数0表示第一行
* @param {Number} column 单元格所在列数从0开始的整数0表示第一列
* @param {Object | String | Number} value 要设置的值可以为字符串或数字或为符合Luckysheet单元格格式的对象
* @param {Object} options 可选参数
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Boolean} options.isRefresh 是否刷新界面默认为`true`
* @param {Function} options.success 操作结束的回调函数
*/
// export function setCellValue(row, column, value, options = {}) {
// if (row == null && column == null) {
// return tooltip.info('Arguments row or column cannot be null or undefined.', '')
// }
// let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
// let {
// order = curSheetOrder,
// success
// } = {...options}
// let targetSheetData = Store.luckysheetfile[order].data;
// let cell = targetSheetData[row][column];
// let vupdate;
// if (getObjType(value) == 'object') {
// cell = value;
// if (getObjType(value.v) == 'object') {
// vupdate = vaule.v.v;
// } else {
// vupdate = value.v;
// }
// } else {
// vupdate = value;
// }
// if (isRealNull(vupdate)) {
// if (getObjType(cell) == 'object') {
// delete cell.m;
// delete cell.v;
// } else {
// cell = null;
// }
// return;
// }
// if (isRealNull(cell)) {
// cell = {}
// }
// if (vupdate.toString().substring(0, 1) == "'") {
// cell.m = vupdate.toString().substring(1);
// cell.ct = { "fa": "@", "t": "s" };
// cell.v = vupdate.toString().substring(1);
// } else if (vupdate.toString().toUpperCase() === 'TRUE') {
// cell.m = "TRUE";
// cell.ct = { "fa": "General", "t": "b" };
// cell.v = true;
// } else if (vupdate.toString().toUpperCase() === 'FALSE') {
// cell.m = "FALSE";
// cell.ct = { "fa": "General", "t": "b" };
// cell.v = false;
// } else if (valueIsError(vupdate)) {
// cell.m = vupdate.toString();
// cell.ct = { "fa": "General", "t": "e" };
// cell.v = vupdate;
// } else {
// if (cell.f != null && isRealNum(vupdate) && !IDCardReg.test(vupdate)) {
// cell.v = parseFloat(vupdate);
// if (cell.ct == null) {
// cell.ct = {
// 'fa': 'General',
// 't': 'n'
// }
// }
// if (cell.v == Infinity || cell.v == -Infinity) {
// cell.m = cell.v.toString();
// } else {
// if (cell.v.toString().indexOf('e') > -1) {
// let len = cell.v.toString().split('.')[1].split('e')[0].length;
// if (len > 5) {
// len = 5;
// }
// cell.m = cell.v.toExponential(len).toString();
// } else {
// let v_p = Math.round(cell.v * 1000000000) / 1000000000;
// if (cell.ct == null) {
// let mask = genarate(v_p);
// cell.m = mask[0].toString();
// } else {
// let mask = update(cell.ct.fa, v_p);
// cell.m = mask.toString();
// }
// }
// }
// } else if (cell.ct != null && cell.ct.fa == '@') {
// cell.m = vupdate.toString();
// cell.v = vupdate;
// } else if (cell.ct != null && cell.ct.fa != null && cell.ct.fa != 'General') {
// if (isRealNum(vupdate)) {
// vupdate = parseFloat(vupdate);
// }
// let mask = update(cell.ct.fa, vupdate);
// if (mask === vupdate) {// 若原来单元格格式 应用不了 要更新的值,则获取更新值的 格式
// mask = genarate(vupdate);
// cell.m = mask[0].toString();
// cell.ct = mask[1];
// cell.v = mask[2];
// } else {
// cell.m = mask.toString();
// cell.v = vupdate;
// }
// } else {
// if (isRealNum(vupdate) && !IDCardReg.test(vupdate)) {
// vupdate = parseFloat(vupdate);
// cell.v = parseFloat(vupdate);
// cell.ct = {
// 'fa': 'General',
// 't': 'n'
// }
// if (cell.v == Infinity || cell.v == -Infinity) {
// cell.m = cell.v.toString();
// } else {
// let mask = genarate(cell.v);
// cell.m = mask[0].toString();
// }
// } else {
// let mask = genarate(vupdate);
// cell.m = mask[0].toString();
// cell.ct = mask[1];
// cell.v = mask[2];
// }
// }
// }
// if (!server.allowUpdate && !luckysheetConfigsetting.pointEdit) {
// if (cell.ct != null && !/^(w|W)((0?)|(0\.0+))$/.test(cell.ct.fa) && cell.ct.t == 'n' && cell.v != null && parseInt(cell.v).toString().length > 4) {
// let autoFormatw = luckysheetConfigsetting.autoFormatw.toString().toUpperCase();
// let accuracy = luckysheetConfigsetting.accuracy;
// let sfmt = setAccuracy(autoFormatw, accuracy);
// if (sfmt != 'General') {
// cell.ct.fa = sfmt;
// cell.m = update(sfmt, cell.v);
// }
// }
// }
// // refresh
// jfrefreshgrid(targetSheetData, {
// row: [row],
// column: [column]
// })
// if (success && typeof success === 'function') {
// success();
// }
// }
export function setCellValue(row, column, value, options = {}) {
if (row == null && column == null) {
return tooltip.info('Arguments row or column cannot be null or undefined.', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
order = curSheetOrder,
success
} = {...options}
luckysheetformula.updatecell(row, column, value);
if (success && typeof success === 'function') {
success();
}
}
/**
* 清除指定工作表指定单元格的内容返回清除掉的数据不同于删除单元格的功能不需要设定单元格移动情况
* @param {Number} row 单元格所在行数从0开始的整数0表示第一行
* @param {Number} column 单元格所在列数从0开始的整数0表示第一列
* @param {Object} options 可选参数
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function clearCell(row, column, options = {}) {
if (row == null || column == null) {
return tooltip.info('Arguments row and column cannot be null or undefined.', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
order = curSheetOrder,
success
} = {...options}
let targetSheetData = $.extend(true, [], Store.luckysheetfile[order].data);
let cell = targetSheetData[row][column];
if(getObjType(cell) == "object"){
delete cell["m"];
delete cell["v"];
if(cell["f"] != null){
delete cell["f"];
formula.delFunctionGroup(row, column, order);
delete cell["spl"];
}
}
else{
cell = null;
}
// 若操作为当前sheet页,则刷新当前sheet页
if (order === curSheetOrder) {
jfrefreshgrid(targetSheetData, [{
row: [row, row],
column: [column, column]
}])
}
else{
Store.luckysheetfile[order].data = targetSheetData;
}
if (success && typeof success === 'function') {
success(cell)
}
}
/**
* 删除指定工作表指定单元格返回删除掉的数据同时指定是右侧单元格左移还是下方单元格上移
* @param {String} move 删除后右侧还是下方的单元格移动可选值为 'left''up'
* @param {Number} row 单元格所在行数从0开始的整数0表示第一行
* @param {Number} column 单元格所在列数从0开始的整数0表示第一列
* @param {Object} options 可选参数
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function deleteCell(move, row, column, options = {}) {
let moveTypes = ['left', 'up'];
if (!move || moveTypes.indexOf(move) < 0) {
return tooltip.info('Arguments move cannot be null or undefined and its value must be \'left\' or \'up\'', '')
}
if (row == null || column == null) {
return tooltip.info('Arguments row and column cannot be null or undefined.', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
order = curSheetOrder,
success
} = {...options}
let moveType = 'move' + move.replace(move[0], move[0].toUpperCase()); // left-moveLeft; up-moveUp
luckysheetDeleteCell(moveType, row, row, column, column, order);
if (success && typeof success === 'function') {
success()
}
}
/**
* 设置某个单元格的属性如果要设置单元格的值或者同时设置多个单元格属性推荐使用setCellValue
* @param {Number} row 单元格所在行数从0开始的整数0表示第一行
* @param {Number} column 单元格所在列数从0开始的整数0表示第一列
* @param {String} attr
* @param {Number | String | Object} value 具体的设置值一个属性会对应多个值参考 单元格属性表的值示例特殊情况如果属性类型attr是单元格格式ct则设置值value应提供ct.fa比如设置A1单元格的格式为百分比格式luckysheet.setCellFormat(0, 0, "ct", "0.00%")
* @param {Object} options 可选参数
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数, callback参数为改变后的cell对象
*/
export function setCellFormat(row, column, attr, value, options = {}) {
if (row == null && column == null) {
return tooltip.info('Arguments row or column cannot be null or undefined.', '')
}
if (!attr) {
return tooltip.info('Arguments attr cannot be null or undefined.', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
order = curSheetOrder,
success
} = { ...options };
let targetSheetData = $.extend(true, [], Store.luckysheetfile[order].data);
let cellData = targetSheetData[row][column];
// 特殊格式
if (attr == 'ct' && (!value || !value.hasOwnProperty('fa') || !value.hasOwnProperty('t'))) {
return new TypeError('While set attribute \'ct\' to cell, the value must have property \'fa\' and \'t\'')
cellData.m = update(value.fa, cellData.v)
}
cellData[attr] = value;
// refresh
jfrefreshgrid(targetSheetData, {
row: [row],
column: [column]
})
if (success && typeof success === 'function') {
success(cellData);
}
}
/**
* 查找一个工作表中的指定内容返回查找到的内容组成的单元格一位数组数据格式同celldata
* @param {String} content 要查找的内容 可以为正则表达式不包含前后'/')
* @param {Object} options 可选参数
* @param {Boolean} options.isRegularExpression 是否正则表达式匹配默认为 false. 注意正则中的规则需要转义\S需要写成 \\S
* @param {Boolean} options.isWholeWord 是否整词匹配默认为 false
* @param {Boolean} options.isCaseSensitive 是否区分大小写匹配默认为 false
* @param {Number} options.order 工作表索引默认值为当前工作表索引
*/
export function find(content, options = {}) {
if (!content && content != 0) {
return tooltip.info('Search content cannot be null or empty', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
isRegularExpression = false,
isWholeWord = false,
isCaseSensitive = false,
order = curSheetOrder
} = { ...options };
let targetSheetData = Store.luckysheetfile[order].data;
let result = [];
for (let i = 0; i < targetSheetData.length; i++) {
const rowArr = targetSheetData[i];
for (let j = 0; j < rowArr.length; j++) {
const cell = rowArr[j];
if (!cell) {
continue;
}
// 添加cell的row, column属性
// replace方法中的setCellValue中需要使用该属性
cell.row = i;
cell.column = j;
if (isWholeWord) {
if (isCaseSensitive) {
if (content.toString() == cell.m) {
result.push(cell)
}
} else {
if (cell.m && content.toString().toLowerCase() == cell.m.toLowerCase()) {
result.push(cell)
}
}
} else if (isRegularExpression) {
let reg;
if (isCaseSensitive) {
reg = new RegExp(func_methods.getRegExpStr(content), 'g')
} else {
reg = new RegExp(func_methods.getRegExpStr(content), 'ig')
}
if (reg.test(cell.m)) {
result.push(cell)
}
} else if (isCaseSensitive) {
let reg = new RegExp(func_methods.getRegExpStr(content), 'g');
if (reg.test(cell.m)) {
result.push(cell);
}
} else {
let reg = new RegExp(func_methods.getRegExpStr(content), 'ig');
if (reg.test(cell.m)) {
result.push(cell);
}
}
}
}
return result;
}
/**
* 查找一个工作表中的指定内容并替换成新的内容返回替换后的内容组成的单元格一位数组数据格式同celldata
* @param {String} content 要查找的内容
* @param {String} replaceContent 要替换的内容
* @param {Object} options 可选参数
* @param {Boolean} options.isRegularExpression 是否正则表达式匹配默认为 false
* @param {Boolean} options.isWholeWord 是否整词匹配默认为 false
* @param {Boolean} options.isCaseSensitive 是否区分大小写匹配默认为 false
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数, callback参数为替换后的cell集合
*/
export function replace(content, replaceContent, options = {}) {
let matchCells = find(content, options)
matchCells.forEach(cell => {
cell.m = replaceContent;
setCellValue(cell.row, cell.column, replaceContent, options);
})
if (options.success && typeof options.success === 'function') {
options.success(matchCells)
}
return matchCells;
}
/**
* 冻结首行
* 若设置冻结的sheet不是当前sheet页只设置参数不渲染
* @param {Number | String} order 工作表索引
*/
export function frozenFirstRow(order) {
// store frozen
luckysheetFreezen.saveFrozen("freezenRow", order);
// 冻结为当前sheet页
if (!order || order == getSheetIndex(Store.currentSheetIndex)) {
let scrollTop = $("#luckysheet-cell-main").scrollTop();
let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);
if(row_st == -1){
row_st = 0;
}
let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columeHeaderHeight;
let freezenhorizontaldata = [
Store.visibledatarow[row_st],
row_st + 1,
scrollTop,
luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1),
top
];
luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, null, null);
if (luckysheetFreezen.freezenverticaldata != null) {
luckysheetFreezen.cancelFreezenVertical();
luckysheetFreezen.createAssistCanvas();
luckysheetrefreshgrid();
}
luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);
luckysheetFreezen.createAssistCanvas();
luckysheetrefreshgrid();
}
}
/**
* 冻结首列
* 若设置冻结的sheet不是当前sheet页只设置参数不渲染
* @param {Number | String} order 工作表索引
*/
export function frozenFirstColumn(order) {
// store frozen
luckysheetFreezen.saveFrozen("freezenColumn", order);
// 冻结为当前sheet页
if (!order || order == getSheetIndex(Store.currentSheetIndex)) {
let scrollLeft = $("#luckysheet-cell-main").scrollLeft();
let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);
if(col_st == -1){
col_st = 0;
}
let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;
let freezenverticaldata = [
Store.visibledatacolumn[col_st],
col_st + 1,
scrollLeft,
luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1),
left
];
luckysheetFreezen.saveFreezen(null, null, freezenverticaldata, left);
if (luckysheetFreezen.freezenhorizontaldata != null) {
luckysheetFreezen.cancelFreezenHorizontal();
luckysheetFreezen.createAssistCanvas();
luckysheetrefreshgrid();
}
luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);
luckysheetFreezen.createAssistCanvas();
luckysheetrefreshgrid();
}
}
/**
* 冻结行选区
* @param {Object} range 行选区范围的focus单元格的行列值构成的对象格式为{ row_focus:0, column_focus:0 }
* @param {Number | String} order 工作表索引
*/
export function frozenRowRange(range, order) {
const locale_frozen = locale().freezen;
if (!range || (!range.hasOwnProperty('row_focus') && !formula.iscelldata(range))) {
if(isEditMode()){
alert(locale_frozen.noSeletionError);
} else{
tooltip.info(locale_frozen.noSeletionError, "");
}
return
}
if (typeof range === 'string' && formula.iscelldata(range)) {
range = formula.getcellrange(range)
range = {
row_focus: range.row[0],
column_focus: range.column[0]
}
}
// store frozen
luckysheetFreezen.saveFrozen("freezenRowRange", order, range);
if (!order || order == getSheetIndex(Store.currentSheetIndex)) {
let scrollTop = $("#luckysheet-cell-main").scrollTop();
let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);
let row_focus = range.row_focus;
if(row_focus > row_st){
row_st = row_focus;
}
if(row_st == -1){
row_st = 0;
}
let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columeHeaderHeight;
let freezenhorizontaldata = [
Store.visibledatarow[row_st],
row_st + 1,
scrollTop,
luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1),
top
];
luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, null, null);
if (luckysheetFreezen.freezenverticaldata != null) {
luckysheetFreezen.cancelFreezenVertical();
luckysheetFreezen.createAssistCanvas();
luckysheetrefreshgrid();
}
luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);
luckysheetFreezen.createAssistCanvas();
luckysheetrefreshgrid();
}
}
/**
* 冻结列选区
* @param {Object} range 列选区范围的focus单元格的行列值构成的对象格式为{ row_focus:0, column_focus:0 }
* @param {Number | String} order 工作表索引
*/
export function frozenColumnRange(range, order) {
const locale_frozen = locale().freezen;
let isStringRange = typeof range === 'string' && formula.iscelldata(range);
if (!range || (!range.hasOwnProperty('column_focus') && !isStringRange)) {
if(isEditMode()){
alert(locale_frozen.noSeletionError);
} else{
tooltip.info(locale_frozen.noSeletionError, "");
}
return
}
if (isStringRange) {
range = formula.getcellrange(range)
range = {
row_focus: range.row[0],
column_focus: range.column[0]
}
}
// store frozen
luckysheetFreezen.saveFrozen("freezenColumnRange", order, range);
if (!order || order == getSheetIndex(Store.currentSheetIndex)) {
let scrollLeft = $("#luckysheet-cell-main").scrollLeft();
let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);
let column_focus = range.column_focus;
if(column_focus > col_st){
col_st = column_focus;
}
if(col_st == -1){
col_st = 0;
}
let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;
let freezenverticaldata = [
Store.visibledatacolumn[col_st],
col_st + 1,
scrollLeft,
luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1),
left
];
luckysheetFreezen.saveFreezen(null, null, freezenverticaldata, left);
if (luckysheetFreezen.freezenhorizontaldata != null) {
luckysheetFreezen.cancelFreezenHorizontal();
luckysheetFreezen.createAssistCanvas();
luckysheetrefreshgrid();
}
luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);
luckysheetFreezen.createAssistCanvas();
luckysheetrefreshgrid();
}
}
/**
* 取消冻结
* @param {Number | String} order
*/
export function cancelFrozen(order) {
luckysheetFreezen.saveFrozen("freezenCancel", order);
// 取消当前sheet冻结时,刷新canvas
if (!order || order == getSheetIndex(Store.currentSheetIndex)) {
if (luckysheetFreezen.freezenverticaldata != null) {
luckysheetFreezen.cancelFreezenVertical();
}
if (luckysheetFreezen.freezenhorizontaldata != null) {
luckysheetFreezen.cancelFreezenHorizontal();
}
luckysheetFreezen.createAssistCanvas();
luckysheetrefreshgrid();
}
}
/**
* 冻结行操作特别注意只有在isRange设置为true的时候才需要设置setting中的range且与一般的range格式不同
* @param {Boolean} isRange 是否冻结行到选区 true-冻结行到选区 false-冻结首行
* @param {Object} options 可选参数
* @param {Object} options.range isRange为true的时候设置开启冻结的单元格位置格式为{ row_focus:0, column_focus:0 }意为当前激活的单元格的行数和列数默认从当前选区最后的一个选区中取得
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function setHorizontalFrozen(isRange, options = {}) {
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
range,
order = curSheetOrder,
success
} = { ...options };
// 若已存在冻结,取消之前的冻结效果
cancelFrozen(order);
if (!isRange) {
frozenFirstRow(order)
} else { // 选区行冻结
frozenRowRange(range, order);
}
if (success && typeof success === 'function') {
success()
}
}
/**
* 冻结列操作特别注意只有在isRange设置为true的时候才需要设置setting中的range且与一般的range格式不同
* @param {Boolean} isRange 是否冻结列到选区 true-冻结列到选区 false-冻结首列
* @param {Object} options 可选参数
* @param {Object} options.range isRange为true的时候设置开启冻结的单元格位置格式为{ row_focus:0, column_focus:0 }意为当前激活的单元格的行数和列数默认从当前选区最后的一个选区中取得
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function setVerticalFrozen(isRange, options = {}) {
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
range,
order = curSheetOrder,
success
} = { ...options };
// 若已存在冻结,取消之前的冻结效果
cancelFrozen(order);
if (!isRange) {
frozenFirstColumn(order);
} else {
frozenColumnRange(range, order);
}
if (success && typeof success === 'function') {
success()
}
}
/**
* 冻结行列操作特别注意只有在isRange设置为true的时候才需要设置setting中的range且与一般的range格式不同
* @param {Boolean} isRange 是否冻结行列到选区 true-冻结行列到选区 false-冻结首行列
* @param {Object} options 可选参数
* @param {Object} options.range isRange为true的时候设置开启冻结的单元格位置格式为{ row_focus:0, column_focus:0 }意为当前激活的单元格的行数和列数默认从当前选区最后的一个选区中取得
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function setBothFrozen(isRange, options = {}) {
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
range,
order = curSheetOrder,
success
} = { ...options };
let isCurrentSheet = !order || order == getSheetIndex(Store.currentSheetIndex);
const locale_frozen = locale().freezen;
// 若已存在冻结,取消之前的冻结效果
cancelFrozen(order);
// 冻结首行列
if (!isRange) {
// store frozen
luckysheetFreezen.saveFrozen("freezenRC", order)
if (isCurrentSheet) {
let scrollTop = $("#luckysheet-cell-main").scrollTop();
let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);
if(row_st == -1){
row_st = 0;
}
let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columeHeaderHeight;
let freezenhorizontaldata = [
Store.visibledatarow[row_st],
row_st + 1,
scrollTop,
luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1),
top
];
luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, null, null);
luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);
let scrollLeft = $("#luckysheet-cell-main").scrollLeft();
let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);
if(col_st == -1){
col_st = 0;
}
let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;
let freezenverticaldata = [
Store.visibledatacolumn[col_st],
col_st + 1,
scrollLeft,
luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1),
left
];
luckysheetFreezen.saveFreezen(null, null, freezenverticaldata, left);
luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);
luckysheetFreezen.createAssistCanvas();
luckysheetrefreshgrid();
}
} else { // 冻结行列到选区
// store frozen
luckysheetFreezen.saveFrozen("freezenRCRange", order, range)
let isStringRange = typeof range === 'string' && formula.iscelldata(range);
if (isCurrentSheet) {
if ((!range || !(range.hasOwnProperty('column_focus') && range.hasOwnProperty('row_focus'))) && !isStringRange) {
if(isEditMode()){
alert(locale_frozen.noSeletionError);
} else{
tooltip.info(locale_frozen.noSeletionError, "");
}
return
}
if (isStringRange) {
range = formula.getcellrange(range)
range = {
row_focus: range.row[0],
column_focus: range.column[0]
}
}
let scrollTop = $("#luckysheet-cell-main").scrollTop();
let row_st = luckysheet_searcharray(Store.visibledatarow, scrollTop);
let row_focus = range.row_focus;
if(row_focus > row_st){
row_st = row_focus;
}
if(row_st == -1){
row_st = 0;
}
let top = Store.visibledatarow[row_st] - 2 - scrollTop + Store.columeHeaderHeight;
let freezenhorizontaldata = [
Store.visibledatarow[row_st],
row_st + 1,
scrollTop,
luckysheetFreezen.cutVolumn(Store.visibledatarow, row_st + 1),
top
];
luckysheetFreezen.saveFreezen(freezenhorizontaldata, top, null, null);
luckysheetFreezen.createFreezenHorizontal(freezenhorizontaldata, top);
let scrollLeft = $("#luckysheet-cell-main").scrollLeft();
let col_st = luckysheet_searcharray(Store.visibledatacolumn, scrollLeft);
let column_focus = range.column_focus;
if(column_focus > col_st){
col_st = column_focus;
}
if(col_st == -1){
col_st = 0;
}
let left = Store.visibledatacolumn[col_st] - 2 - scrollLeft + Store.rowHeaderWidth;
let freezenverticaldata = [
Store.visibledatacolumn[col_st],
col_st + 1,
scrollLeft,
luckysheetFreezen.cutVolumn(Store.visibledatacolumn, col_st + 1),
left
];
luckysheetFreezen.saveFreezen(null, null, freezenverticaldata, left);
luckysheetFreezen.createFreezenVertical(freezenverticaldata, left);
luckysheetFreezen.createAssistCanvas();
luckysheetrefreshgrid();
}
}
}
/**
* 在第index行或列的位置插入number行或列
* @param {String} type 插入行或列 row- column-
* @param {Number} index 在第几行插入空白行从0开始
* @param {Object} options 可选参数
* @param {Number} options.number 插入的空白行数默认为 1
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function insertRowOrColumn(type, index = 0, options = {}) {
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
number = 1,
order = curSheetOrder,
success
} = {...options}
if (!isRealNum(number)) {
if(isEditMode()){
alert(locale_info.tipInputNumber);
} else{
tooltip.info(locale_info.tipInputNumber, "");
}
return;
}
number = parseInt(number);
if (number < 1 || number > 100) {
if(isEditMode()){
alert(locale_info.tipInputNumberLimit);
} else{
tooltip.info(locale_info.tipInputNumberLimit, "");
}
return;
}
// 默认在行上方增加行,列左侧增加列
luckysheetextendtable(type, index, number, "lefttop", order);
if (success && typeof success === 'function') {
success();
}
}
/**
* 在第row行的位置插入number行空白行
* @param {Number} row 在第几行插入空白行从0开始
* @param {Object} options 可选参数
* @param {Number} options.number 插入的空白行数默认为 1
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function insertRow(row = 0, options = {}) {
insertRowOrColumn('row', row, options)
}
/**
* 在第column列的位置插入number列空白列
* @param {Number} column 在第几列插入空白列从0开始
* @param {Object} options 可选参数
* @param {Number} options.number 插入的空白列数默认为 1
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function insertColumn(column = 0, options = {}) {
insertRowOrColumn('column', column, options)
}
/**
* 删除指定的行或列删除行列之后行列的序号并不会变化下面的行右侧的列会补充到上注意观察数据是否被正确删除即可
* @param {String} type 删除行或列 row- column-
* @param {Number} startIndex 要删除的起始行或列
* @param {Number} endIndex 要删除的结束行或列
* @param {Object} options 可选参数
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function deleteRowOrColumn(type, startIndex, endIndex, options = {}) {
if (startIndex == null || endIndex == null) {
return tooltip.info('Please enter the index for deleting rows or columns correctly.', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
order = curSheetOrder,
success
} = {...options}
luckysheetdeletetable(type, startIndex, endIndex, order)
if (success && typeof success === 'function') {
success()
}
}
/**
* 删除指定的行
* @param {Number} rowStart 要删除的起始行
* @param {Number} rowEnd 要删除的结束行
* @param {Object} options 可选参数
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function deleteRow(rowStart, rowEnd, options = {}) {
deleteRowOrColumn('row', rowStart, rowEnd, options)
}
/**
* 删除指定的列
* @param {Number} columnStart 要删除的起始列
* @param {Number} columnEnd 要删除的结束列
* @param {Object} options 可选参数
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function deleteColumn(columnStart, columnEnd, options = {}) {
deleteRowOrColumn('column', columnStart, columnEnd, options)
}
/**
* 隐藏行或列
* @param {String} type 隐藏行或列 row-隐藏行 column-隐藏列
* @param {Number} startIndex 起始行或列
* @param {Number} endIndex 结束行或列
* @param {Object} options 可选参数
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function hideRowOrColumn(type, startIndex, endIndex, options = {}) {
if (startIndex == null || endIndex == null) {
return tooltip.info('Please enter the index for deleting rows or columns correctly.', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
order = curSheetOrder,
success
} = {...options}
let file = Store.luckysheetfile[order];
let cfgKey = type === 'row' ? 'rowhidden': 'colhidden';
let cfg = $.extend(true, {}, file.config);
if(cfg[cfgKey] == null) {
cfg[cfgKey] = {};
}
for (let i = startIndex; i <= endIndex; i++) {
cfg[cfgKey][i] = 0;
}
//保存撤销
if(Store.clearjfundo){
let redo = {};
redo["type"] = type === 'row' ? 'showHidRows' : 'showHidCols';
redo["sheetIndex"] = file.index;
redo["config"] = $.extend(true, {}, file.config);
redo["curconfig"] = cfg;
Store.jfundo = [];
Store.jfredo.push(redo);
}
Store.luckysheetfile[order].config = cfg;
server.saveParam("cg", file.index, cfg[cfgKey], { "k": cfgKey });
// 若操作sheet为当前sheet页,行高、列宽 刷新
if (order == curSheetOrder) {
//config
Store.config = cfg;
jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);
}
if (success && typeof success === 'function') {
success();
}
}
/**
* 显示隐藏的行或列
* @param {String} type 显示行或列 row-显示行 column-显示列
* @param {Number} startIndex 起始行或列
* @param {Number} endIndex 结束行或列
* @param {Object} options 可选参数
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function showRowOrColumn(type, startIndex, endIndex, options = {}) {
if (startIndex == null || endIndex == null) {
return tooltip.info('Please enter the index for deleting rows or columns correctly.', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
order = curSheetOrder,
success
} = {...options}
let file = Store.luckysheetfile[order];
let cfgKey = type === 'row' ? 'rowhidden': 'colhidden';
let cfg = $.extend(true, {}, file.config);
if(cfg[cfgKey] == null) {
return;
}
for (let i = startIndex; i <= endIndex; i++) {
delete cfg[cfgKey][i];
}
//保存撤销
if(Store.clearjfundo){
let redo = {};
redo["type"] = type === 'row' ? 'showHidRows' : 'showHidCols';
redo["sheetIndex"] = file.index;
redo["config"] = $.extend(true, {}, file.config);
redo["curconfig"] = cfg;
Store.jfundo = [];
Store.jfredo.push(redo);
}
//config
Store.luckysheetfile[order].config = Store.config;
server.saveParam("cg", file.index, cfg[cfgKey], { "k": cfgKey });
// 若操作sheet为当前sheet页,行高、列宽 刷新
if (order === curSheetOrder) {
Store.config = cfg;
jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length);
}
if (success && typeof success === 'function') {
success();
}
}
/**
* 隐藏行
* @param {Number} startIndex 起始行
* @param {Number} endIndex 结束行
* @param {Object} options 可选参数
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function hideRow(startIndex, endIndex, options = {}) {
hideRowOrColumn('row', startIndex, endIndex, options);
}
/**
* 显示行
* @param {Number} startIndex 起始行
* @param {Number} endIndex 结束行
* @param {Object} options 可选参数
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function showRow(startIndex, endIndex, options = {}) {
showRowOrColumn('row', startIndex, endIndex, options);
}
/**
* 隐藏列
* @param {Number} startIndex 起始列
* @param {Number} endIndex 结束列
* @param {Object} options 可选参数
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function hideColumn(startIndex, endIndex, options = {}) {
hideRowOrColumn('column', startIndex, endIndex, options);
}
/**
* 显示列
* @param {Number} startIndex 起始列
* @param {Number} endIndex 结束列
* @param {Object} options 可选参数
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function showColumn(startIndex, endIndex, options = {}) {
showRowOrColumn('column', startIndex, endIndex, options);
}
/**
* 返回当前选区对象的数组可能存在多个选区
* 每个选区的格式为row/column信息组成的对象{row:[0,1],column:[0,1]}
* @returns {Array}
*/
export function getRange() {
let rangeArr = Store.luckysheet_select_save;
let result = [];
for (let i = 0; i < rangeArr.length; i++) {
let rangeItem = rangeArr[i];
let temp = {
row: rangeItem.row,
column: rangeItem.column
}
result.push(temp)
}
return result;
}
/**
* 返回指定工作表指定范围的单元格二维数组数据每个单元格为一个对象
* @param {Object} options
* @param {Object | String} options.range 选区范围,支持选区的格式为"A1:B2""sheetName!A1:B2"或者{row:[0,1],column:[0,1]}只能为单个选区默认为当前选区
* @param {Number} options.order 工作表索引默认值为当前工作表索引
*/
export function getRangeValue(options = {}) {
let curOrder = getSheetIndex(Store.currentSheetIndex);
let {
range,
order = curOrder
} = {...options}
let file = Store.luckysheetfile[order];
if (!range || typeof range === 'object') {
return getdatabyselection(range, file.index);
} else if (typeof range === 'string') {
if (formula.iscelldata(range)) {
return getdatabyselection(formula.getcellrange(range), file.index)
} else {
tooltip.info('The range is invalid, please check range parameter.', '')
}
}
}
/**
* @todo 核心功能未实现to be continue
* @description 复制指定工作表指定单元格区域的数据返回一维二维或者自定义行列数的二维数组的数据只有在dimensional设置为custom的时候才需要设置setting中的row和column
* @param {String} dimensional 数组维度可选值为oneDimensional-一维数组twoDimensional-二维数组 custom-自定义行列数的二维数组
* @param {Object} options 可选参数
* @param {Number} options.row dimensional为custom的时候设置多维数组的行数
* @param {Number} options.column dimensional为custom的时候设置多维数组的列数
* @param {Object | String} options.range 选区范围,支持选区的格式为"A1:B2""sheetName!A1:B2"或者{row:[0,1],column:[0,1]}只能为单个选区默认为当前选区
* @param {Number} options.order 工作表索引默认值为当前工作表索引
*/
function getRangeArray(dimensional, options = {}) {
let dimensionalArray = ['oneDimensional', 'twoDimensional', 'custom']
if (dimensionalArray.indexOf(dimensional) < 0) {
return tooltip.info('Argument dimensional is invalid, the value can be \'oneDimensional\', \'twoDimensional\', \'custom\'', '')
}
let {
row,
column,
range,
order
} = {...options}
let realRange = range;
if (typeof range === 'string') {
if (formula.iscelldata(range)) {
realRange = formula.getcellrange(range)
} else {
return tooltip.info('The range is invalid, please check range parameter.', '')
}
}
if (dimensional === 'oneDimensional') {
formula.getRangeArray(realRange)
} else if (dimensional === 'twoDimensional') {
formula.getRangeArrayTwo(realRange)
} else if (dimensional === 'custom') {
// TODO
}
}
/**
* 复制指定工作表指定单元格区域的数据返回json格式的数据
* @param {Boolean} isFirstRowTitle 是否首行为标题
* @param {Object} options 可选参数
* @param {Object | String} options.range 选区范围,支持选区的格式为"A1:B2""sheetName!A1:B2"或者{row:[0,1],column:[0,1]}只能为单个选区默认为当前选区
* @param {Number} options.order 工作表索引默认值为当前工作表索引
*/
export function getRangeJson(isFirstRowTitle, options = {}) {
let curRange = Store.luckysheet_select_save;
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
range = curRange,
order = curSheetOrder
} = {...options}
let file = Store.luckysheetfile[order];
let config = file.config;
if (range && typeof range === 'string' && formula.iscelldata(range)) {
range = formula.getcellrange(range)
}
if (!range || range.length > 1) {
if(isEditMode()){
alert(locale_drag.noMulti);
} else{
tooltip.info(locale_drag.noMulti, "");
}
return;
}
//复制范围内包含部分合并单元格,提示
if(config["merge"] != null) {
let has_PartMC = false;
let r1 = range[0].row[0],
r2 = range[0].row[1],
c1 = range[0].column[0],
c2 = range[0].column[1];
has_PartMC = hasPartMC(config, r1, r2, c1, c2);
if(has_PartMC){
if(isEditMode()){
alert(locale().drag.noPartMerge);
} else{
tooltip.info(locale().drag.noPartMerge, "");
}
return;
}
}
let getdata = getdatabyselection(range, order);
let arr = [];
if (getdata.length === 0) {
return;
}
if (isFirstRowTitle) {
if (getdata.length === 1) {
let obj = {};
for (let i = 0; i < getdata[0].length; i++) {
obj[getcellvalue(0, i, getdata)] = "";
}
arr.push(obj);
} else {
for (let r = 1; r < getdata.length; r++) {
let obj = {};
for (let c = 0; c < getdata[0].length; c++) {
if(getcellvalue(0, c, getdata) == undefined){
obj[""] = getcellvalue(r, c, getdata);
}else{
obj[getcellvalue(0, c, getdata)] = getcellvalue(r, c, getdata);
}
}
arr.push(obj);
}
}
} else {
let st = range[0]["column"][0];
for (let r = 0; r < getdata.length; r++) {
let obj = {};
for (let c = 0; c < getdata[0].length; c++) {
obj[chatatABC(c + st)] = getcellvalue(r, c, getdata);
}
arr.push(obj);
}
}
selection.copybyformat(new Event(), JSON.stringify(arr));
}
/**
*
* @param {String} type 对角线还是对角线偏移 "normal"-对角线 "anti"-反对角线
"offset"-对角线偏移
* @param {Object} options 可选参数
* @param {Number} options.column type为offset的时候设置对角偏移的列数
* @param {Object | String} options.range 选区范围,支持选区的格式为"A1:B2""sheetName!A1:B2"或者{row:[0,1],column:[0,1]}只能为单个选区默认为当前选区
* @param {Number} options.order 工作表索引默认值为当前工作表索引
*/
export function getRangeDiagonal(type, options = {}) {
let typeValues = ['normal', 'anti', 'offset'];
if (typeValues.indexOf(type) < 0) {
return tooltip.info('The type parameter must be included in [\'normal\', \'anti\', \'offset\']', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let curRange = Store.luckysheet_select_save;
let {
column = 1,
range = curRange,
order = curSheetOrder
} = {...options}
let file = Store.luckysheetfile[order];
let config = file.config;
if (range && typeof range === 'string' && formula.iscelldata(range)) {
range = formula.getcellrange(range)
}
if (!range || range.length > 1) {
if(isEditMode()){
alert(locale().drag.noMulti);
} else{
tooltip.info(locale().drag.noMulti, "");
}
return;
}
//复制范围内包含部分合并单元格,提示
if(config["merge"] != null) {
let has_PartMC = false;
let r1 = range[0].row[0],
r2 = range[0].row[1],
c1 = range[0].column[0],
c2 = range[0].column[1];
has_PartMC = hasPartMC(config, r1, r2, c1, c2);
if(has_PartMC){
if(isEditMode()){
alert(locale().drag.noPartMerge);
} else{
tooltip.info(locale().drag.noPartMerge, "");
}
return;
}
}
let getdata = getdatabyselection(range, order);
let arr = [];
if (getdata.length === 0) {
return;
}
let clen = getdata[0].length;
switch (type) {
case 'normal':
for (let r = 0; r < getdata.length; r++) {
if (r >= clen) {
break;
}
arr.push(getdata[r][r]);
}
break;
case 'anti':
for (let r = 0; r < getdata.length; r++) {
if (r >= clen) {
break;
}
arr.push(getdata[r][clen - r - 1]);
}
break;
case 'offset':
if(column.toString() == "NaN"){
if(isEditMode()){
alert(locale().drag.inputCorrect);
} else{
tooltip.info(locale().drag.inputCorrect, "");
}
return;
}
if(column < 0){
if(isEditMode()){
alert(locale().drag.offsetColumnLessZero);
} else{
tooltip.info(locale().drag.offsetColumnLessZero, "");
}
return;
}
for (let r = 0; r < getdata.length; r++) {
if (r + column >= clen) {
break;
}
arr.push(getdata[r][r + column]);
}
break;
}
selection.copybyformat(new Event(), JSON.stringify(arr));
}
/**
* 复制指定工作表指定单元格区域的数据返回布尔值的数据
* @param {Object} options 可选参数
* @param {Object | String} options.range 选区范围,支持选区的格式为"A1:B2""sheetName!A1:B2"或者{row:[0,1],column:[0,1]}只能为单个选区默认为当前选区
* @param {Number} options.order 工作表索引默认值为当前工作表索引
*/
export function getRangeBoolean(options = {}) {
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let curRange = Store.luckysheet_select_save;
let {
range = curRange,
order = curSheetOrder
} = {...options}
let file = Store.luckysheetfile[order];
let config = file.config;
if (range && typeof range === 'string' && formula.iscelldata(range)) {
range = formula.getcellrange(range)
}
if (!range || range.length > 1) {
if(isEditMode()){
alert(locale().drag.noMulti);
} else{
tooltip.info(locale().drag.noMulti, "");
}
return;
}
//复制范围内包含部分合并单元格,提示
if(config["merge"] != null) {
let has_PartMC = false;
let r1 = range[0].row[0],
r2 = range[0].row[1],
c1 = range[0].column[0],
c2 = range[0].column[1];
has_PartMC = hasPartMC(config, r1, r2, c1, c2);
if(has_PartMC){
if(isEditMode()){
alert(locale().drag.noPartMerge);
} else{
tooltip.info(locale().drag.noPartMerge, "");
}
return;
}
}
let getdata = getdatabyselection(range, order);
let arr = [];
if (getdata.length === 0) {
return;
}
for (let r = 0; r < getdata.length; r++) {
let a = [];
for (let c = 0; c < getdata[0].length; c++) {
let bool = false;
let v;
if(getObjType(getdata[r][c]) == "object"){
v = getdata[r][c].v;
} else{
v = getdata[r][c];
}
if (v == null || v == "") {
bool = false;
} else {
v = parseInt(v);
if (v == null || v > 0) {
bool = true;
} else {
bool = false;
}
}
a.push(bool);
}
arr.push(a);
}
selection.copybyformat(event, JSON.stringify(arr));
}
/**
* 将一个单元格数组数据赋值到指定的区域数据格式同getRangeValue方法取到的数据
* @param {Array[Array]} data 要赋值的单元格二维数组数据每个单元格的值可以为字符串或数字或为符合Luckysheet格式的对象
* @param {Object} options 可选参数
* @param {Object | String} options.range 选区范围,支持选区的格式为"A1:B2""sheetName!A1:B2"或者{row:[0,1],column:[0,1]}只能为单个选区默认为当前选区
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function setRangeValue(data, options = {}) {
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let curRange = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];
let {
range = curRange,
order = curSheetOrder,
success
} = {...options}
if (data == null) {
return tooltip.info('The data which will be set to range cannot be null.', '')
}
if (range instanceof Array) {
return tooltip.info('setRangeValue only supports a single selection.', '')
}
if (typeof range === 'string' && formula.iscelldata(range)) {
range = formula.getcellrange(range)
}
let rowCount = range.row[1] - range.row[0] + 1,
columnCount = range.column[1] - range.column[0] + 1;
if (data.length !== rowCount || data[0].length !== columnCount) {
return tooltip.info('The data to be set does not match the selection.', '')
}
for (let i = 0; i < rowCount; i++) {
for (let j = 0; j < columnCount; j++) {
let row = range.row[0] + i,
column = range.column[0] + j;
setCellValue(row, column, data[i][j], {order: order})
}
}
if (success && typeof success === 'function') {
success();
}
}
/**
* 设置指定范围的单元格格式一般用作处理格式赋值操作推荐使用setRangeValue方法
* @param {String} attr 要赋值的单元格二维数组数据每个单元格的值可以为字符串或数字或为符合Luckysheet格式的对象
* @param {Number | String | Object} value 具体的设置值
* @param {Object} options 可选参数
* @param {Object | String} options.range 设置参数的目标选区范围支持选区的格式为"A1:B2""sheetName!A1:B2"或者{row:[0,1],column:[0,1]}只能为单个选区默认为当前选区
* @param {Number} options.order 工作表索引默认值为当前工作表索引
*/
export function setSingleRangeFormat(attr, value, options = {}) {
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let curRange = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1];
let {
range = curRange,
order = curSheetOrder,
} = {...options}
if (attr == null) {
return tooltip.info('Arguments attr cannot be null or undefined.', '')
}
if (range instanceof Array) {
return tooltip.info('setRangeValue only supports a single selection.', '')
}
if (typeof range === 'string' && formula.iscelldata(range)) {
range = formula.getcellrange(range)
}
let rowCount = range.row[1] - range.row[0] + 1,
columnCount = range.column[1] - range.column[0] + 1;
if (data.length !== rowCount || data[0].length !== columnCount) {
return tooltip.info('The data to be set does not match the selection', '')
}
for (let i = 0; i < rowCount; i++) {
for (let j = 0; j < columnCount; j++) {
let row = range.row[0] + i,
column = range.column[0] + j;
setCellFormat(row, column, attr, value, {order: order})
}
}
}
/**
* 设置指定范围的单元格格式一般用作处理格式支持多选区设置
* @param {String} attr 要赋值的单元格二维数组数据每个单元格的值可以为字符串或数字或为符合Luckysheet格式的对象
* @param {Number | String | Object} value 具体的设置值
* @param {Object} options 可选参数
* @param {Array | Object | String} options.range 设置参数的目标选区范围支持选区的格式为"A1:B2""sheetName!A1:B2"或者{row:[0,1],column:[0,1]}只能为单个选区默认为当前选区
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function setRangeFormat(attr, value, options = {}) {
let curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let curRange = Store.luckysheet_select_save;
let {
range = curRange,
order = curSheetOrder,
success
} = {...options}
if (range instanceof Array) {
for (let i = 0; i < range.length; i++) {
setSingleRangeFormat(range[i])
}
}
if (success && typeof success === 'function') {
success()
}
}
/**
* 为指定索引的工作表选定的范围开启或关闭筛选功能
* @param {String} type 打开还是关闭筛选功能 open-打开筛选功能返回当前筛选的范围对象close-关闭筛选功能返回关闭前筛选的范围对象
* @param {Object} options 可选参数
* @param {Object | String} options.range 选区范围
* @param {Number} options.order
* @param {Object} options.success
*/
function setRangeFilter(type, options = {}) {
let typeValues = ['open', 'close'];
if (typeValues.indexOf(type) < 0) {
return tooltip.info('The type parameter must be included in [\'open\', \'close\']', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex),
curRange = Store.luckysheet_select_save;
let {
range = curRange,
order = curSheetOrder,
success
} = {...options}
if(range.length > 1){
const locale_splitText = locale().splitText;
if(isEditMode()){
alert(locale_splitText.tipNoMulti);
} else{
tooltip.info(locale_splitText.tipNoMulti, "");
}
return;
}
if(Store.luckysheetfile[order].isPivotTable){
return;
}
// TODO to be continue
}
/**
* 为指定索引的工作表选定的范围设定合并单元格
* @param {String} type 合并类型 all-全部合并 horizontal-水平合并 vertical-垂直合并
* @param {Object} options 可选参数
* @param {Object | String} options.range 选区范围
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Object} options.success 操作结束的回调函数
*/
export function setRangeMerge(type, options = {}) {
let typeValues = ['all', 'horizontal', 'vertical'];
if (typeValues.indexOf(type) < 0) {
return tooltip.info('The type parameter must be included in [\'all\', \'horizontal\', \'vertical\']', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex),
curRange = Store.luckysheet_select_save;
let {
range = curRange,
order = curSheetOrder,
success
} = {...options}
let file = Store.luckysheetfile[order],
cfg = $.extend(true, {}, file.config),
data = $.extend(true, [], file.data);
if(getObjType(range) == 'string'){
if(!formula.iscelldata(range)){
return tooltip.info('Incorrect selection format', '');
}
let cellrange = formula.getcellrange(range);
range = [{
"row": cellrange.row,
"column": cellrange.column
}]
}
else if(getObjType(range) == 'object'){
if(!range.hasOwnProperty("row") || !range.hasOwnProperty("column")){
return tooltip.info('Incorrect selection format', '');
}
range = [{
"row": range.row,
"column": range.column
}]
}
//不能合并重叠区域
if(selectIsOverlap(range)){
return tooltip.info('Cannot merge overlapping range', '');
}
//选区是否含有 部分合并单元格
if(cfg["merge"] != null){
let has_PartMC = false;
for(let s = 0; s < range.length; s++){
let r1 = range[s].row[0],
r2 = range[s].row[1];
let c1 = range[s].column[0],
c2 = range[s].column[1];
has_PartMC = hasPartMC(cfg, r1, r2, c1, c2);
if(has_PartMC){
break;
}
}
if(has_PartMC){
return tooltip.info('Cannot perform this operation on partially merged cells', '');
}
}
//选区是否含有 合并的单元格
let isHasMc = false;
for(let i = 0; i < range.length; i++){
let r1 = range[i].row[0],
r2 = range[i].row[1];
let c1 = range[i].column[0],
c2 = range[i].column[1];
for(let r = r1; r <= r2; r++){
for(let c = c1; c <= c2; c++){
let cell = data[r][c];
if(getObjType(cell) == "object" && ("mc" in cell)){
isHasMc = true;
break;
}
}
if(isHasMc){
break;
}
}
}
if(isHasMc){//选区有合并单元格(选区都执行 取消合并)
cancelRangeMerge({
range: range,
order: order
})
}
else{
for(let i = 0; i < range.length; i++){
let r1 = range[i].row[0],
r2 = range[i].row[1];
let c1 = range[i].column[0],
c2 = range[i].column[1];
if(r1 == r2 && c1 == c2){
continue;
}
if(type == "all"){
let fv = {}, isfirst = false;
for(let r = r1; r <= r2; r++){
for(let c = c1; c <= c2; c++){
let cell = data[r][c];
if(cell != null && (!isRealNull(cell.v) || cell.f != null) && !isfirst){
fv = $.extend(true, {}, cell);
isfirst = true;
}
data[r][c] = { "mc": { "r": r1, "c": c1 } };
}
}
data[r1][c1] = fv;
data[r1][c1].mc = { "r": r1, "c": c1, "rs": r2 - r1 + 1, "cs": c2 - c1 + 1 };
cfg["merge"][r1 + "_" + c1] = { "r": r1, "c": c1, "rs": r2 - r1 + 1, "cs": c2 - c1 + 1 };
}
else if(type == "vertical"){
for(let c = c1; c <= c2; c++){
let fv = {}, isfirst = false;
for(let r = r1; r <= r2; r++){
let cell = data[r][c];
if(cell != null && (!isRealNull(cell.v) || cell.f != null) && !isfirst){
fv = $.extend(true, {}, cell);
isfirst = true;
}
data[r][c] = { "mc": { "r": r1, "c": c } };
}
data[r1][c] = fv;
data[r1][c].mc = { "r": r1, "c": c, "rs": r2 - r1 + 1, "cs": 1 };
cfg["merge"][r1 + "_" + c] = { "r": r1, "c": c, "rs": r2 - r1 + 1, "cs": 1 };
}
}
else if(type == "horizontal"){
for(let r = r1; r <= r2; r++){
let fv = {}, isfirst = false;
for(let c = c1; c <= c2; c++){
let cell = data[r][c];
if(cell != null && (!isRealNull(cell.v) || cell.f != null) && !isfirst){
fv = $.extend(true, {}, cell);
isfirst = true;
}
data[r][c] = { "mc": { "r": r, "c": c1 } };
}
data[r][c1] = fv;
data[r][c1].mc = { "r": r, "c": c1, "rs": 1, "cs": c2 - c1 + 1 };
cfg["merge"][r + "_" + c1] = { "r": r, "c": c1, "rs": 1, "cs": c2 - c1 + 1 };
}
}
}
if(order == curSheetOrder){
if (Store.clearjfundo) {
Store.jfundo = [];
Store.jfredo.push({
"type": "mergeChange",
"sheetIndex": file.index,
"data": $.extend(true, [], file.data),
"curData": data,
"range": range,
"config": $.extend(true, {}, file.config),
"curConfig": cfg
});
}
Store.clearjfundo = false;
jfrefreshgrid(data, range, {"cfg": cfg});
Store.clearjfundo = true;
}
else{
file.data = data;
file.config = cfg;
}
}
if (success && typeof success === 'function') {
success();
}
}
/**
* 为指定索引的工作表选定的范围取消合并单元格
* @param {Object} options 可选参数
* @param {Array | Object | String} options.range 选区范围
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Object} options.success 操作结束的回调函数
*/
export function cancelRangeMerge(options = {}) {
let curRange = Store.luckysheet_select_save,
curSheetOrder = getSheetIndex(Store.currentSheetIndex);
let {
range = curRange,
order = curSheetOrder,
success
} = {...options}
let file = Store.luckysheetfile[order],
cfg = $.extend(true, {}, file.config),
data = $.extend(true, [], file.data);
if(getObjType(range) == 'string'){
if(!formula.iscelldata(range)){
return tooltip.info('Incorrect selection format', '');
}
let cellrange = formula.getcellrange(range);
range = [{
"row": cellrange.row,
"column": cellrange.column
}]
}
else if(getObjType(range) == 'object'){
if(!range.hasOwnProperty("row") || !range.hasOwnProperty("column")){
return tooltip.info('Incorrect selection format', '');
}
range = [{
"row": range.row,
"column": range.column
}]
}
//不能合并重叠区域
if(selectIsOverlap(range)){
return tooltip.info('Cannot merge overlapping range', '');
}
//选区是否含有 部分合并单元格
if(cfg["merge"] != null){
let has_PartMC = false;
for(let s = 0; s < range.length; s++){
let r1 = range[s].row[0],
r2 = range[s].row[1];
let c1 = range[s].column[0],
c2 = range[s].column[1];
has_PartMC = hasPartMC(cfg, r1, r2, c1, c2);
if(has_PartMC){
break;
}
}
if(has_PartMC){
return tooltip.info('Cannot perform this operation on partially merged cells', '');
}
}
for(let i = 0; i < range.length; i++){
let r1 = range[i].row[0],
r2 = range[i].row[1];
let c1 = range[i].column[0],
c2 = range[i].column[1];
if(r1 == r2 && c1 == c2){
continue;
}
let fv = {};
for(let r = r1; r <= r2; r++){
for(let c = c1; c <= c2; c++){
let cell = data[r][c];
if(cell != null && cell.mc != null){
let mc_r = cell.mc.r, mc_c = cell.mc.c;
if("rs" in cell.mc){
delete cell.mc;
delete cfg["merge"][mc_r + "_" + mc_c];
fv[mc_r + "_" + mc_c] = $.extend(true, {}, cell);
}
else{
let cell_clone = fv[mc_r + "_" + mc_c];
delete cell_clone.v;
delete cell_clone.m;
delete cell_clone.ct;
delete cell_clone.f;
delete cell_clone.spl;
data[r][c] = cell_clone;
}
}
}
}
}
if(order == curSheetOrder){
if (Store.clearjfundo) {
Store.jfundo = [];
Store.jfredo.push({
"type": "mergeChange",
"sheetIndex": file.index,
"data": $.extend(true, [], file.data),
"curData": data,
"range": range,
"config": $.extend(true, {}, file.config),
"curConfig": cfg
});
}
Store.clearjfundo = false;
jfrefreshgrid(data, range, {"cfg": cfg});
Store.clearjfundo = true;
}
else{
file.data = data;
file.config = cfg;
}
}
/**
* 为指定索引的工作表选定的范围开启排序功能返回选定范围排序后的数据
* @param {String} type 排序类型 asc-升序 desc-降序
* @param {Object} options 可选参数
* @param {Object | String} options.range 选区范围,支持选区的格式为"A1:B2""sheetName!A1:B2"或者{row:[0,1],column:[0,1]}只能为单个选区默认为当前选区
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function setRangeSort(type, options = {}) {
let typeValues = ['asc', 'desc']
if (typeValues.indexOf(type) < 0) {
return tooltip.info('The type parameter must be included in [\'asc\', \'desc\'', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex),
curRange = Store.luckysheet_select_save[0];
let {
range = curRange,
order = curSheetOrder,
success
} = {...options}
let file = Store.luckysheetfile[order],
cfg = $.extend(true, {}, file.config),
fileData = $.extend(true, [], file.data);
if(range instanceof Array && range.length > 1){
tooltip.info(locale().sort.noRangeError, "");
return;
}
if (range && typeof range === 'string' && formula.iscelldata(range)) {
range = formula.getcellrange(range)
}
let r1 = range.row[0],
r2 = range.row[1],
c1 = range.column[0],
c2 = range.column[1];
let hasMc = false; //Whether the sort selection has merged cells
let data = [];
for(let r = r1; r <= r2; r++){
let data_row = [];
for(let c = c1; c <= c2; c++){
if(fileData[r][c] != null && fileData[r][c].mc != null){
hasMc = true;
break;
}
data_row.push(fileData[r][c]);
}
data.push(data_row);
}
if(hasMc){
tooltip.info(locale().sort.mergeError, "");
return;
}
data = orderbydata([].concat(data), 0, type === 'asc');
for(let r = r1; r <= r2; r++){
for(let c = c1; c <= c2; c++){
fileData[r][c] = data[r - r1][c - c1];
}
}
let allParam = {};
if(cfg["rowlen"] != null){
cfg = rowlenByRange(fileData, r1, r2, cfg);
allParam = {
"cfg": cfg,
"RowlChange": true
}
}
if (file.index == Store.currentSheetIndex) {
jfrefreshgrid(fileData, [{ "row": [r1, r2], "column": [c1, c2] }], allParam);
}
else{
file.data = fileData;
file.config = cfg;
}
if (success && typeof success === 'function') {
success();
}
}
/**
* 为指定索引的工作表选定的范围开启多列自定义排序功能返回选定范围排序后的数据
* @param {Boolean} hasTitle 数据是否具有标题行
* @param {Array} sort 列设置设置需要排序的列索引和排序方式格式如[{ i:0,sort:'asc' },{ i:1,sort:'des' }]
* @param {Object} options 可选参数
* @param {Object | String} options.range 选区范围,支持选区的格式为"A1:B2""sheetName!A1:B2"或者{row:[0,1],column:[0,1]}只能为单个选区默认为当前选区
* @param {Number} options.order 工作表索引默认值为当前工作表索引
* @param {Function} options.success 操作结束的回调函数
*/
export function setRangeSortMulti(hasTitle, sort, options = {}) {
if (!sort || !(sort instanceof Array)) {
return tooltip.info('The sort parameter is invalid.', '')
}
let curSheetOrder = getSheetIndex(Store.currentSheetIndex),
curRange = Store.luckysheet_select_save[0];
let {
range = curRange,
order = curSheetOrder,
success
} = {...options}
let file = Store.luckysheetfile[order],
cfg = $.extend(true, {}, file.config),
fileData = $.extend(true, [], file.data);
if(range instanceof Array && range.length > 1){
tooltip.info(locale().sort.noRangeError, "");
return;
}
if (range && typeof range === 'string' && formula.iscelldata(range)) {
range = formula.getcellrange(range)
}
let r1 = range.row[0],
r2 = range.row[1],
c1 = range.column[0],
c2 = range.column[1];
let str;
if(hasTitle){
str = r1 + 1;
} else{
str = r1;
}
let hasMc = false; //Whether the sort selection has merged cells
let data = [];
for(let r = str; r <= r2; r++){
let data_row = [];
for(let c = c1; c <= c2; c++){
if(fileData[r][c] != null && fileData[r][c].mc != null){
hasMc = true;
break;
}
data_row.push(fileData[r][c]);
}
data.push(data_row);
}
if(hasMc){
tooltip.info(locale().sort.mergeError, "");
return;
}
sort.forEach(sortItem => {
let i = sortItem.i;
i -= c1;
data = orderbydata([].concat(data), i, sortItem.sort === 'asc');
})
for(let r = str; r <= r2; r++){
for(let c = c1; c <= c2; c++){
fileData[r][c] = data[r - str][c - c1];
}
}
let allParam = {};
if(cfg["rowlen"] != null){
cfg = rowlenByRange(fileData, str, r2, cfg);
allParam = {
"cfg": cfg,
"RowlChange": true
}
}
if (file.index === Store.currentSheetIndex) {
jfrefreshgrid(fileData, [{ "row": [str, r2], "column": [c1, c2] }], allParam);
}
else{
file.data = fileData;
file.config = cfg;
}
if (success && typeof success === 'function') {
success();
}
}
/**
*
* @param {String} move 删除后右侧还是下方的单元格移动
* @param {Object} options 可选参数
*/
function deleteRange(move, options = {}) {
}
/**
* 指定工作表指定单元格区域的数据进行矩阵操作返回操作成功后的结果数据
* @param {String} type 矩阵操作的类型
* @param {Object} options 可选参数
* @param {Object | String} options.range 选区范围,支持选区的格式为"A1:B2""sheetName!A1:B2"或者{row:[0,1],column:[0,1]}只能为单个选区默认为当前选区
* @param {Function} options.success 操作结束的回调函数
*/
export function matrixOperation(type, options = {}) {
let typeValues = [
'flipUpDown', // 上下翻转
'flipLeftRight', // 左右翻转
'flipClockwise', // 顺时针旋转
'flipCounterClockwise', // 逆时针旋转
'transpose', // 转置
'deleteZeroByRow', // 按行删除两端0值
'deleteZeroByColumn', // 按列删除两端0值
'removeDuplicateByRow', // 按行删除重复值
'removeDuplicateByColumn', // 按列删除重复值
'newMatrix' // 生产新矩阵
]
if (!type || typeValues.indexOf(type) < 0) {
return tooltip.info('The type parameter is invalid.', '')
}
let curRange = Store.luckysheet_select_save[0];
let {
range = curRange,
success
} = {...options}
if(range instanceof Array && range.length > 1){
tooltip.info(locale().drag.noMulti, "");
return;
}
if (range && typeof range === 'string' && formula.iscelldata(range)) {
range = formula.getcellrange(range)
}
let getdata = getdatabyselection(range);
let arr = [];
if (getdata.length === 0) {
return;
}
let getdatalen, collen, arr1;
switch (type) {
case 'flipUpDown':
for (let r = getdata.length - 1; r >= 0; r--) {
let a = [];
for (let c = 0; c < getdata[0].length; c++) {
let value = "";
if (getdata[r] != null && getdata[r][c] != null) {
value = getdata[r][c];
}
a.push(value);
}
arr.push(a);
}
break;
case 'flipLeftRight':
for (let r = 0; r < getdata.length; r++) {
let a = [];
for (let c = getdata[0].length - 1; c >= 0; c--) {
let value = "";
if (getdata[r] != null && getdata[r][c] != null) {
value = getdata[r][c];
}
a.push(value);
}
arr.push(a);
}
break;
case 'flipClockwise':
for (let c = 0; c < getdata[0].length; c++) {
let a = [];
for (let r = getdata.length - 1; r >= 0; r--) {
let value = "";
if (getdata[r] != null && getdata[r][c] != null) {
value = getdata[r][c];
}
a.push(value);
}
arr.push(a);
}
break;
case 'flipCounterClockwise':
for (let c = getdata[0].length - 1; c >= 0; c--) {
let a = [];
for (let r = 0; r < getdata.length; r++) {
let value = "";
if (getdata[r] != null && getdata[r][c] != null) {
value = getdata[r][c];
}
a.push(value);
}
arr.push(a);
}
break;
case 'transpose':
for (let c = 0; c < getdata[0].length; c++) {
let a = [];
for (let r = 0; r < getdata.length; r++) {
let value = "";
if (getdata[r] != null && getdata[r][c] != null) {
value = getdata[r][c];
}
a.push(value);
}
arr.push(a);
}
break;
case 'deleteZeroByRow':
getdatalen = getdata[0].length;
for (let r = 0; r < getdata.length; r++) {
let a = [], stdel = true, eddel = true;
for (let c = 0; c < getdatalen; c++) {
let value = "";
if (getdata[r] != null && getdata[r][c] != null) {
value = getdata[r][c];
if ((value.v == "0" || value.v == 0) && stdel) {
continue;
}
else {
stdel = false;
}
}
a.push(value);
}
let a1 = [];
if (a.length == getdatalen) {
a1 = a;
} else {
for (let c = a.length - 1; c >= 0; c--) {
let value = "";
if (a[c] != null) {
value = a[c];
if ((value.v == "0" || value.v == 0) && eddel) {
continue;
}
else {
eddel = false;
}
}
a1.unshift(value);
}
let l = getdatalen - a1.length;
for (let c1 = 0; c1 < l; c1++) {
a1.push("");
}
}
arr.push(a1);
}
break;
case 'deleteZeroByColumn':
getdatalen = getdata.length;
collen = getdata[0].length;
for (let c = 0; c < collen; c++) {
let a = [], stdel = true, eddel = true;
for (let r = 0; r < getdatalen; r++) {
let value = "";
if (getdata[r] != null && getdata[r][c] != null) {
value = getdata[r][c];
if ((value.v == "0" || value.v == 0) && stdel) {
continue;
}
else {
stdel = false;
}
}
a.push(value);
}
let a1 = [];
if (a.length == getdatalen) {
a1 = a;
}
else {
for (let r = a.length - 1; r >= 0; r--) {
let value = "";
if (a[r] != null) {
value = a[r];
if ((value.v == "0" || value.v == 0) && eddel) {
continue;
}
else {
eddel = false;
}
}
a1.unshift(value);
}
let l = getdatalen - a1.length;
for (let r1 = 0; r1 < l; r1++) {
a1.push("");
}
}
arr.push(a1);
}
arr1 = [];
for (let c = 0; c < arr[0].length; c++) {
let a = [];
for (let r = 0; r < arr.length; r++) {
let value = "";
if (arr[r] != null && arr[r][c] != null) {
value = arr[r][c];
}
a.push(value);
}
arr1.push(a);
}
break;
case 'removeDuplicateByRow':
getdatalen = getdata[0].length;
for (let r = 0; r < getdata.length; r++) {
let a = [], repeat = {};
for (let c = 0; c < getdatalen; c++) {
let value = null;
if (getdata[r] != null && getdata[r][c] != null) {
value = getdata[r][c];
if(value.v in repeat){
repeat[value.v].push(value);
}
else{
repeat[value.v] = [];
repeat[value.v].push(value);
}
}
}
for (let c = 0; c < getdatalen; c++) {
let value = null;
if (getdata[r] != null && getdata[r][c] != null) {
value = getdata[r][c];
if(repeat[value.v].length == 1){
a.push(value);
}
}
}
let l = getdatalen - a.length;
for (let c1 = 0; c1 < l; c1++) {
a.push(null);
}
arr.push(a);
}
break;
case 'removeDuplicateByColumn':
collen = getdata[0].length;
getdatalen = getdata.length;
for (let c = 0; c < collen; c++) {
let a = [], repeat = {};
for (let r = 0; r < getdatalen; r++) {
let value = null;
if (getdata[r] != null && getdata[r][c] != null) {
value = getdata[r][c];
if(value.v in repeat){
repeat[value.v].push(value);
}
else{
repeat[value.v] = [];
repeat[value.v].push(value);
}
}
}
for (let r = 0; r < getdatalen; r++) {
let value = null;
if (getdata[r] != null && getdata[r][c] != null) {
value = getdata[r][c];
if(repeat[value.v].length == 1){
a.push(value);
}
}
}
a1 = a;
let l = getdatalen - a1.length;
for (let r1 = 0; r1 < l; r1++) {
a1.push(null);
}
arr.push(a1);
}
arr1 = [];
for (let c = 0; c < arr[0].length; c++) {
let a = [];
for (let r = 0; r < arr.length; r++) {
let value = null;
if (arr[r] != null && arr[r][c] != null) {
value = arr[r][c];
}
a.push(value);
}
arr1.push(a);
}
break;
case 'newMatrix':
// TODO
console.log("TODO")
break;
}
editor.controlHandler(arr, range)
if (success && typeof success === 'function') {
success();
}
}
/**
* 指定工作表指定单元格区域的数据进行矩阵计算返回计算成功后的结果数据
* @param {String} type 计算方式
* @param {Number} number 计算数值
* @param {Object} options 可选参数
* @param {Object | String} options.range 选区范围,支持选区的格式为"A1:B2""sheetName!A1:B2"或者{row:[0,1],column:[0,1]}只能为单个选区默认为当前选区
* @param {Function} options.success 操作结束的回调函数
*/
export function matrixCalculation(type, number, options = {}) {
let typeValues = [
'plus', // 加
'minus', // 减
'multiply', // 乘
'divided', // 除
'power', // 幂
'root', // 次方根
'log' // 对数log
]
if (!type || typeValues.indexOf(type) < 0) {
return tooltip.info('The type parameter is invalid.', '')
}
if(number.toString() == "NaN"){
return tooltip.info('The number parameter is invalid.', '')
}
let curRange = Store.luckysheet_select_save[0];
let {
range = curRange,
success
} = {...options}
if(range instanceof Array && range.length > 1){
tooltip.info(locale().drag.noMulti, "");
return;
}
if (range && typeof range === 'string' && formula.iscelldata(range)) {
range = formula.getcellrange(range)
}
let getdata = getdatabyselection(range);
if (getdata.length == 0) {
return;
}
let arr = [];
for (let r = 0; r < getdata.length; r++) {
let a = [];
for (let c = 0; c < getdata[0].length; c++) {
let value = "";
if (getdata[r] != null && getdata[r][c] != null) {
value = getdata[r][c];
if (parseInt(value) != null && getdata[r][c].ct != undefined && getdata[r][c].ct.t == "n") {
if (type == "minus") {
value.v = value.v - number;
}
else if (type == "multiply") {
value.v = value.v * number;
}
else if (type == "divided") {
value.v = numFormat(value.v / number, 4);
}
else if (type == "power") {
value.v = Math.pow(value.v, number);
}
else if (type == "root") {
if (number == 2) {
value.v = numFormat(Math.sqrt(value.v), 4);
}
else if (number == 3 && Math.cbrt) {
value.v = numFormat(Math.cbrt(value.v), 4);
}
else {
value.v = numFormat(jfnqrt(value.v, number), 4);
}
}
else if (type == "log") {
value.v = numFormat(Math.log(value.v) * 10000 / Math.log(Math.abs(number)), 4);
}
else {
value.v = value.v + number;
}
if(value.v == null){
value.m = "";
}
else{
value.m = value.v.toString();
}
}
}
a.push(value);
}
arr.push(a);
}
editor.controlHandler(arr, range);
if (success && typeof success === 'function') {
success();
}
}
/**
* 新增一个sheet返回新增的工作表对象
* @param {Object} options 可选参数
* @param {Object} options.sheetObject 新增的工作表的数据默认值为空对象
* @param {Number} options.order 新增的工作表索引默认值为最后一个索引位置
* @param {Function} options.success 操作结束的回调函数
*/
export function setSheetAdd(options = {}) {
let lastOrder = Store.luckysheetfile.length - 1;
let {
sheetObject = {},
order = lastOrder,
success
} = {...options}
if(!isRealNum(order)){
return tooltip.info("Parameter is not a table index", "");
}
order = Number(order);
let index = sheetmanage.generateRandomSheetIndex();
let sheetname = sheetmanage.generateRandomSheetName(Store.luckysheetfile, false);
if(!!sheetObject.name){
let sameName = false;
for(let i = 0; i < Store.luckysheetfile.length; i++){
if(Store.luckysheetfile[i].name == sheetObject.name){
sameName = true;
break;
}
}
if(!sameName){
sheetname = sheetObject.name;
}
}
$("#luckysheet-sheet-container-c").append(replaceHtml(sheetHTML, {
"index": index,
"active": "",
"name": sheetname,
"style": "",
"colorset": ""
}));
let sheetconfig = {
"name": "",
"color": "",
"status": "0",
"order": "",
"index": "",
"celldata": [],
"row": Store.defaultrowNum,
"column": Store.defaultcolumnNum,
"config": {},
"pivotTable": null,
"isPivotTable": false
};
sheetconfig = $.extend(true, sheetconfig, sheetObject);
sheetconfig.index = index;
sheetconfig.name = sheetname;
sheetconfig.order = order;
if(order <= 0){
let beforeIndex = Store.luckysheetfile[0].index;
let beforeObj = $("#luckysheet-sheets-item" + beforeIndex);
$("#luckysheet-sheets-item" + index).insertBefore(beforeObj);
Store.luckysheetfile.splice(0, 0, sheetconfig);
}
else{
if(order > Store.luckysheetfile.length){
order = Store.luckysheetfile.length;
}
let afterIndex = Store.luckysheetfile[order - 1].index;
let afterObj = $("#luckysheet-sheets-item" + afterIndex);
$("#luckysheet-sheets-item" + index).insertAfter(afterObj);
Store.luckysheetfile.splice(order, 0, sheetconfig);
}
Store.luckysheetfile.forEach((item, i, arr) => {
arr[i].order = i;
})
$("#luckysheet-sheet-area div.luckysheet-sheets-item").removeClass("luckysheet-sheets-item-active");
$("#luckysheet-sheets-item" + index).addClass("luckysheet-sheets-item-active");
$("#luckysheet-cell-main").append('<div id="luckysheet-datavisual-selection-set-' + index + '" class="luckysheet-datavisual-selection-set"></div>');
cleargridelement(true);
server.saveParam("sha", null, $.extend(true, {}, sheetconfig));
if (Store.clearjfundo) {
Store.jfundo = [];
let redo = {};
redo["type"] = "addSheet";
redo["sheetconfig"] = $.extend(true, {}, sheetconfig);
redo["index"] = index;
redo["currentSheetIndex"] = Store.currentSheetIndex;
Store.jfredo.push(redo);
}
sheetmanage.changeSheetExec(index, false, true);
}
/**
* 根据窗口大小自动resize画布
*
* @param {Object} options 可选参数
* @param {Function} options.success 操作结束的回调函数
*/
export function resize(options = {}){
luckysheetsizeauto();
let {
success
} = {...options}
if (success && typeof success === 'function') {
success();
}
}
/**
* 根据index获取sheet页配置
*
* @param {Object} options 可选参数
* @param {String} options.index 工作表index
* @param {Number} options.order 工作表order
* @param {String} options.name 工作表name
*/
export function getSheet(options = {}){
let {
index,
order,
name
} = {...options};
if(index != null){
return sheetmanage.getSheetByIndex(index);
}else if(order != null){
return Store.luckysheetfile[order];
}else if(name != null){
return sheetmanage.getSheetByName(name);
}
return sheetmanage.getSheetByIndex();
}