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

687 lines
19 KiB

import { getObjType } from '../utils/util';
import { isRealNum, isRealNull, valueIsError } from './validate';
import { update } from './format';
import formula from './formula';
import dayjs from "dayjs";
const error = {
v: "#VALUE!", //错误的参数或运算符
n: "#NAME?", //公式名称错误
na: "#N/A", //函数或公式中没有可用数值
r: "#REF!", //删除了由其他公式引用的单元格
d: "#DIV/0!", //除数是0或空单元格
nm: "#NUM!", //当公式或函数中某个数字有问题时
nl: "#NULL!", //交叉运算符(空格)使用不正确
sp: "#SPILL!" //数组范围有其它值
}
const func_methods = {
//单元格数据生成一维数组
getCellDataArr: function(rangeObj, nullCellType, isNeglectNullCell){
let dataArr = [];
if(rangeObj.data == null){
if(!isNeglectNullCell){
if(nullCellType === "number"){
dataArr.push(0);
}
else if(nullCellType === "text"){
dataArr.push("");
}
}
}
else{
if(getObjType(rangeObj.data) === "array"){
for(let i = 0; i < rangeObj.data.length; i++){
for(let j = 0; j < rangeObj.data[i].length; j++){
let cell = rangeObj.data[i][j];
let value = cell
if(getObjType(cell) === 'object'){
value = cell.v
}
if(value == null ){
if(!isNeglectNullCell){
if(nullCellType === "number"){
value = 0;
}
else if(nullCellType === "text"){
value = '';
}
dataArr.push(value);
}
}
else{
dataArr.push(value);
}
}
}
}
else{
if(isRealNull(rangeObj.data.v)){
if(!isNeglectNullCell){
if(nullCellType == "number"){
dataArr.push(0);
}
else if(nullCellType == "text"){
dataArr.push("");
}
}
}
else{
dataArr.push(rangeObj.data.v);
}
}
}
return dataArr;
},
//单元格数据生成二维数组
getCellDataDyadicArr: function(rangeObj, nullCellType){
let dataArr = [];
if(rangeObj.data == null){
let rowArr = [];
if(nullCellType == "number"){
rowArr.push(0);
}
else if(nullCellType == "text"){
rowArr.push("");
}
dataArr.push(rowArr);
}
else{
if(getObjType(rangeObj.data) == "array"){
for(let i = 0; i < rangeObj.data.length; i++){
let rowArr = [];
for(let j = 0; j < rangeObj.data[i].length; j++){
let cell = rangeObj.data[i][j];
let value = cell;
if(getObjType(cell) === 'object'){
value = cell.v
}
if(value == null){
if(nullCellType === "number"){
value = 0;
}
else if(nullCellType === "text"){
value = '';
}
}
rowArr.push(value);
}
dataArr.push(rowArr);
}
}
else{
let rowArr = [];
let value = rangeObj.data.v;
if(isRealNull(value)){
if(nullCellType == "number"){
value = 0;
}
else if(nullCellType == "text"){
value = "";
}
}
rowArr.push(value);
dataArr.push(rowArr);
}
}
return dataArr;
},
//数组数据生成一维数组
getDataArr: function(arr, isNeglectNaN){
let dataArr = [];
if(isNeglectNaN == null){
isNeglectNaN = false;
}
if(getObjType(arr[0]) == "array"){
for(let i = 0; i < arr.length; i++){
for(let j = 0; j < arr[i].length; j++){
if(isNeglectNaN && !isRealNum(arr[i][j])){
continue;
}
dataArr.push(arr[i][j]);
}
}
}
else{
for(let i = 0; i < arr.length; i++){
if(isNeglectNaN && !isRealNum(arr[i])){
continue;
}
dataArr.push(arr[i]);
}
}
return dataArr;
},
getDataDyadicArr: function(arr){
let dataArr = [];
if(getObjType(arr[0]) == "array"){
for(let i = 0; i < arr.length; i++){
let rowArr = [];
for(let j = 0; j < arr[i].length; j++){
rowArr.push(arr[i][j]);
}
dataArr.push(rowArr);
}
}
else{
let rowArr = [];
for(let i = 0; i < arr.length; i++){
rowArr.push(arr[i]);
}
dataArr.push(rowArr);
}
return dataArr;
},
//是否是规则二维数组
isDyadicArr: function(arr){
let isDyadic = true;
if(arr.length > 1){
let collen = arr[0].length;
for(let i = 1; i < arr.length; i++){
if(arr[i].length != collen){
isDyadic = false;
break;
}
}
}
return isDyadic;
},
//获取单个单元格数据,数组第一个值
getFirstValue: function(data, nullCellType){
let _this = this;
if(nullCellType == null){
nullCellType = "number";
}
let value;
if(getObjType(data) == "array"){
if(getObjType(data[0]) == "array"){
if(!_this.isDyadicArr(data)){
return error.v;
}
value = data[0][0];
}
else{
value = data[0];
}
}
else if(getObjType(data) == "object" && data.startCell != null){
if(data.data == null){
if(nullCellType == "number"){
value = 0;
}
else if(nullCellType == "text"){
value = "";
}
}
else{
let cell_r = window.luckysheetCurrentRow;
let cell_c = window.luckysheetCurrentColumn;
if(data.rowl == 1 && data.coll == 1){
value = data.data;
if(value == null || isRealNull(value.v)){
if(nullCellType == "number"){
value = 0;
}
else if(nullCellType == "text"){
value = "";
}
}
else{
value = value.v;
}
}
else{
if(data.data[0][0].mc != null && data.data[0][0].mc.rs == data.rowl && data.data[0][0].mc.cs == data.coll){
value = data.data[0][0];
if(value == null || isRealNull(value.v)){
if(nullCellType == "number"){
value = 0;
}
else if(nullCellType == "text"){
value = "";
}
}
else{
value = value.v;
}
}
else if(data.rowl == 1 || data.coll == 1){
let cellrange = formula.getcellrange(data.startCell);
let str = cellrange.row[0],
edr = str + data.rowl - 1,
stc = cellrange.column[0],
edc = stc + data.coll - 1;
if(data.rowl == 1){
if(cell_c < stc || cell_c > edc){
return error.v;
}
value = data.data[0][cell_c - stc];
}
else if(data.coll == 1){
if(cell_r < str || cell_r > edr){
return error.v;
}
value = data.data[cell_r - str][0];
}
if(value == null || isRealNull(value.v) || value.mc != null){
if(nullCellType == "number"){
value = 0;
}
else if(nullCellType == "text"){
value = "";
}
}
else{
value = value.v;
}
}
else{
return error.v;
}
}
}
}
else{
value = data;
}
return value;
},
//获取单元格的逻辑值
getCellBoolen: function(data){
let _this = this;
let cumulative = _this.getFirstValue(data);
if(valueIsError(cumulative)){
return cumulative;
}
if(getObjType(cumulative) == "boolean"){
}
else if(getObjType(cumulative) == "string" && (cumulative.toLowerCase() == "true" || cumulative.toLowerCase() == "false")){
if(cumulative.toLowerCase() == "true"){
cumulative = true;
}
else if(cumulative.toLowerCase() == "false"){
cumulative = false;
}
}
else if(isRealNum(cumulative)){
cumulative = parseFloat(cumulative);
cumulative = cumulative == 0 ? false : true;
}
else{
return error.v;
}
return cumulative;
},
//获取单元格的日期
getCellDate: function(data){
let _this = this;
let date_text;
if(getObjType(data) == "array"){
if(getObjType(data[0]) == "array"){
if(!_this.isDyadicArr(data)){
return error.v;
}
date_text = data[0][0];
}
else{
date_text = data[0];
}
}
else if(getObjType(data) == "object" && data.startCell != null){
if(data.data == null || getObjType(data.data) == "array" || isRealNull(data.data.v)){
return error.v;
}
date_text = data.data.v;
if(data.data.ct != null && data.data.ct.t == "d"){
date_text = update("YYYY-MM-DD h:mm:ss", date_text);
}
}
else{
date_text = data;
}
return date_text;
},
getCellrangeDate: function(data){
let _this = this;
let date = [];
if(getObjType(data) == "array"){
if(getObjType(data[0]) == "array" && !_this.isDyadicArr(data)){
return error.v;
}
date = date.concat(_this.getDataArr(data, false));
}
else if(getObjType(data) == "object" && data.startCell != null){
if(data.data == null){
date.push(0);
}
else{
if(getObjType(data.data) == "array"){
for(let i = 0; i < data.data.length; i++){
for(let j = 0; j < data.data[i].length; j++){
if(data.data[i][j] != null && !isRealNull(data.data[i][j].v)){
let value = data.data[i][j].v;
if(data.data[i][j].ct != null && data.data[i][j].ct.t == "d"){
value = update("YYYY-MM-DD h:mm:ss", value);
}
date.push(value);
}
else{
date.push(0);
}
}
}
}
else{
let value = data.data.v;
if(data.data.ct != null && data.data.ct.t == "d"){
value = update("YYYY-MM-DD h:mm:ss", value);
}
date.push(value);
}
}
}
else{
date.push(data);
}
return date;
},
//获取正则字符串(处理 . * ? ~* ~?)
getRegExpStr: function(str){
return str.replace("~*", "\\*").replace("~?", "\\?").replace(".", "\\.").replace("*", ".*").replace("?", ".");
},
//阶乘
factorial: function(num){
if (num == 0 || num == 1) {
return 1;
}
else {
return (num * this.factorial(num - 1));
}
},
//双阶乘
factorialDouble: function(num){
if (num <= 0) {
return 1;
}
else {
return (num * this.factorialDouble(num - 2));
}
},
//总体方差
variance: function(num_arr){
let sum = 0, count = 0;
for(let i = 0; i < num_arr.length; i++){
let number = num_arr[i];
sum += number;
count++;
}
let avg = sum / count;
let sum_variance = 0;
for(let j = 0; j < num_arr.length; j++){
let number = num_arr[j];
sum_variance += (number - avg) * (number - avg);
}
return sum_variance / count;
},
//样本方差
variance_s: function(num_arr){
let sum = 0, count = 0;
for(let i = 0; i < num_arr.length; i++){
let number = num_arr[i];
sum += number;
count++;
}
let avg = sum / count;
let sum_variance = 0;
for(let j = 0; j < num_arr.length; j++){
let number = num_arr[j];
sum_variance += (number - avg) * (number - avg);
}
return sum_variance / (count - 1);
},
//总体标准偏差
standardDeviation: function(num_arr){
let sum = 0, count = 0;
for(let i = 0; i < num_arr.length; i++){
let number = num_arr[i];
sum += number;
count++;
}
let avg = sum / count;
let sum_variance = 0;
for(let j = 0; j < num_arr.length; j++){
let number = num_arr[j];
sum_variance += (number - avg) * (number - avg);
}
return Math.sqrt(sum_variance / count);
},
//样本标准偏差
standardDeviation_s: function(num_arr){
let sum = 0, count = 0;
for(let i = 0; i < num_arr.length; i++){
let number = num_arr[i];
sum += number;
count++;
}
let avg = sum / count;
let sum_variance = 0;
for(let j = 0; j < num_arr.length; j++){
let number = num_arr[j];
sum_variance += (number - avg) * (number - avg);
}
return Math.sqrt(sum_variance / (count - 1));
},
//是否是闰年
isLeapYear: function(year){
return new Date(year, 1, 29).getMonth() === 1;
},
//2月是否有29
feb29Between: function(date1, date2){
let _this = this;
let year1 = dayjs(date1).year();
let mar1year1 = dayjs().set({ 'year': year1, 'month': 2, 'date': 1 });
if (_this.isLeapYear(year1) && dayjs(date1) < dayjs(mar1year1) && dayjs(date2) >= dayjs(mar1year1)) {
return true;
}
let year2 = dayjs(date2).year();
let mar1year2 = dayjs().set({ 'year': year2, 'month': 2, 'date': 1 });
return (_this.isLeapYear(year2) && dayjs(date2) >= dayjs(mar1year2) && dayjs(date1) < dayjs(mar1year2));
},
//SQL 查询
findResultIndex: function(database, criterias){
let matches = {};
for (let i = 1; i < database[0].length; ++i) {
matches[i] = true;
}
let maxCriteriaLength = criterias[0].length;
for (i = 1; i < criterias.length; ++i) {
if (criterias[i].length > maxCriteriaLength) {
maxCriteriaLength = criterias[i].length;
}
}
for (let k = 1; k < database.length; ++k) {
for (let l = 1; l < database[k].length; ++l) {
let currentCriteriaResult = false;
let hasMatchingCriteria = false;
for (let j = 0; j < criterias.length; ++j) {
let criteria = criterias[j];
if (criteria.length < maxCriteriaLength) {
continue;
}
let criteriaField = criteria[0];
if (database[k][0] !== criteriaField) {
continue;
}
hasMatchingCriteria = true;
for (let p = 1; p < criteria.length; ++p) {
currentCriteriaResult = currentCriteriaResult || (new Function("return " + database[k][l] + criteria[p])()); // jshint ignore:line
}
}
if (hasMatchingCriteria) {
matches[l] = matches[l] && currentCriteriaResult;
}
}
}
let result = [];
for (let n = 0; n < database[0].length; ++n) {
if (matches[n]) {
result.push(n - 1);
}
}
return result;
},
findField: function(database, title){
let index = null;
for (let i = 0; i < database.length; i++) {
if (database[i][0] == title) {
index = i;
break;
}
}
if (index == null) {
return error.v;
}
return index;
},
rest: function(array, idx){
idx = idx || 1;
if (!array || typeof array.slice !== 'function') {
return array;
}
return array.slice(idx);
},
compact: function(array){
if (!array) {
return array;
}
let result = [];
for (let i = 0; i < array.length; ++i) {
if (!array[i]) {
continue;
}
result.push(array[i]);
}
return result;
}
}
export default func_methods;