項目需求需要將用戶上傳的excel解析成前端可以使用的樹數據並且繪制表格到頁面上,這里我將用戶上傳的excel使用xlsx解析后,拿到json數據對他進行解析生成樹,上傳的excel為:
,解析方法如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> </body> </html> <script> let ref = "A1:L3"//xlsx解析后獲取到的單元格所占行列數 let marge = [ { "s": { "c": 6, "r": 0 }, "e": { "c": 11, "r": 0 } }, { "s": { "c": 9, "r": 1 }, "e": { "c": 11, "r": 1 } }, { "s": { "c": 7, "r": 1 }, "e": { "c": 8, "r": 1 } }, { "s": { "c": 6, "r": 1 }, "e": { "c": 6, "r": 2 } }, { "s": { "c": 0, "r": 0 }, "e": { "c": 0, "r": 2 } }, { "s": { "c": 1, "r": 0 }, "e": { "c": 1, "r": 2 } }, { "s": { "c": 2, "r": 0 }, "e": { "c": 2, "r": 2 } }, { "s": { "c": 3, "r": 0 }, "e": { "c": 4, "r": 1 } }, { "s": { "c": 5, "r": 0 }, "e": { "c": 5, "r": 1 } } ];//xlsx解析后獲取到的單元格合並數據 let arr = [ { "key_": "A1", "data": "點點滴滴" }, { "key_": "B1", "data": "數量" }, { "key_": "C1", "data": "雙數" }, { "key_": "D1", "data": "單數" }, { "key_": "F1", "data": "單雙數" }, { "key_": "G1", "data": "2019年" }, { "key_": "G2", "data": "計算2018" }, { "key_": "H2", "data": "中央大的" }, { "key_": "J2", "data": "阿達" }, { "key_": "D3", "data": "法法" }, { "key_": "E3", "data": "大師傅" }, { "key_": "F3", "data": "阿發" }, { "key_": "H3", "data": "阿法狗" }, { "key_": "I3", "data": "算法22" }, { "key_": "J3", "data": "阿嘎" }, { "key_": "K3", "data": "阿法阿發" }, { "key_": "L3", "data": "誰改的根" } ];//xlsx解析后獲取到的單元格數據,我將它轉化為了數組格式 let tree = [];//存儲目標樹形結構 let margezh = [];//存儲合並單元格數據 marge.forEach(item => { let t = Number(item.s.r) + 1; margezh.push({ "s": item.s, "e": item.e, "s_": numToString(item.s.c) + "" + t }) }) console.log(margezh, "margezh"); function numToString(number) {//解析單元格合並 let char = ""; let array = []; let numToStringAction = function (nnum) { let num = nnum; let a = parseInt(num / 26); let b = num % 26; array.push(b); if (a > 0) { numToStringAction(a); } } numToStringAction(number); array = array.reverse(); for (let i = 0; i < array.length; i++) { char += String.fromCharCode(64 + parseInt(array[i] + 1)); } return char; } arr.forEach((item, idx) => {//存儲字母數字 let separat = separation(item.key_); item.letter = separat.letter[0]; item.digital = Number(separat.digital[0]); let a = stringTonum(separat.letter[0]); item.letter_digital = a; }) function separation(num) {//拆分字母數字 let letter = num.match(/^[a-z|A-Z]+/gi); let digital = num.match(/\d+$/gi); console.log(letter + "," + digital); return { "letter": letter, "digital": digital } } for (let j = 0; j < arr.length; j++) { if (arr[j].digital == 1) { let t = matchMerger(arr[j].key_); if (t && t.e) { tree.push( { name: arr[j].data, startrow: t.s.r, startcol: t.s.c, endrow: t.e.r, endcol: t.e.c, children: [], flagkey: arr[j].key_, flag_r: t.e.r+1, //自身所在行 flag_c: arr[j].letter_digital//自身所在列 } ) } else { tree.push( { name: arr[j].data, children: [], flagkey: arr[j].key_, flag_r: arr[j].digital, //自身所在行 flag_c: arr[j].letter_digital//自身所在列 } ) } } else { recursive(tree, arr[j].letter_digital, arr[j].digital, arr[j].key_, arr[j].data); } } console.log(tree,"tree"); function stringTonum(a) {//excel字母轉數字 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); }; return numout; } function matchMerger(data) {//獲取所合並行數據 for (let i = 0; i < margezh.length; i++) { if (margezh[i].s_ == data) { return margezh[i]; } } } function recursive(data, xcol, xrow, key, name) {//遞歸樹 let flag = 0; for (let i = 0; i < data.length; i++) { if (data[i].children) { if (data[i].flag_c <= xcol && data[i].flag_r == xrow - 1&&data[i].endcol+1 >= xcol ) { if (flag == 0) { let t = matchMerger(key); if (t && t.s) { data[i].children.push({ name: name, startrow: t.s.r, startcol: t.s.c, endrow: t.e.r, endcol: t.e.c, children: [], flagkey: key, flag_r: t.e.r+1, //自身所在行 flag_c: xcol//自身所在列 }) } else { data[i].children.push({ name: name, children: [], flagkey: key, flag_r: xrow, //自身所在行 flag_c: xcol//自身所在列 }) } } falag = 1; } else { recursive(data[i].children, xcol, xrow, key, name); } } else { } } } console.log(tree)//打印最后生成樹 </script>
最后打印的結果為
其中有的參數或許你們不需要,可以在生成樹后遞歸去掉,別在代碼里去掉,這會出現錯誤。
下面貼出xlsx解析excel需要取得數據
這些就是具體核心方法,如果不知道如何解析excel,請參考前面發的文章,若有問題請留言,大家一起學習,謝謝。