import { columeHeader_word, columeHeader_word_index, luckysheetdefaultFont } from '../controllers/constant'; import menuButton from '../controllers/menuButton'; import { isdatatype, isdatatypemulti } from '../global/datecontroll'; import { hasChinaword,isRealNum } from '../global/validate'; import Store from '../store'; import locale from '../locale/locale'; import numeral from 'numeral'; // import method from '../global/method'; /** * Common tool methods */ /** * Determine whether a string is in standard JSON format * @param {String} str */ function isJsonString(str) { try { if (typeof JSON.parse(str) == "object") { return true; } } catch (e) { } return false; } /** * extend two objects * @param {Object } jsonbject1 * @param {Object } jsonbject2 */ function common_extend(jsonbject1, jsonbject2) { let resultJsonObject = {}; for (let attr in jsonbject1) { resultJsonObject[attr] = jsonbject1[attr]; } for (let attr in jsonbject2) { // undefined is equivalent to no setting if(jsonbject2[attr] == undefined){ continue; } resultJsonObject[attr] = jsonbject2[attr]; } return resultJsonObject; }; // 替换temp中的${xxx}为指定内容 ,temp:字符串,这里指html代码,dataarry:一个对象{"xxx":"替换的内容"} // 例:luckysheet.replaceHtml("${image}",{"image":"abc","jskdjslf":"abc"}) ==> abc function replaceHtml(temp, dataarry) { return temp.replace(/\$\{([\w]+)\}/g, function (s1, s2) { let s = dataarry[s2]; if (typeof (s) != "undefined") { return s; } else { return s1; } }); }; //获取数据类型 function getObjType(obj) { let toString = Object.prototype.toString; let map = { '[object Boolean]': 'boolean', '[object Number]': 'number', '[object String]': 'string', '[object Function]': 'function', '[object Array]': 'array', '[object Date]': 'date', '[object RegExp]': 'regExp', '[object Undefined]': 'undefined', '[object Null]': 'null', '[object Object]': 'object' } // if(obj instanceof Element){ // return 'element'; // } return map[toString.call(obj)]; } //获取当前日期时间 function getNowDateTime(format) { let now = new Date(); let year = now.getFullYear(); //得到年份 let month = now.getMonth(); //得到月份 let date = now.getDate(); //得到日期 let day = now.getDay(); //得到周几 let hour = now.getHours(); //得到小时 let minu = now.getMinutes(); //得到分钟 let sec = now.getSeconds(); //得到秒 month = month + 1; if (month < 10) month = "0" + month; if (date < 10) date = "0" + date; if (hour < 10) hour = "0" + hour; if (minu < 10) minu = "0" + minu; if (sec < 10) sec = "0" + sec; let time = ''; //日期 if(format == 1) { time = year + "-" + month + "-" + date; } //日期时间 else if(format == 2) { time = year + "-" + month + "-" + date+ " " + hour + ":" + minu + ":" + sec; } return time; } //颜色 16进制转rgb function hexToRgb(hex) { let color = [], rgb = []; hex = hex.replace(/#/, ""); if (hex.length == 3) { // 处理 "#abc" 成 "#aabbcc" let tmp = []; for (let i = 0; i < 3; i++) { tmp.push(hex.charAt(i) + hex.charAt(i)); } hex = tmp.join(""); } for (let i = 0; i < 3; i++) { color[i] = "0x" + hex.substr(i + 2, 2); rgb.push(parseInt(Number(color[i]))); } return 'rgb(' + rgb.join(",") + ')'; }; //颜色 rgb转16进制 function rgbTohex(color) { let rgb; if (color.indexOf("rgba") > -1) { rgb = color.replace("rgba(", "").replace(")", "").split(','); } else { rgb = color.replace("rgb(", "").replace(")", "").split(','); } let r = parseInt(rgb[0]); let g = parseInt(rgb[1]); let b = parseInt(rgb[2]); let hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); return hex; }; //列下标 字母转数字 function ABCatNum(a) { // abc = abc.toUpperCase(); // let abc_len = abc.length; // if (abc_len == 0) { // return NaN; // } // let abc_array = abc.split(""); // let wordlen = columeHeader_word.length; // let ret = 0; // for (let i = abc_len - 1; i >= 0; i--) { // if (i == abc_len - 1) { // ret += columeHeader_word_index[abc_array[i]]; // } // else { // ret += Math.pow(wordlen, abc_len - i - 1) * (columeHeader_word_index[abc_array[i]] + 1); // } // } // return ret; if(a==null || a.length==0){ return NaN; } var str=a.toLowerCase().split(""); var num=0; var al = str.length; var getCharNumber = function(charx){ return charx.charCodeAt() -96; }; var numout = 0; var charnum = 0; for(var i = 0; i < al; i++){ charnum = getCharNumber(str[i]); numout += charnum * Math.pow(26, al-i-1); }; // console.log(a, numout-1); if(numout==0){ return NaN; } return numout-1; }; //列下标 数字转字母 function chatatABC(n) { // let wordlen = columeHeader_word.length; // if (index < wordlen) { // return columeHeader_word[index]; // } // else { // let last = 0, pre = 0, ret = ""; // let i = 1, n = 0; // while (index >= (wordlen / (wordlen - 1)) * (Math.pow(wordlen, i++) - 1)) { // n = i; // } // let index_ab = index - (wordlen / (wordlen - 1)) * (Math.pow(wordlen, n - 1) - 1);//970 // last = index_ab + 1; // for (let x = n; x > 0; x--) { // let last1 = last, x1 = x;//-702=268, 3 // if (x == 1) { // last1 = last1 % wordlen; // if (last1 == 0) { // last1 = 26; // } // return ret + columeHeader_word[last1 - 1]; // } // last1 = Math.ceil(last1 / Math.pow(wordlen, x - 1)); // //last1 = last1 % wordlen; // ret += columeHeader_word[last1 - 1]; // if (x > 1) { // last = last - (last1 - 1) * wordlen; // } // } // } var orda = 'a'.charCodeAt(0); var ordz = 'z'.charCodeAt(0); var len = ordz - orda + 1; var s = ""; while( n >= 0 ) { s = String.fromCharCode(n % len + orda) + s; n = Math.floor(n / len) - 1; } return s.toUpperCase(); }; function ceateABC(index) { let wordlen = columeHeader_word.length; if (index < wordlen) { return columeHeader_word; } else { let relist = []; let i = 2, n = 0; while (index < (wordlen / (wordlen - 1)) * (Math.pow(wordlen, i) - 1)) { n = i; i++; } for (let x = 0; x < n; x++) { if (x == 0) { relist = relist.concat(columeHeader_word); } else { relist = relist.concat(createABCdim(x), index); } } } }; function createABCdim(x, count) { let chwl = columeHeader_word.length; if (x == 1) { let ret = []; let c = 0, con = true; for (let i = 0; i < chwl; i++) { let b = columeHeader_word[i]; for (let n = 0; n < chwl; n++) { let bq = b + columeHeader_word[n]; ret.push(bq); c++; if (c > index) { return ret; } } } } else if (x == 2) { let ret = []; let c = 0, con = true; for (let i = 0; i < chwl; i++) { let bb = columeHeader_word[i]; for (let w = 0; w < chwl; w++) { let aa = columeHeader_word[w]; for (let n = 0; n < chwl; n++) { let bqa = bb + aa + columeHeader_word[n]; ret.push(bqa); c++; if (c > index) { return ret; } } } } } }; /** * 计算字符串字节长度 * @param {*} val 字符串 * @param {*} subLen 要截取的字符串长度 */ function getByteLen(val,subLen) { if(subLen === 0){ return ""; } if (val == null) { return 0; } let len = 0; for (let i = 0; i < val.length; i++) { let a = val.charAt(i); if (a.match(/[^\x00-\xff]/ig) != null) { len += 2; } else { len += 1; } if(isRealNum(subLen) && len === ~~subLen){ return val.substring(0,i) } } return len; }; //数组去重 function ArrayUnique(dataArr) { let result = []; let obj = {}; if (dataArr.length > 0) { for (let i = 0; i < dataArr.length; i++) { let item = dataArr[i]; if (!obj[item]) { result.push(item); obj[item] = 1; } } } return result } //获取字体配置 function luckysheetfontformat(format) { let fontarray = locale().fontarray; if (getObjType(format) == "object") { let font = ""; //font-style if (format.it == "0" || format.it == null) { font += "normal "; } else { font += "italic "; } //font-variant font += "normal "; //font-weight if (format.bl == "0" || format.bl == null) { font += "normal "; } else { font += "bold "; } //font-size/line-height if (!format.fs) { font += Store.defaultFontSize + "pt "; } else { font += Math.ceil(format.fs) + "pt "; } if (!format.ff) { font += fontarray[0] + ', "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif'; } else { let fontfamily = null; let fontjson = locale().fontjson; if (isdatatypemulti(format.ff)["num"]) { fontfamily = fontarray[parseInt(format.ff)]; } else { // fontfamily = fontarray[fontjson[format.ff]]; fontfamily = format.ff; fontfamily = fontfamily.replace(/"/g, "").replace(/'/g, ""); if(fontfamily.indexOf(" ")>-1){ fontfamily = '"' + fontfamily + '"'; } if(fontfamily!=null && document.fonts && !document.fonts.check("12px "+fontfamily)){ menuButton.addFontTolist(fontfamily); } } if (fontfamily == null) { fontfamily = fontarray[0]; } font += fontfamily + ', "Helvetica Neue", Helvetica, Arial, "PingFang SC", "Hiragino Sans GB", "Heiti SC", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif'; } return font; } else { return luckysheetdefaultFont(); } } //右键菜单 function showrightclickmenu($menu, x, y) { let winH = $(window).height(), winW = $(window).width(); let menuW = $menu.width(), menuH = $menu.height(); let top = y, left = x; if (x + menuW > winW) { left = x - menuW; } if (y + menuH > winH) { top = y - menuH; } if (top < 0) { top = 0; } $menu.css({ "top": top, "left": left }).show(); } //单元格编辑聚焦 function luckysheetactiveCell() { if (!!Store.fullscreenmode) { setTimeout(function () { // need preventScroll:true,fix Luckysheet has been set top, and clicking the cell will trigger the scrolling problem const input = document.getElementById('luckysheet-rich-text-editor'); input.focus({preventScroll:true}); $("#luckysheet-rich-text-editor").select(); // $("#luckysheet-rich-text-editor").focus().select(); }, 50); } } //单元格编辑聚焦 function luckysheetContainerFocus() { // $("#" + Store.container).focus({ // preventScroll: true // }); // fix jquery error: Uncaught TypeError: ((n.event.special[g.origType] || {}).handle || g.handler).apply is not a function // $("#" + Store.container).attr("tabindex", 0).focus(); // need preventScroll:true,fix Luckysheet has been set top, and clicking the cell will trigger the scrolling problem document.getElementById(Store.container).focus({preventScroll:true}); } //数字格式 function numFormat(num, type) { if (num == null || isNaN(parseFloat(num)) || hasChinaword(num) || num == -Infinity || num == Infinity) { return null; } let floatlen = 6, ismustfloat = false; if (type == null || type == "auto") { if (num < 1) { floatlen = 6; } else { floatlen = 1; } } else { if (isdatatype(type) == "num") { floatlen = parseInt(type); ismustfloat = true; } else { floatlen = 6; } } let format = "", value = null; for (let i = 0; i < floatlen; i++) { format += "0"; } if (!ismustfloat) { format = "[" + format + "]"; } if (num >= 1e+21) { value = parseFloat(numeral(num).value()); } else { value = parseFloat(numeral(num).format("0." + format)); } return value; } function numfloatlen(n) { if (n != null && !isNaN(parseFloat(n)) && !hasChinaword(n)) { let value = numeral(n).value(); let lens = value.toString().split("."); if (lens.length == 1) { lens = 0; } else { lens = lens[1].length; } return lens; } else { return null; } } //二级菜单显示位置 function mouseclickposition($menu, x, y, p) { let winH = $(window).height(), winW = $(window).width(); let menuW = $menu.width(), menuH = $menu.height(); let top = y, left = x; if (p == null) { p = "lefttop"; } if (p == "lefttop") { $menu.css({ "top": y, "left": x }).show(); } else if (p == "righttop") { $menu.css({ "top": y, "left": x - menuW }).show(); } else if (p == "leftbottom") { $menu.css({ "bottom": winH - y - 12, "left": x }).show(); } else if (p == "rightbottom") { $menu.css({ "bottom": winH - y - 12, "left": x - menuW }).show(); } } /** * 元素选择器 * @param {String} selector css选择器 * @param {String} context 指定父级DOM */ function $$(selector, context) { context = context || document var elements = context.querySelectorAll(selector) return elements.length == 1 ? Array.prototype.slice.call(elements)[0] : Array.prototype.slice.call(elements) } /** * 串行加载指定的脚本 * 串行加载[异步]逐个加载,每个加载完成后加载下一个 * 全部加载完成后执行回调 * @param {Array|String} scripts 指定要加载的脚本 * @param {Object} options 属性设置 * @param {Function} callback 成功后回调的函数 * @return {Array} 所有生成的脚本元素对象数组 */ function seriesLoadScripts(scripts, options, callback) { if (typeof (scripts) !== 'object') { var scripts = [scripts]; } var HEAD = document.getElementsByTagName('head')[0] || document.documentElement; var s = []; var last = scripts.length - 1; //递归 var recursiveLoad = function (i) { s[i] = document.createElement('script'); s[i].setAttribute('type', 'text/javascript'); // Attach handlers for all browsers // 异步 s[i].onload = s[i].onreadystatechange = function () { if (!/*@cc_on!@*/0 || this.readyState === 'loaded' || this.readyState === 'complete') { this.onload = this.onreadystatechange = null; this.parentNode.removeChild(this); if (i !== last) { recursiveLoad(i + 1); } else if (typeof (callback) === 'function') { callback() }; } } // 同步 s[i].setAttribute('src', scripts[i]); // 设置属性 if (typeof options === 'object') { for (var attr in options) { s[i].setAttribute(attr, options[attr]); } } HEAD.appendChild(s[i]); }; recursiveLoad(0); } /** * 并行加载指定的脚本 * 并行加载[同步]同时加载,不管上个是否加载完成,直接加载全部 * 全部加载完成后执行回调 * @param {Array|String} scripts 指定要加载的脚本 * @param {Object} options 属性设置 * @param {Function} callback 成功后回调的函数 * @return {Array} 所有生成的脚本元素对象数组 */ function parallelLoadScripts(scripts, options, callback) { if (typeof (scripts) !== 'object') { var scripts = [scripts]; } var HEAD = document.getElementsByTagName('head')[0] || document.documentElement; var s = []; var loaded = 0; for (var i = 0; i < scripts.length; i++) { s[i] = document.createElement('script'); s[i].setAttribute('type', 'text/javascript'); // Attach handlers for all browsers // 异步 s[i].onload = s[i].onreadystatechange = function () { if (!/*@cc_on!@*/0 || this.readyState === 'loaded' || this.readyState === 'complete') { loaded++; this.onload = this.onreadystatechange = null; this.parentNode.removeChild(this); if (loaded === scripts.length && typeof (callback) === 'function') callback(); } }; // 同步 s[i].setAttribute('src', scripts[i]); // 设置属性 if (typeof options === 'object') { for (var attr in options) { s[i].setAttribute(attr, options[attr]); } } HEAD.appendChild(s[i]); } } /** * 动态添加css * @param {String} url 指定要加载的css地址 */ function loadLink(url) { var doc = document; var link = doc.createElement("link"); link.setAttribute("rel", "stylesheet"); link.setAttribute("type", "text/css"); link.setAttribute("href", url); var heads = doc.getElementsByTagName("head"); if (heads.length) { heads[0].appendChild(link); } else { doc.documentElement.appendChild(link); } } /** * 动态添加一组css * @param {String} url 指定要加载的css地址 */ function loadLinks(urls) { if (typeof (urls) !== 'object') { urls = [urls]; } if (urls.length) { urls.forEach(url => { loadLink(url); }); } } function transformRangeToAbsolute(txt1){ if(txt1 ==null ||txt1.length==0){ return null; } let txtArray = txt1.split(","); let ret = ""; for(let i=0;i<txtArray.length;i++){ let txt = txtArray[i]; let txtSplit = txt.split("!"), sheetName="", rangeTxt=""; if(txtSplit.length>1){ sheetName = txtSplit[0]; rangeTxt = txtSplit[1]; } else{ rangeTxt = txtSplit[0]; } let rangeTxtArray = rangeTxt.split(":"); let rangeRet = ""; for(let a=0;a<rangeTxtArray.length;a++){ let t = rangeTxtArray[a]; let row = t.replace(/[^0-9]/g, ""); let col = t.replace(/[^A-Za-z]/g, ""); let rangeTT = "" if(col!=""){ rangeTT += "$" + col; } if(row!=""){ rangeTT += "$" + row; } rangeRet+=rangeTT+":"; } rangeRet = rangeRet.substr(0, rangeRet.length-1); ret += sheetName + rangeRet + ","; } return ret.substr(0, ret.length-1); } function openSelfModel(id, isshowMask=true){ let $t = $("#"+id) .find(".luckysheet-modal-dialog-content") .css("min-width", 300) .end(), myh = $t.outerHeight(), myw = $t.outerWidth(); let winw = $(window).width(), winh = $(window).height(); let scrollLeft = $(document).scrollLeft(), scrollTop = $(document).scrollTop(); $t.css({ "left": (winw + scrollLeft - myw) / 2, "top": (winh + scrollTop - myh) / 3 }).show(); if(isshowMask){ $("#luckysheet-modal-dialog-mask").show(); } } /** * 监控对象变更 * @param {*} data */ // const createProxy = (data,list=[]) => { // if (typeof data === 'object' && data.toString() === '[object Object]') { // for (let k in data) { // if(list.includes(k)){ // if (typeof data[k] === 'object') { // defineObjectReactive(data, k, data[k]) // } else { // defineBasicReactive(data, k, data[k]) // } // } // } // } // } const createProxy = (data, k, callback) => { if(!data.hasOwnProperty(k)){ console.info('No %s in data',k); return; }; if (getObjType(data) === 'object') { if (getObjType(data[k]) === 'object' || getObjType(data[k]) === 'array') { defineObjectReactive(data, k, data[k], callback) } else { defineBasicReactive(data, k, data[k], callback) } } } function defineObjectReactive(obj, key, value, callback) { // 递归 obj[key] = new Proxy(value, { set(target, property, val, receiver) { setTimeout(() => { callback(target, property, val, receiver); }, 0); return Reflect.set(target, property, val, receiver) } }) } function defineBasicReactive(obj, key, value, callback) { Object.defineProperty(obj, key, { enumerable: true, configurable: false, get() { return value }, set(newValue) { if (value === newValue) return console.log(`发现 ${key} 属性 ${value} -> ${newValue}`) setTimeout(() => { callback(value,newValue); }, 0); value = newValue } }) } /** * Remove an item in the specified array * @param {array} array Target array * @param {string} item What needs to be removed */ function arrayRemoveItem(array, item) { array.some((curr, index, arr)=>{ if(curr === item){ arr.splice(index, 1); return curr === item; } }) } /** * camel 形式的单词转换为 - 形式 如 fillColor -> fill-color * @param {string} camel camel 形式 * @returns */ function camel2split(camel) { return camel.replace(/([A-Z])/g, function(all, group) { return '-' + group.toLowerCase(); }); } export { isJsonString, common_extend, replaceHtml, getObjType, getNowDateTime, hexToRgb, rgbTohex, ABCatNum, chatatABC, ceateABC, createABCdim, getByteLen, ArrayUnique, luckysheetfontformat, showrightclickmenu, luckysheetactiveCell, numFormat, numfloatlen, mouseclickposition, $$, seriesLoadScripts, parallelLoadScripts, loadLinks, luckysheetContainerFocus, transformRangeToAbsolute, openSelfModel, createProxy, arrayRemoveItem, camel2split }