/** * 计算多个数值的和 * * @param val 数值型参数,可变长参数列表 * @returns 返回所有参数的和,如果参数列表为空或参数类型非数值型,则返回null */ function SUM(...val){ try { let num = null; if(val&&val.length>0){ val.forEach(item=>{ num+=item; }) } return num; } catch (error) { } } /** * 计算传入参数中的最大值 * * @param ...val 可变参数列表,用于计算最大值的数值或可转换为数值的类型 * @returns 返回最大值,如果参数列表为空或为null/undefined/'',则返回null */ function MAX(...val){ try { let max = null; if(val&&val.length>0){ val = val.filter(item=>item!=null&&item!=='') if(val.length>0){ max = Math.max(...val) }else{ max = null; } } return max; } catch (error) { } } /** * 计算传入参数中的最小值 * * @param val 可变参数,用于计算最小值的数值数组 * @returns 返回传入参数中的最小值,如果传入参数为空或所有值均为null或空字符串,则返回null */ function MIN(...val){ try { let min = null; if(val&&val.length>0){ val = val.filter(item=>item!=null&&item!=='') // console.log(val) if(val.length>0){ min = Math.min(...val) } } return min; } catch (error) { } } /** * 计算给定数值的平均值 * * @param val 数值列表,可包含任意个参数 * @returns 返回平均值,如果数值列表为空或包含非数值项,则返回null */ function AVERAGE(...val){ try { let num = null; let arr = []; if(val&&val.length>0){ arr = val.filter(item=>item!=null&&item!=='') arr.forEach(item=>{ num+=item; }) if(arr.length>0){ return num/arr.length; }else{ return null; } }else{ return null; } } catch (error) { } } /** * 计算一个数的绝对值 * * @param val 任意数值 * @returns 返回该数值的绝对值 */ function ABS(val){ try { return Math.abs(val); } catch (error) { } } /** * 计算一组数字的中位数 * * @param val 任意个参数,需要计算中位数的数字 * @returns 如果参数中有有效的数字,则返回计算出的中位数;否则返回null */ function MEDIAN(...val){ try { let arr = []; if(val&&val.length>0){ arr = val.filter(item=>item!=null&&item!=='') const sortedArr = arr.sort((a, b) => a - b); // 计算中位数 const half = Math.floor(sortedArr.length / 2); if(arr.length>0){ // 如果数组长度是奇数,直接取中间的元素 if (sortedArr.length % 2 === 1) { return sortedArr[half]; } else { // 如果数组长度是偶数,取中间两个元素的平均值 return (sortedArr[half - 1] + sortedArr[half]) / 2; } }else{ return null; } }else{ return null; } } catch (error) { } } /** * 计算幂 * * @param str 字符串形式的幂表达式,例如"2^3" * @returns 返回计算后的幂值,如果表达式无效则返回null */ function CalculatePower(str){ try { if(str&&str.includes('^')){ let arr = str.split('^'); if(arr&&arr.length>1){ return Math.pow(arr[0],arr[1]); }else{ return null; } } } catch (error) { } } /** * 根据坐标获取列名 * @param {Object} cellId */ function getColumnNameFromId(cellId){ try{ if (! Array.isArray(cellId)) { cellId = cellId.split('-'); } var i = cellId[0]; var letter = ''; if (i > 701) { letter += String.fromCharCode(64 + parseInt(i / 676)); letter += String.fromCharCode(64 + parseInt((i % 676) / 26)); } else if (i > 25) { letter += String.fromCharCode(64 + parseInt(i / 26)); } letter += String.fromCharCode(65 + (i % 26)); return letter + (parseInt(cellId[1]) + 1); }catch(e){ console.log('error',cellId) } } /** * 根据列名获取坐标 * @param {Object} id * @param {Object} arr */ function getIdFromColumnName(id, arr) { try{ // Get the letters var t = /^[a-zA-Z]+/.exec(id); if (t) { // Base 26 calculation var code = 0; for (var i = 0; i < t[0].length; i++) { code += parseInt(t[0].charCodeAt(i) - 64) * Math.pow(26, (t[0].length - 1 - i)); } code--; // Make sure jexcel starts on zero if (code < 0) { code = 0; } // Number var number = parseInt(/[0-9]+$/.exec(id)); if (number > 0) { number--; } if (arr == true) { id = [ code, number ]; } else { // id = code + '-' + number; id = { c:code, r:number } } } return id; }catch(e){ console.log('error',id) } } /** * 更改参数 * * @param f 参数列表 * @returns 返回一个包含坐标信息的数组 */ function changeParameter(f){ try { let arr = getABCList(f) let arr2 = [] arr.forEach(item=>{ if(item.includes(':')){ let r0 = getIdFromColumnName(item.split(':')[0]).r; let c0 = getIdFromColumnName(item.split(':')[0]).c; let r1 = getIdFromColumnName(item.split(':')[1]).r; let c1 = getIdFromColumnName(item.split(':')[1]).c; for (let i = Number(r0); i <= Number(r1); i++) { for (let u = Number(c0); u <= Number(c1); u++) { arr2.push({ r: i, c: u }) } } }else{ arr2.push(getIdFromColumnName(item)) } }) return arr2; } catch (error) { } } /** * 获取包含 ABC 字符的列表 * * @param f 字符串,包含需要解析的公式或表达式 * @returns 包含 ABC 字符的数组列表 */ function getABCList(f){ try { let regex = /[=\+\-\*\%\(\)\/\^\s]/g; let fouList = [ "SUM", 'MAX', 'MIN', 'AVERAGE', 'ABS', ] f = f.replace(regex, ',').replace(new RegExp('"&', 'g'),'').replace(new RegExp('&"', 'g'),'') fouList.forEach(item=>{ f = f.replace(new RegExp(item, 'g'),'') }) // console.log('f',f) let arr = f.split(',').filter(item=>{ return item&& /[a-zA-Z]/.test(item)&&item!='undefined'&&item!='null' }); return arr; } catch (error) { } } /** * 获取所有单元格 * * @param f 表格数据或相关参数 * @returns 返回一个对象,其键为单元格的唯一标识符(由列和行ID拼接而成),值为null */ function getAllCell(f){ try { let arr = changeParameter(f) let arr0 = {} arr.forEach(item=>{ arr0[getColumnNameFromId(`${item.c}`+'-'+`${item.r}`)] = null }) return arr0; } catch (error) { } } /** * 计算函数 * * @param f 字符串类型,表示待计算的公式 * @param comValue 对象类型,表示要替换的单元格值,键为单元格名称,值为替换后的值 * @returns 返回计算后的结果,如果计算失败则返回0 */ function compute(f,comValue){ try { let str = f // 获取单元格对应值 let arr = getAllCell(f) for (var a in comValue) { if(comValue[a]!=='undefined'&&comValue[a]!=='null'&&comValue[a]!==undefined){ if(typeof(comValue[a])=='string'&&comValue[a].includes('^')){ // 计算幂次 arr[a] = CalculatePower(comValue[a]) } else if (typeof(comValue[a])=='string'&&comValue[a].includes('/')) { arr[a] = comValue[a] } else{ arr[a] = comValue[a] } } } // 解析公式参数,特别是带:的 let arr0 = getABCList(f) let obj = {} arr0.forEach(item=>{ if(item.includes(':')){ let arr1 = [] let r0 = getIdFromColumnName(item.split(':')[0]).r; let c0 = getIdFromColumnName(item.split(':')[0]).c; let r1 = getIdFromColumnName(item.split(':')[1]).r; let c1 = getIdFromColumnName(item.split(':')[1]).c; for (let i = Number(r0); i <= Number(r1); i++) { for (let u = Number(c0); u <= Number(c1); u++) { arr1.push({ r: i, c: u }) } } let arr2 = [] arr1.forEach(m=>{ arr2.push(getColumnNameFromId(`${m.c}`+'-'+`${m.r}`)) }) obj[item.split(':').join('-')] = arr2.join(',') }else{ obj[item] = item } }) str = str.replace(new RegExp(':', 'g'),'') // 替换参数 for (var a in obj) { str = str.replace(new RegExp(a, 'g'),obj[a]) } // 计算 for (var a in arr) { str = str.replace(new RegExp(a, 'g'),arr[a]) } return eval(str) } catch (error) { } } export default { compute, changeParameter }