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.
4034 lines
136 KiB
4034 lines
136 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 { isdatetime, diff } from "./datecontroll";
|
|
import { getBorderInfoCompute } from './border';
|
|
|
|
import server from "../controllers/server";
|
|
import menuButton from '../controllers/menuButton';
|
|
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 conditionformat from '../controllers/conditionformat';
|
|
import { luckysheet_searcharray } from "../controllers/sheetSearch";
|
|
import { selectHightlightShow, selectIsOverlap } from '../controllers/select';
|
|
import { sheetHTML } from '../controllers/constant';
|
|
import { createFilterOptions } from '../controllers/filter';
|
|
|
|
|
|
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}
|
|
|
|
|
|
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.', '')
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 复制指定工作表指定单元格区域的数据,返回包含`<table>`html格式的数据,可用于粘贴到excel中保持单元格样式。
|
|
* @param {Object} options 可选参数
|
|
* @param {Array | Object | String} options.range 选区范围
|
|
* @param {order} options.order 工作表下标
|
|
*/
|
|
export function getRangeHtml(options = {}) {
|
|
let {
|
|
range = Store.luckysheet_select_save,
|
|
order = getSheetIndex(Store.currentSheetIndex),
|
|
success
|
|
} = {...options}
|
|
|
|
if(getObjType(range) == 'string'){
|
|
if(!formula.iscelldata(range)){
|
|
return tooltip.info("The range parameter is invalid.", "");
|
|
}
|
|
|
|
let cellrange = formula.getcellrange(range);
|
|
range = [{
|
|
"row": cellrange.row,
|
|
"column": cellrange.column
|
|
}]
|
|
}
|
|
else if(getObjType(range) == 'object'){
|
|
if(range.row == null || range.column == null){
|
|
return tooltip.info("The range parameter is invalid.", "");
|
|
}
|
|
|
|
range = [{
|
|
"row": range.row,
|
|
"column": range.column
|
|
}];
|
|
}
|
|
|
|
let file = Store.luckysheetfile[order];
|
|
|
|
if(file == null){
|
|
return tooltip.info("The order parameter is invalid.", "");
|
|
}
|
|
|
|
//复制范围内包含部分合并单元格,提示
|
|
let cfg = $.extend(true, {}, file.config);
|
|
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 cdformat = $.extend(true, [], file.luckysheet_conditionformat_save);
|
|
if (range.length > 1 && cdformat.length > 0) {
|
|
let hasCF = false;
|
|
let cf_compute = conditionformat.getComputeMap(file.index);
|
|
|
|
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];
|
|
|
|
for (let r = r1; r <= r2; r++) {
|
|
for (let c = c1; c <= c2; c++) {
|
|
if (conditionformat.checksCF(r, c, cf_compute) != null) {
|
|
hasCF = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hasCF) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hasCF) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hasCF) {
|
|
return tooltip.info("Cannot perform this operation on multiple selection areas, please select a single area", "");
|
|
}
|
|
}
|
|
|
|
//多重选区 行不一样且列不一样时 提示
|
|
if (range.length > 1) {
|
|
let isSameRow = true,
|
|
str_r = range[0].row[0],
|
|
end_r = range[0].row[1];
|
|
let isSameCol = true,
|
|
str_c = range[0].column[0],
|
|
end_c = range[0].column[1];
|
|
|
|
for (let s = 1; s < range.length; s++) {
|
|
if (range[s].row[0] != str_r || range[s].row[1] != end_r) {
|
|
isSameRow = false;
|
|
}
|
|
|
|
if (range[s].column[0] != str_c || range[s].column[1] != end_c) {
|
|
isSameCol = false;
|
|
}
|
|
}
|
|
|
|
if ((!isSameRow && !isSameCol) || selectIsOverlap(range)) {
|
|
return tooltip.info("Cannot perform this operation on multiple selection areas, please select a single area", "");
|
|
}
|
|
}
|
|
|
|
let rowIndexArr = [], colIndexArr = [];
|
|
|
|
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];
|
|
|
|
for(let r = r1; r <= r2; r++){
|
|
if (cfg["rowhidden"] != null && cfg["rowhidden"][r] != null) {
|
|
continue;
|
|
}
|
|
|
|
if(!rowIndexArr.includes(r)){
|
|
rowIndexArr.push(r);
|
|
}
|
|
|
|
for(let c = c1; c <= c2; c++){
|
|
if (cfg["colhidden"] != null && cfg["colhidden"][c] != null) {
|
|
continue;
|
|
}
|
|
|
|
if(!colIndexArr.includes(c)){
|
|
colIndexArr.push(c);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let borderInfoCompute;
|
|
if(cfg["borderInfo"] && cfg["borderInfo"].length > 0){ //边框
|
|
borderInfoCompute = getBorderInfoCompute(file.index);
|
|
}
|
|
|
|
let d = file.data;
|
|
if(d == null || d.length == 0){
|
|
d = sheetmanage.buildGridData(file);
|
|
}
|
|
|
|
let cpdata = "";
|
|
let colgroup = "";
|
|
|
|
rowIndexArr = rowIndexArr.sort();
|
|
colIndexArr = colIndexArr.sort();
|
|
|
|
for (let i = 0; i < rowIndexArr.length; i++) {
|
|
let r = rowIndexArr[i];
|
|
|
|
if (cfg["rowhidden"] != null && cfg["rowhidden"][r] != null) {
|
|
continue;
|
|
}
|
|
|
|
cpdata += '<tr>';
|
|
|
|
for (let j = 0; j < colIndexArr.length; j++) {
|
|
let c = colIndexArr[j];
|
|
|
|
if (cfg["colhidden"] != null && cfg["colhidden"][c] != null) {
|
|
continue;
|
|
}
|
|
|
|
let column = '<td ${span} style="${style}">';
|
|
|
|
if (d[r] != null && d[r][c] != null) {
|
|
let style = "", span = "";
|
|
|
|
if(r == rowIndexArr[0]){
|
|
if(cfg["columnlen"] == null || cfg["columnlen"][c.toString()] == null){
|
|
colgroup += '<colgroup width="72px"></colgroup>';
|
|
}
|
|
else {
|
|
colgroup += '<colgroup width="'+ cfg["columnlen"][c.toString()] +'px"></colgroup>';
|
|
}
|
|
}
|
|
|
|
if(c == colIndexArr[0]){
|
|
if(cfg["rowlen"] == null || cfg["rowlen"][r.toString()] == null){
|
|
style += 'height:19px;';
|
|
}
|
|
else {
|
|
style += 'height:'+ cfg["rowlen"][r.toString()] + 'px;';
|
|
}
|
|
}
|
|
|
|
let reg = /^(w|W)((0?)|(0\.0+))$/;
|
|
let c_value;
|
|
if(d[r][c].ct != null && d[r][c].ct.fa != null && d[r][c].ct.fa.match(reg)){
|
|
c_value = getcellvalue(r, c, d);
|
|
}
|
|
else{
|
|
c_value = getcellvalue(r, c, d, "m");
|
|
}
|
|
|
|
style += menuButton.getStyleByCell(d, r, c);
|
|
|
|
if(getObjType(d[r][c]) == "object" && ("mc" in d[r][c])){
|
|
if("rs" in d[r][c]["mc"]){
|
|
span = 'rowspan="'+ d[r][c]["mc"].rs +'" colspan="'+ d[r][c]["mc"].cs +'"';
|
|
|
|
//边框
|
|
if(borderInfoCompute && borderInfoCompute[r + "_" + c]){
|
|
let bl_obj = { "color": {}, "style": {} },
|
|
br_obj = { "color": {}, "style": {} },
|
|
bt_obj = { "color": {}, "style": {} },
|
|
bb_obj = { "color": {}, "style": {} };
|
|
|
|
for(let bd_r = r; bd_r < (r + d[r][c]["mc"].rs); bd_r++){
|
|
for(let bd_c = c; bd_c < (c + d[r][c]["mc"].cs); bd_c++){
|
|
if(bd_r == r && borderInfoCompute[bd_r + "_" + bd_c] && borderInfoCompute[bd_r + "_" + bd_c].t){
|
|
let linetype = borderInfoCompute[bd_r + "_" + bd_c].t.style;
|
|
let bcolor = borderInfoCompute[bd_r + "_" + bd_c].t.color;
|
|
|
|
if(bt_obj["style"][linetype] == null){
|
|
bt_obj["style"][linetype] = 1;
|
|
}
|
|
else{
|
|
bt_obj["style"][linetype] = bt_obj["style"][linetype] + 1;
|
|
}
|
|
|
|
if(bt_obj["color"][bcolor] == null){
|
|
bt_obj["color"][bcolor] = 1;
|
|
}
|
|
else{
|
|
bt_obj["color"][bcolor] = bt_obj["color"][bcolor] + 1;
|
|
}
|
|
}
|
|
|
|
if(bd_r == (r + d[r][c]["mc"].rs - 1) && borderInfoCompute[bd_r + "_" + bd_c] && borderInfoCompute[bd_r + "_" + bd_c].b){
|
|
let linetype = borderInfoCompute[bd_r + "_" + bd_c].b.style;
|
|
let bcolor = borderInfoCompute[bd_r + "_" + bd_c].b.color;
|
|
|
|
if(bb_obj["style"][linetype] == null){
|
|
bb_obj["style"][linetype] = 1;
|
|
}
|
|
else{
|
|
bb_obj["style"][linetype] = bb_obj["style"][linetype] + 1;
|
|
}
|
|
|
|
if(bb_obj["color"][bcolor] == null){
|
|
bb_obj["color"][bcolor] = 1;
|
|
}
|
|
else{
|
|
bb_obj["color"][bcolor] = bb_obj["color"][bcolor] + 1;
|
|
}
|
|
}
|
|
|
|
if(bd_c == c && borderInfoCompute[bd_r + "_" + bd_c] && borderInfoCompute[bd_r + "_" + bd_c].l){
|
|
let linetype = borderInfoCompute[r + "_" + c].l.style;
|
|
let bcolor = borderInfoCompute[bd_r + "_" + bd_c].l.color;
|
|
|
|
if(bl_obj["style"][linetype] == null){
|
|
bl_obj["style"][linetype] = 1;
|
|
}
|
|
else{
|
|
bl_obj["style"][linetype] = bl_obj["style"][linetype] + 1;
|
|
}
|
|
|
|
if(bl_obj["color"][bcolor] == null){
|
|
bl_obj["color"][bcolor] = 1;
|
|
}
|
|
else{
|
|
bl_obj["color"][bcolor] = bl_obj["color"][bcolor] + 1;
|
|
}
|
|
}
|
|
|
|
if(bd_c == (c + d[r][c]["mc"].cs - 1) && borderInfoCompute[bd_r + "_" + bd_c] && borderInfoCompute[bd_r + "_" + bd_c].r){
|
|
let linetype = borderInfoCompute[bd_r + "_" + bd_c].r.style;
|
|
let bcolor = borderInfoCompute[bd_r + "_" + bd_c].r.color;
|
|
|
|
if(br_obj["style"][linetype] == null){
|
|
br_obj["style"][linetype] = 1;
|
|
}
|
|
else{
|
|
br_obj["style"][linetype] = br_obj["style"][linetype] + 1;
|
|
}
|
|
|
|
if(br_obj["color"][bcolor] == null){
|
|
br_obj["color"][bcolor] = 1;
|
|
}
|
|
else{
|
|
br_obj["color"][bcolor] = br_obj["color"][bcolor] + 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
let rowlen = d[r][c]["mc"].rs, collen = d[r][c]["mc"].cs;
|
|
|
|
if(JSON.stringify(bl_obj).length > 23){
|
|
let bl_color = null, bl_style = null;
|
|
|
|
for(let x in bl_obj.color){
|
|
if(bl_obj.color[x] >= (rowlen / 2)){
|
|
bl_color = x;
|
|
}
|
|
}
|
|
|
|
for(let x in bl_obj.style){
|
|
if(bl_obj.style[x] >= (rowlen / 2)){
|
|
bl_style = x;
|
|
}
|
|
}
|
|
|
|
if(bl_color != null && bl_style != null){
|
|
style += "border-left:" + selection.getHtmlBorderStyle(bl_style, bl_color);
|
|
}
|
|
}
|
|
|
|
if(JSON.stringify(br_obj).length > 23){
|
|
let br_color = null, br_style = null;
|
|
|
|
for(let x in br_obj.color){
|
|
if(br_obj.color[x] >= (rowlen / 2)){
|
|
br_color = x;
|
|
}
|
|
}
|
|
|
|
for(let x in br_obj.style){
|
|
if(br_obj.style[x] >= (rowlen / 2)){
|
|
br_style = x;
|
|
}
|
|
}
|
|
|
|
if(br_color != null && br_style != null){
|
|
style += "border-right:" + selection.getHtmlBorderStyle(br_style, br_color);
|
|
}
|
|
}
|
|
|
|
if(JSON.stringify(bt_obj).length > 23){
|
|
let bt_color = null, bt_style = null;
|
|
|
|
for(let x in bt_obj.color){
|
|
if(bt_obj.color[x] >= (collen / 2)){
|
|
bt_color = x;
|
|
}
|
|
}
|
|
|
|
for(let x in bt_obj.style){
|
|
if(bt_obj.style[x] >= (collen / 2)){
|
|
bt_style = x;
|
|
}
|
|
}
|
|
|
|
if(bt_color != null && bt_style != null){
|
|
style += "border-top:" + selection.getHtmlBorderStyle(bt_style, bt_color);
|
|
}
|
|
}
|
|
|
|
if(JSON.stringify(bb_obj).length > 23){
|
|
let bb_color = null, bb_style = null;
|
|
|
|
for(let x in bb_obj.color){
|
|
if(bb_obj.color[x] >= (collen / 2)){
|
|
bb_color = x;
|
|
}
|
|
}
|
|
|
|
for(let x in bb_obj.style){
|
|
if(bb_obj.style[x] >= (collen / 2)){
|
|
bb_style = x;
|
|
}
|
|
}
|
|
|
|
if(bb_color != null && bb_style != null){
|
|
style += "border-bottom:" + selection.getHtmlBorderStyle(bb_style, bb_color);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
continue;
|
|
}
|
|
}
|
|
else{
|
|
//边框
|
|
if(borderInfoCompute && borderInfoCompute[r + "_" + c]){
|
|
//左边框
|
|
if(borderInfoCompute[r + "_" + c].l){
|
|
let linetype = borderInfoCompute[r + "_" + c].l.style;
|
|
let bcolor = borderInfoCompute[r + "_" + c].l.color;
|
|
style += "border-left:" + selection.getHtmlBorderStyle(linetype, bcolor);
|
|
}
|
|
|
|
//右边框
|
|
if(borderInfoCompute[r + "_" + c].r){
|
|
let linetype = borderInfoCompute[r + "_" + c].r.style;
|
|
let bcolor = borderInfoCompute[r + "_" + c].r.color;
|
|
style += "border-right:" + selection.getHtmlBorderStyle(linetype, bcolor);
|
|
}
|
|
|
|
//下边框
|
|
if(borderInfoCompute[r + "_" + c].b){
|
|
let linetype = borderInfoCompute[r + "_" + c].b.style;
|
|
let bcolor = borderInfoCompute[r + "_" + c].b.color;
|
|
style += "border-bottom:" + selection.getHtmlBorderStyle(linetype, bcolor);
|
|
}
|
|
|
|
//上边框
|
|
if(borderInfoCompute[r + "_" + c].t){
|
|
let linetype = borderInfoCompute[r + "_" + c].t.style;
|
|
let bcolor = borderInfoCompute[r + "_" + c].t.color;
|
|
style += "border-top:" + selection.getHtmlBorderStyle(linetype, bcolor);
|
|
}
|
|
}
|
|
}
|
|
|
|
column = replaceHtml(column, {"style": style, "span": span});
|
|
|
|
if(c_value == null){
|
|
c_value = getcellvalue(r, c, d);
|
|
}
|
|
|
|
if(c_value == null){
|
|
c_value = " ";
|
|
}
|
|
|
|
column += c_value;
|
|
}
|
|
else {
|
|
let style = "";
|
|
|
|
//边框
|
|
if(borderInfoCompute && borderInfoCompute[r + "_" + c]){
|
|
//左边框
|
|
if(borderInfoCompute[r + "_" + c].l){
|
|
let linetype = borderInfoCompute[r + "_" + c].l.style;
|
|
let bcolor = borderInfoCompute[r + "_" + c].l.color;
|
|
style += "border-left:" + selection.getHtmlBorderStyle(linetype, bcolor);
|
|
}
|
|
|
|
//右边框
|
|
if(borderInfoCompute[r + "_" + c].r){
|
|
let linetype = borderInfoCompute[r + "_" + c].r.style;
|
|
let bcolor = borderInfoCompute[r + "_" + c].r.color;
|
|
style += "border-right:" + selection.getHtmlBorderStyle(linetype, bcolor);
|
|
}
|
|
|
|
//下边框
|
|
if(borderInfoCompute[r + "_" + c].b){
|
|
let linetype = borderInfoCompute[r + "_" + c].b.style;
|
|
let bcolor = borderInfoCompute[r + "_" + c].b.color;
|
|
style += "border-bottom:" + selection.getHtmlBorderStyle(linetype, bcolor);
|
|
}
|
|
|
|
//上边框
|
|
if(borderInfoCompute[r + "_" + c].t){
|
|
let linetype = borderInfoCompute[r + "_" + c].t.style;
|
|
let bcolor = borderInfoCompute[r + "_" + c].t.color;
|
|
style += "border-top:" + selection.getHtmlBorderStyle(linetype, bcolor);
|
|
}
|
|
}
|
|
|
|
column += "";
|
|
|
|
if(r == rowIndexArr[0]){
|
|
if(cfg["columnlen"] == null || cfg["columnlen"][c.toString()] == null){
|
|
colgroup += '<colgroup width="72px"></colgroup>';
|
|
}
|
|
else {
|
|
colgroup += '<colgroup width="'+ cfg["columnlen"][c.toString()] +'px"></colgroup>';
|
|
}
|
|
}
|
|
|
|
if(c == colIndexArr[0]){
|
|
if(cfg["rowlen"] == null || cfg["rowlen"][r.toString()] == null){
|
|
style += 'height:19px;';
|
|
}
|
|
else {
|
|
style += 'height:'+ cfg["rowlen"][r.toString()] + 'px;';
|
|
}
|
|
}
|
|
|
|
column = replaceHtml(column, {"style": style, "span": ""});
|
|
column += " ";
|
|
}
|
|
|
|
column += '</td>';
|
|
cpdata += column;
|
|
}
|
|
|
|
cpdata += "</tr>";
|
|
}
|
|
|
|
cpdata = '<table data-type="luckysheet_copy_action_table">' + colgroup + cpdata + '</table>';
|
|
|
|
return cpdata;
|
|
}
|
|
|
|
|
|
/**
|
|
* 复制指定工作表指定单元格区域的数据,返回一维、二维或者自定义行列数的二维数组的数据。只有在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 工作表索引;默认值为当前工作表索引
|
|
*/
|
|
export function getRangeArray(dimensional, options = {}) {
|
|
let dimensionalValues = ['oneDimensional', 'twoDimensional'];
|
|
|
|
if(!dimensionalValues.includes(dimensional)){
|
|
return tooltip.info("The dimensional parameter is invalid.", "");
|
|
}
|
|
|
|
let {
|
|
range = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1],
|
|
order = getSheetIndex(Store.currentSheetIndex),
|
|
} = {...options}
|
|
|
|
let file = Store.luckysheetfile[order];
|
|
|
|
if(file == null){
|
|
return tooltip.info("The order parameter is invalid.", "");
|
|
}
|
|
|
|
if(getObjType(range) == 'string'){
|
|
if(!formula.iscelldata(range)){
|
|
return tooltip.info("The range parameter is invalid.", "");
|
|
}
|
|
|
|
range = formula.getcellrange(range);
|
|
}
|
|
|
|
if(getObjType(range) != 'object' || range.row == null || range.column == null){
|
|
return tooltip.info("The range parameter is invalid.", "");
|
|
}
|
|
|
|
let r1 = range.row[0],
|
|
r2 = range.row[1];
|
|
let c1 = range.column[0],
|
|
c2 = range.column[1];
|
|
|
|
//复制范围内包含部分合并单元格,提示
|
|
let cfg = $.extend(true, {}, file.config);
|
|
if(cfg["merge"] != null){
|
|
let has_PartMC = hasPartMC(cfg, r1, r2, c1, c2);
|
|
|
|
if(has_PartMC){
|
|
return tooltip.info("Cannot perform this operation on partially merged cells", "");
|
|
}
|
|
}
|
|
|
|
let data = file.data;
|
|
if(data == null || data.length == 0){
|
|
data = sheetmanage.buildGridData(file);
|
|
}
|
|
|
|
let dataArr = [];
|
|
|
|
if(dimensional == 'oneDimensional'){//一维数组
|
|
for(let r = r1; r <= r2; r++){
|
|
for(let c = c1; c <= c2; c++){
|
|
let cell = data[r][c];
|
|
dataArr.push(cell);
|
|
}
|
|
}
|
|
}
|
|
else if(dimensional == 'twoDimensional'){
|
|
for(let r = r1; r <= r2; r++){
|
|
let row = [];
|
|
|
|
for(let c = c1; c <= c2; c++){
|
|
let cell = data[r][c];
|
|
row.push(cell);
|
|
}
|
|
|
|
dataArr.push(row);
|
|
}
|
|
}
|
|
|
|
return dataArr;
|
|
}
|
|
|
|
/**
|
|
* 复制指定工作表指定单元格区域的数据,返回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));
|
|
}
|
|
|
|
|
|
/**
|
|
* 指定工作表选中一个或多个选区为选中状态并选择是否高亮,支持多种格式设置。
|
|
* @param {Array | Object | String} range 选区范围
|
|
* @param {Object} options 可选参数
|
|
* @param {Boolean} options.show 是否显示高亮选中效果;默认值为 `true`
|
|
* @param {Number} options.order 工作表下标;默认值为当前工作表下标
|
|
* @param {Function} options.success 操作结束的回调函数
|
|
*/
|
|
export function setRangeShow(range, options = {}) {
|
|
if(getObjType(range) == 'string'){
|
|
if(!formula.iscelldata(range)){
|
|
return tooltip.info("The range parameter is invalid.", "");
|
|
}
|
|
|
|
let cellrange = formula.getcellrange(range);
|
|
range = [{
|
|
"row": cellrange.row,
|
|
"column": cellrange.column
|
|
}]
|
|
}
|
|
else if(getObjType(range) == 'object'){
|
|
if(range.row == null || range.column == null){
|
|
return tooltip.info("The range parameter is invalid.", "");
|
|
}
|
|
|
|
range = [{
|
|
"row": range.row,
|
|
"column": range.column
|
|
}];
|
|
}
|
|
|
|
if(getObjType(range) != 'array'){
|
|
return tooltip.info("The range parameter is invalid.", "");
|
|
}
|
|
|
|
let {
|
|
show = true,
|
|
order = getSheetIndex(Store.currentSheetIndex),
|
|
success
|
|
} = {...options}
|
|
|
|
let file = Store.luckysheetfile[order];
|
|
|
|
if(file == null){
|
|
return tooltip.info("The order parameter is invalid.", "");
|
|
}
|
|
|
|
file.luckysheet_select_save = range;
|
|
|
|
if(file.index == Store.currentSheetIndex){
|
|
Store.luckysheet_select_save = range;
|
|
selectHightlightShow();
|
|
|
|
if(!show){
|
|
$("#luckysheet-cell-selected-boxs").hide();
|
|
$("#luckysheet-cell-selected-focus").hide();
|
|
$("#luckysheet-row-count-show").hide();
|
|
$("#luckysheet-column-count-show").hide();
|
|
$("#luckysheet-rows-h-selected").empty();
|
|
$("#luckysheet-cols-h-selected").empty();
|
|
}
|
|
}
|
|
|
|
if (success && typeof success === 'function') {
|
|
success();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 将一个单元格数组数据赋值到指定的区域,数据格式同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 操作结束的回调函数
|
|
*/
|
|
export function setRangeFilter(type, options = {}) {
|
|
let typeValues = ['open', 'close'];
|
|
|
|
if(!typeValues.includes(type)){
|
|
return tooltip.info("The type parameter is invalid.", "");
|
|
}
|
|
|
|
let {
|
|
range = Store.luckysheet_select_save[Store.luckysheet_select_save.length - 1],
|
|
order = getSheetIndex(Store.currentSheetIndex),
|
|
success
|
|
} = {...options}
|
|
|
|
let file = Store.luckysheetfile[order];
|
|
|
|
if(file == null){
|
|
return tooltip.info("The order parameter is invalid.", "");
|
|
}
|
|
|
|
if(getObjType(range) == 'string'){
|
|
if(!formula.iscelldata(range)){
|
|
return tooltip.info("The range parameter is invalid.", "");
|
|
}
|
|
|
|
range = formula.getcellrange(range);
|
|
}
|
|
|
|
if(getObjType(range) != 'object' || range.row == null || range.column == null){
|
|
return tooltip.info("The range parameter is invalid.", "");
|
|
}
|
|
|
|
setTimeout(() => {
|
|
if (success && typeof success === 'function') {
|
|
success();
|
|
}
|
|
}, 1);
|
|
|
|
if(type == 'open'){
|
|
file.filter_select = range;
|
|
|
|
if(file.index == Store.currentSheetIndex){
|
|
createFilterOptions(range, file.filter);
|
|
}
|
|
|
|
return {
|
|
"row": range.row,
|
|
"column": range.column
|
|
};
|
|
}
|
|
else if(type == 'close'){
|
|
let luckysheet_filter_save = $.extend(true, {}, file.filter_select);
|
|
|
|
file.filter_select = null;
|
|
|
|
$("#luckysheet-filter-selected-sheet" + file.index).remove();
|
|
$("#luckysheet-filter-options-sheet" + file.index).remove();
|
|
|
|
return {
|
|
"row": luckysheet_filter_save.row,
|
|
"column": luckysheet_filter_save.column
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 为指定索引的工作表,选定的范围设定合并单元格
|
|
* @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(data.length == 0){
|
|
data = $.extend(true, [], sheetmanage.buildGridData(file));
|
|
}
|
|
|
|
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(data.length == 0){
|
|
data = $.extend(true, [], sheetmanage.buildGridData(file));
|
|
}
|
|
|
|
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(fileData.length == 0){
|
|
fileData = $.extend(true, [], sheetmanage.buildGridData(file));
|
|
}
|
|
|
|
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(fileData.length == 0){
|
|
fileData = $.extend(true, [], sheetmanage.buildGridData(file));
|
|
}
|
|
|
|
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} conditionName 条件格式规则类型
|
|
* @param {Object} conditionValue 可以设置条件单元格或者条件值
|
|
* @param {Object} options 可选参数
|
|
* @param {Object} options.format 颜色设置
|
|
* @param {Array | Object | String} options.cellrange 选区范围
|
|
* @param {Number} options.order 工作表索引;默认值为当前工作表索引
|
|
* @param {Function} options.success 操作结束的回调函数
|
|
*/
|
|
export function setRangeConditionalFormatDefault(conditionName, conditionValue, options = {}) {
|
|
let conditionNameValues = [
|
|
'greaterThan',
|
|
'lessThan',
|
|
'betweenness',
|
|
'equal',
|
|
'textContains',
|
|
'occurrenceDate',
|
|
'duplicateValue',
|
|
'top10',
|
|
'top10%',
|
|
'last10',
|
|
'last10%',
|
|
'AboveAverage',
|
|
'SubAverage'
|
|
];
|
|
|
|
if(!conditionName || !conditionNameValues.includes(conditionName)){
|
|
return tooltip.info('The conditionName parameter is invalid.', '');
|
|
}
|
|
|
|
if(getObjType(conditionValue) != 'array' || conditionValue.length == 0){
|
|
return tooltip.info('The conditionValue parameter is invalid.', '');
|
|
}
|
|
|
|
let {
|
|
format = {
|
|
"textColor": "#000000",
|
|
"cellColor": "#ff0000"
|
|
},
|
|
cellrange = Store.luckysheet_select_save,
|
|
order = getSheetIndex(Store.currentSheetIndex),
|
|
success
|
|
} = {...options}
|
|
|
|
let file = Store.luckysheetfile[order];
|
|
let data = file.data;
|
|
|
|
if(data == null || data.length == 0){
|
|
data = sheetmanage.buildGridData(file);
|
|
}
|
|
|
|
if(file == null){
|
|
return tooltip.info('Incorrect worksheet index', '');
|
|
}
|
|
|
|
const conditionformat_Text = locale().conditionformat;
|
|
|
|
let conditionRange = [], conditionValue2 = [];
|
|
|
|
if(conditionName == 'betweenness'){
|
|
let v1 = conditionValue[0];
|
|
let v2 = conditionValue[1];
|
|
|
|
//条件值是否是选区
|
|
let rangeArr1 = conditionformat.getRangeByTxt(v1);
|
|
if(rangeArr1.length > 1){
|
|
conditionformat.infoDialog(conditionformat_Text.onlySingleCell, "");
|
|
return;
|
|
}
|
|
else if(rangeArr1.length == 1){
|
|
let r1 = rangeArr1[0].row[0], r2 = rangeArr1[0].row[1];
|
|
let c1 = rangeArr1[0].column[0], c2 = rangeArr1[0].column[1];
|
|
|
|
if(r1 == r2 && c1 == c2){
|
|
v1 = getcellvalue(r1, c1, data);
|
|
|
|
conditionRange.push({ "row": rangeArr1[0].row, "column": rangeArr1[0].column });
|
|
conditionValue2.push(v1);
|
|
}
|
|
else{
|
|
conditionformat.infoDialog(conditionformat_Text.onlySingleCell, "");
|
|
return;
|
|
}
|
|
}
|
|
else if(rangeArr1.length == 0){
|
|
if(isNaN(v1) || v1 == ""){
|
|
conditionformat.infoDialog(conditionformat_Text.conditionValueCanOnly, "");
|
|
return;
|
|
}
|
|
else{
|
|
conditionValue2.push(v1);
|
|
}
|
|
}
|
|
|
|
let rangeArr2 = conditionformat.getRangeByTxt(v2);
|
|
if(rangeArr2.length > 1){
|
|
conditionformat.infoDialog(conditionformat_Text.onlySingleCell, "");
|
|
return;
|
|
}
|
|
else if(rangeArr2.length == 1){
|
|
let r1 = rangeArr2[0].row[0], r2 = rangeArr2[0].row[1];
|
|
let c1 = rangeArr2[0].column[0], c2 = rangeArr2[0].column[1];
|
|
|
|
if(r1 == r2 && c1 == c2){
|
|
v2 = getcellvalue(r1, c1, data);
|
|
|
|
conditionRange.push({ "row": rangeArr2[0].row, "column": rangeArr2[0].column });
|
|
conditionValue2.push(v2);
|
|
}
|
|
else{
|
|
conditionformat.infoDialog(conditionformat_Text.onlySingleCell, "");
|
|
return;
|
|
}
|
|
}
|
|
else if(rangeArr2.length == 0){
|
|
if(isNaN(v2) || v2 == ""){
|
|
conditionformat.infoDialog(conditionformat_Text.conditionValueCanOnly, "");
|
|
return;
|
|
}
|
|
else{
|
|
conditionValue2.push(v2);
|
|
}
|
|
}
|
|
}
|
|
else if(conditionName == 'greaterThan' || conditionName == 'lessThan' || conditionName == 'equal'){
|
|
let v = conditionValue[0];
|
|
|
|
//条件值是否是选区
|
|
let rangeArr = conditionformat.getRangeByTxt(v);
|
|
if(rangeArr.length > 1){
|
|
conditionformat.infoDialog(conditionformat_Text.onlySingleCell, "");
|
|
return;
|
|
}
|
|
else if(rangeArr.length == 1){
|
|
let r1 = rangeArr[0].row[0], r2 = rangeArr[0].row[1];
|
|
let c1 = rangeArr[0].column[0], c2 = rangeArr[0].column[1];
|
|
|
|
if(r1 == r2 && c1 == c2){
|
|
v = getcellvalue(r1, c1, data);
|
|
|
|
conditionRange.push({ "row": rangeArr[0].row, "column": rangeArr[0].column });
|
|
conditionValue2.push(v);
|
|
}
|
|
else{
|
|
conditionformat.infoDialog(conditionformat_Text.onlySingleCell, "");
|
|
return;
|
|
}
|
|
}
|
|
else if(rangeArr.length == 0){
|
|
if(isNaN(v) || v == ""){
|
|
conditionformat.infoDialog(conditionformat_Text.conditionValueCanOnly, "");
|
|
return;
|
|
}
|
|
else{
|
|
conditionValue2.push(v);
|
|
}
|
|
}
|
|
}
|
|
else if(conditionName == 'textContains'){
|
|
let v = conditionValue[0];
|
|
|
|
//条件值是否是选区
|
|
let rangeArr = conditionformat.getRangeByTxt(v);
|
|
if(rangeArr.length > 1){
|
|
conditionformat.infoDialog(conditionformat_Text.onlySingleCell, "");
|
|
return;
|
|
}
|
|
else if(rangeArr.length == 1){
|
|
let r1 = rangeArr[0].row[0], r2 = rangeArr[0].row[1];
|
|
let c1 = rangeArr[0].column[0], c2 = rangeArr[0].column[1];
|
|
|
|
if(r1 == r2 && c1 == c2){
|
|
v = getcellvalue(r1, c1, data);
|
|
|
|
conditionRange.push({ "row": rangeArr[0].row, "column": rangeArr[0].column });
|
|
conditionValue2.push(v);
|
|
}
|
|
else{
|
|
conditionformat.infoDialog(conditionformat_Text.onlySingleCell, "");
|
|
return;
|
|
}
|
|
}
|
|
else if(rangeArr.length == 0){
|
|
if(v == ""){
|
|
conditionformat.infoDialog(conditionformat_Text.conditionValueCanOnly, "");
|
|
return;
|
|
}
|
|
else{
|
|
conditionValue2.push(v);
|
|
}
|
|
}
|
|
}
|
|
else if(conditionName == 'occurrenceDate'){
|
|
let v1 = conditionValue[0];
|
|
let v2 = conditionValue[1];
|
|
|
|
if(!isdatetime(v1) || !isdatetime(v2)){
|
|
return tooltip.info('The conditionValue parameter is invalid.', '');
|
|
}
|
|
|
|
let v;
|
|
if(diff(v1, v2) > 0){
|
|
v = moment(v2).format("YYYY/MM/DD") + "-" + moment(v1).format("YYYY/MM/DD");
|
|
}
|
|
else{
|
|
v = moment(v1).format("YYYY/MM/DD") + "-" + moment(v2).format("YYYY/MM/DD");
|
|
}
|
|
|
|
conditionValue2.push(v);
|
|
}
|
|
else if(conditionName == 'duplicateValue'){
|
|
let v = conditionValue[0];
|
|
|
|
if(v != '0' || v != '1'){
|
|
return tooltip.info('The conditionValue parameter is invalid.', '');
|
|
}
|
|
|
|
conditionValue2.push(v);
|
|
}
|
|
else if(conditionName == 'top10' || conditionName == 'top10%' || conditionName == 'last10' || conditionName == 'last10%'){
|
|
let v = conditionValue[0];
|
|
|
|
if(parseInt(v) != v || parseInt(v) < 1 || parseInt(v) > 1000){
|
|
conditionformat.infoDialog(conditionformat_Text.pleaseEnterInteger, "");
|
|
return;
|
|
}
|
|
|
|
conditionValue2.push(parseInt(v));
|
|
}
|
|
else if(conditionName == 'AboveAverage' || conditionName == 'SubAverage'){
|
|
conditionValue2.push(conditionName);
|
|
}
|
|
|
|
if(!format.hasOwnProperty("textColor") || !format.hasOwnProperty("cellColor")){
|
|
return tooltip.info('The format parameter is invalid.', '');
|
|
}
|
|
|
|
if(getObjType(cellrange) == 'string'){
|
|
cellrange = conditionformat.getRangeByTxt(cellrange);
|
|
}
|
|
else if(getObjType(cellrange) == 'object'){
|
|
cellrange = [cellrange];
|
|
}
|
|
|
|
let rule = {
|
|
"type": "default",
|
|
"cellrange": cellrange,
|
|
"format": format,
|
|
"conditionName": conditionName,
|
|
"conditionRange": conditionRange,
|
|
"conditionValue": conditionValue2
|
|
};
|
|
|
|
//保存之前的规则
|
|
let fileH = $.extend(true, [], Store.luckysheetfile);
|
|
let historyRules = conditionformat.getHistoryRules(fileH);
|
|
|
|
//保存当前的规则
|
|
let ruleArr = file["luckysheet_conditionformat_save"] || [];
|
|
ruleArr.push(rule);
|
|
file["luckysheet_conditionformat_save"] = ruleArr;
|
|
|
|
let fileC = $.extend(true, [], Store.luckysheetfile);
|
|
let currentRules = conditionformat.getCurrentRules(fileC);
|
|
|
|
//刷新一次表格
|
|
conditionformat.ref(historyRules, currentRules);
|
|
|
|
//发送给后台
|
|
if(server.allowUpdate){
|
|
server.saveParam("all", file.index, ruleArr, { "k": "luckysheet_conditionformat_save" });
|
|
}
|
|
|
|
if (success && typeof success === 'function') {
|
|
success();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 为指定索引的工作表,选定的范围开启条件格式,返回开启条件格式后的数据。
|
|
* @param {String} type 条件格式规则类型
|
|
* @param {Object} options 可选参数
|
|
* @param {Array | String} options.format 颜色设置
|
|
* @param {Array | Object | String} options.cellrange 选区范围
|
|
* @param {Number} options.order 工作表索引;默认值为当前工作表索引
|
|
* @param {Function} options.success 操作结束的回调函数
|
|
*/
|
|
export function setRangeConditionalFormat(type, options = {}) {
|
|
let typeValues = [
|
|
'dataBar',
|
|
'colorGradation',
|
|
'icons'
|
|
];
|
|
|
|
if(!type || !typeValues.includes(type)){
|
|
return tooltip.info('The type parameter is invalid.', '');
|
|
}
|
|
|
|
let {
|
|
format,
|
|
cellrange = Store.luckysheet_select_save,
|
|
order = getSheetIndex(Store.currentSheetIndex),
|
|
success
|
|
} = {...options}
|
|
|
|
let file = Store.luckysheetfile[order];
|
|
|
|
if(file == null){
|
|
return tooltip.info('Incorrect worksheet index', '');
|
|
}
|
|
|
|
if(type == 'dataBar'){
|
|
if(format == null){
|
|
format = ["#638ec6", "#ffffff"];
|
|
}
|
|
|
|
if(getObjType(format) != 'array' || format.length < 1 || format.length > 2){
|
|
return tooltip.info('The format parameter is invalid.', '');
|
|
}
|
|
}
|
|
else if(type == 'colorGradation'){
|
|
if(format == null){
|
|
format = ["rgb(99, 190, 123)", "rgb(255, 235, 132)", "rgb(248, 105, 107)"];
|
|
}
|
|
|
|
if(getObjType(format) != 'array' || format.length < 2 || format.length > 3){
|
|
return tooltip.info('The format parameter is invalid.', '');
|
|
}
|
|
}
|
|
else if(type == 'icons'){
|
|
if(format == null){
|
|
format = "threeWayArrowMultiColor";
|
|
}
|
|
|
|
let formatValues = [
|
|
'threeWayArrowMultiColor',
|
|
'threeTriangles',
|
|
'fourWayArrowMultiColor',
|
|
'fiveWayArrowMultiColor',
|
|
'threeWayArrowGrayColor',
|
|
'fourWayArrowGrayColor',
|
|
'fiveWayArrowGrayColor',
|
|
'threeColorTrafficLightRimless',
|
|
'threeSigns',
|
|
'greenRedBlackGradient',
|
|
'threeColorTrafficLightBordered',
|
|
'fourColorTrafficLight',
|
|
'threeSymbolsCircled',
|
|
'tricolorFlag',
|
|
'threeSymbolsnoCircle',
|
|
'threeStars',
|
|
'fiveQuadrantDiagram',
|
|
'fiveBoxes',
|
|
'grade4',
|
|
'grade5'
|
|
];
|
|
|
|
if(getObjType(format) != 'string' || !formatValues.includes(format)){
|
|
return tooltip.info('The format parameter is invalid.', '');
|
|
}
|
|
|
|
switch (format) {
|
|
case 'threeWayArrowMultiColor':
|
|
format = {
|
|
"len": 3,
|
|
"leftMin": 0,
|
|
"top": 0
|
|
};
|
|
break;
|
|
case 'threeTriangles':
|
|
format = {
|
|
"len": 3,
|
|
"leftMin": 0,
|
|
"top": 1
|
|
};
|
|
break;
|
|
case 'fourWayArrowMultiColor':
|
|
format = {
|
|
"len": 4,
|
|
"leftMin": 0,
|
|
"top": 2
|
|
};
|
|
break;
|
|
case 'fiveWayArrowMultiColor':
|
|
format = {
|
|
"len": 5,
|
|
"leftMin": 0,
|
|
"top": 3
|
|
};
|
|
break;
|
|
case 'threeWayArrowGrayColor':
|
|
format = {
|
|
"len": 3,
|
|
"leftMin": 5,
|
|
"top": 0
|
|
};
|
|
break;
|
|
case 'fourWayArrowGrayColor':
|
|
format = {
|
|
"len": 4,
|
|
"leftMin": 5,
|
|
"top": 1
|
|
};
|
|
break;
|
|
case 'fiveWayArrowGrayColor':
|
|
format = {
|
|
"len": 5,
|
|
"leftMin": 5,
|
|
"top": 2
|
|
};
|
|
break;
|
|
case 'threeColorTrafficLightRimless':
|
|
format = {
|
|
"len": 3,
|
|
"leftMin": 0,
|
|
"top": 4
|
|
};
|
|
break;
|
|
case 'threeSigns':
|
|
format = {
|
|
"len": 3,
|
|
"leftMin": 0,
|
|
"top": 5
|
|
};
|
|
break;
|
|
case 'greenRedBlackGradient':
|
|
format = {
|
|
"len": 4,
|
|
"leftMin": 0,
|
|
"top": 6
|
|
};
|
|
break;
|
|
case 'threeColorTrafficLightBordered':
|
|
format = {
|
|
"len": 3,
|
|
"leftMin": 5,
|
|
"top": 4
|
|
};
|
|
break;
|
|
case 'fourColorTrafficLight':
|
|
format = {
|
|
"len": 4,
|
|
"leftMin": 5,
|
|
"top": 5
|
|
};
|
|
break;
|
|
case 'threeSymbolsCircled':
|
|
format = {
|
|
"len": 3,
|
|
"leftMin": 0,
|
|
"top": 7
|
|
};
|
|
break;
|
|
case 'tricolorFlag':
|
|
format = {
|
|
"len": 3,
|
|
"leftMin": 0,
|
|
"top": 8
|
|
};
|
|
break;
|
|
case 'threeSymbolsnoCircle':
|
|
format = {
|
|
"len": 3,
|
|
"leftMin": 5,
|
|
"top": 7
|
|
};
|
|
break;
|
|
case 'threeStars':
|
|
format = {
|
|
"len": 3,
|
|
"leftMin": 0,
|
|
"top": 9
|
|
};
|
|
break;
|
|
case 'fiveQuadrantDiagram':
|
|
format = {
|
|
"len": 5,
|
|
"leftMin": 0,
|
|
"top": 10
|
|
};
|
|
break;
|
|
case 'fiveBoxes':
|
|
format = {
|
|
"len": 5,
|
|
"leftMin": 0,
|
|
"top": 11
|
|
};
|
|
break;
|
|
case 'grade4':
|
|
format = {
|
|
"len": 4,
|
|
"leftMin": 5,
|
|
"top": 9
|
|
};
|
|
break;
|
|
case 'grade5':
|
|
format = {
|
|
"len": 5,
|
|
"leftMin": 5,
|
|
"top": 10
|
|
};
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(getObjType(cellrange) == 'string'){
|
|
cellrange = conditionformat.getRangeByTxt(cellrange);
|
|
}
|
|
else if(getObjType(cellrange) == 'object'){
|
|
cellrange = [cellrange];
|
|
}
|
|
|
|
let rule = {
|
|
"type": type,
|
|
"cellrange": cellrange,
|
|
"format": format
|
|
};
|
|
|
|
//保存之前的规则
|
|
let fileH = $.extend(true, [], Store.luckysheetfile);
|
|
let historyRules = conditionformat.getHistoryRules(fileH);
|
|
|
|
//保存当前的规则
|
|
let ruleArr = file["luckysheet_conditionformat_save"] || [];
|
|
ruleArr.push(rule);
|
|
file["luckysheet_conditionformat_save"] = ruleArr;
|
|
|
|
let fileC = $.extend(true, [], Store.luckysheetfile);
|
|
let currentRules = conditionformat.getCurrentRules(fileC);
|
|
|
|
//刷新一次表格
|
|
conditionformat.ref(historyRules, currentRules);
|
|
|
|
//发送给后台
|
|
if(server.allowUpdate){
|
|
server.saveParam("all", file.index, ruleArr, { "k": "luckysheet_conditionformat_save" });
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
let orders = {};
|
|
|
|
Store.luckysheetfile.forEach((item, i, arr) => {
|
|
arr[i].order = i;
|
|
orders[item.index.toString()] = 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));
|
|
server.saveParam("shr", null, orders);
|
|
|
|
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);
|
|
|
|
if (success && typeof success === 'function') {
|
|
success();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 指定工作表向左边或右边移动一个位置,或者指定索引,返回指定的工作表对象
|
|
* @param {String | Number} type 工作表移动方向或者移动的目标索引
|
|
* @param {Object} options 可选参数
|
|
* @param {Number} options.order 工作表索引;默认值为当前工作表索引
|
|
* @param {Function} options.success 操作结束的回调函数
|
|
*/
|
|
export function setSheetMove(type, options = {}) {
|
|
if(type != 'left' && type != 'right' && !isRealNum(type)){
|
|
return tooltip.info("Type parameter not available", "");
|
|
}
|
|
|
|
if(isRealNum(type)){
|
|
type = parseInt(type);
|
|
}
|
|
|
|
let curOrder = getSheetIndex(Store.currentSheetIndex);
|
|
let {
|
|
order = curOrder,
|
|
success
|
|
} = {...options}
|
|
|
|
let file = Store.luckysheetfile[order];
|
|
|
|
if(file == null){
|
|
return tooltip.info("ncorrect worksheet index", "");
|
|
}
|
|
|
|
let sheetIndex = file.index;
|
|
|
|
if(type == 'left'){
|
|
if(order == 0){
|
|
return;
|
|
}
|
|
|
|
let prevIndex = Store.luckysheetfile[order - 1].index;
|
|
$("#luckysheet-sheets-item" + sheetIndex).insertBefore($("#luckysheet-sheets-item" + prevIndex));
|
|
|
|
Store.luckysheetfile.splice(order, 1);
|
|
Store.luckysheetfile.splice(order - 1, 0, file);
|
|
}
|
|
else if(type == 'right'){
|
|
if(order == Store.luckysheetfile.length - 1){
|
|
return;
|
|
}
|
|
|
|
let nextIndex = Store.luckysheetfile[order + 1].index;
|
|
$("#luckysheet-sheets-item" + sheetIndex).insertAfter($("#luckysheet-sheets-item" + nextIndex));
|
|
|
|
Store.luckysheetfile.splice(order, 1);
|
|
Store.luckysheetfile.splice(order + 1, 0, file);
|
|
}
|
|
else{
|
|
if(type < 0){
|
|
type = 0;
|
|
}
|
|
|
|
if(type > Store.luckysheetfile.length - 1){
|
|
type = Store.luckysheetfile.length - 1;
|
|
}
|
|
|
|
if(type == order){
|
|
return;
|
|
}
|
|
|
|
if(type < order){
|
|
let prevIndex = Store.luckysheetfile[type].index;
|
|
$("#luckysheet-sheets-item" + sheetIndex).insertBefore($("#luckysheet-sheets-item" + prevIndex));
|
|
}
|
|
else{
|
|
let nextIndex = Store.luckysheetfile[type].index;
|
|
$("#luckysheet-sheets-item" + sheetIndex).insertAfter($("#luckysheet-sheets-item" + nextIndex));
|
|
}
|
|
|
|
Store.luckysheetfile.splice(order, 1);
|
|
Store.luckysheetfile.splice(type, 0, file);
|
|
}
|
|
|
|
let orders = {};
|
|
|
|
Store.luckysheetfile.forEach((item, i, arr) => {
|
|
arr[i].order = i;
|
|
orders[item.index.toString()] = i;
|
|
})
|
|
|
|
server.saveParam("shr", null, orders);
|
|
|
|
if (success && typeof success === 'function') {
|
|
success();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* 根据窗口大小自动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();
|
|
|
|
}
|
|
|