項目需求需要將用戶上傳的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,請參考前面發的文章,若有問題請留言,大家一起學習,謝謝。
