xmind文件如圖所示, 最終生成的數據結構如圖: 2,選擇導出為excel文件,導出的excel文件打開如圖 3,安裝node讀取excel模塊 cnpm i node-xlsx --save 4,使用node-xlsx模塊讀取excel文件,註意文件名不能為中文, 使用示例 var xlsx2j ...
xmind文件如圖所示,
最終生成的數據結構如圖:
2,選擇導出為excel文件,導出的excel文件打開如圖
3,安裝node讀取excel模塊 cnpm i node-xlsx --save
4,使用node-xlsx模塊讀取excel文件,註意文件名不能為中文,
使用示例
var xlsx2json = require("node-xlsx"); var list = xlsx2json.parse("./test3.xlsx"); 讀取出的excel數據如圖
5,分析該數據結構和實際的excel可以發現,node模塊讀取是按excel一行一行的讀取,未讀取到的就是null,例如,第一行讀取到的
因為第一行中一些單元格合併為了一個,所以node模塊讀取的時候是按照一行讀取的,所以數組第二項讀取的前四項都為空
接下來是實現將讀取到的數組轉換為json數據的核心部分,
主要由3個函數組成
function arrToJson(arr, column) { //將數組轉換為嵌套的json對象 let MaxLength = arr.length - 1; let deep = {} for (let index = MaxLength; index >= 0; index--) { if (arr[index] === null) { break; } let obj = {}; if (Object.keys(deep).length > 0) { let childArr = [] obj['id'] = String(column) + '_' + String(index) obj['text'] = arr[index] childArr.push(deep) obj['children'] = childArr; deep = obj } else { obj['id'] = String(column) + '_' + String(index) obj['text'] = arr[index] deep = obj } } return deep;} 改函數作用是將每一行中的有效數據轉為具有層級的數形結構,對比node模塊讀取出的數據和excel的數據規律可以發現
每一行數據可以轉化為如圖嵌套的結構,數組的長度就是當前行的最大深度,
將最初的數組的每一項都轉為該結構如圖
6,再次分析node模塊讀取的數據和excel規律可以發現
第二行為個null,代表第一行的前四個數據,因此,只需要將第二行生成的嵌套對象和第一行生成的嵌套對象合併,再將第二行數據和第三行數據合併3->4合併,後邊以此類推即可得到完整的tree,
但是有一個問題,假設同樣有兩個第三級的數據我怎麼能知道後一項是插入第三級的哪一項中呢,其實觀察數據的規律不難發現,每次插入的時候只需要獲取當前數據所在項的深度,然後插入到比當前數據深度多一的父級的最後插入當前數據,即可保證插入的層級不會錯誤,
實現代碼如下
function createTree(arr) { //生成最終樹 let renderTree = {} arr=JSON.parse(JSON.stringify(arr)) arr.forEach((element, index) => { let result = arrToJson(element, index); if (Object.keys(renderTree).length > 0) { renderTree = getMergeTree(renderTree, result) } else { renderTree = getMergeTree(result, null) }}); writeJson(renderTree) } function getMergeTree(parentobj, currentobj) { //生成合併的樹 if (currentobj == null) { return parentobj; } let resultObj = {} DFS(parentobj, currentobj);
function DFS(parentobj, currentobj) {
let idNumber; try { idNumber = Number(currentobj.id.split('_')[1]) - 1 } catch (error) { idNumber = -10; }
let child = parentobj.children; if (child !== undefined && child.length > 0) {
let childrenLength = child.length - 1 let parentId = Number(parentobj.id.split('_')[1]) if (parentId == idNumber) { child.push(currentobj) }
DFS(child[childrenLength], currentobj) resultObj = parentobj }
} return resultObj } 該函數是一個DFS搜索演算法,搜索出比當前級大一級的父級對象樹,並且在父級樹的children數組的最後一項插入當前對象 如圖是前四項生成的json對象和第五項的合併
完整代碼如下:
var xlsx2json = require("node-xlsx"); var list = xlsx2json.parse("./test3.xlsx"); var fs = require("fs") let testarr = [ ['教育心理學', '教育心理學概述', '教育心理學的基本內涵', '研究對象與研究內容', '概念'], [null, null, null, null, '學科性質'], [null, null, null, null, '研究內容', '五要素三過程'], [null, null, null, '教育心理學與普通心理學的關係'], [null, null, null, '教育心理學的作用', '描述'], [null, null, null, null, '解釋'], [null, null, null, null, '預測'], [null, null, null, null, '控制'], [null, null, "教育心理學的發展史", "初創時期", "裴斯泰洛齊"], [null, null, null, null, "赫爾巴特"], [null, null, null, null, "桑代克"], [null, null, null, "發展時期", "小原又一"], [null, null, null, null, "廖世承"], [null, null, null, "成熟時期", "布魯納"], ]createTree(list[0].data)//使用node讀取的數組數據 // createTree(testarr)//測試,使用testarr數據可直接查看生成的數據,測試數據採用真實的一部分數據 // let totalobj={"id":"0_0","text":"教育心理學","children":[{"id":"0_1","text":"教育心理學概述","children":[{"id":"0_2","text":"教育心理學的基本內涵","children":[{"id":"0_3","text":"研究對象與研究內容","children":[{"id":"0_4","text":"概念"}]}]}]}]}
// let resultObj= getMergeTree(totalobj,{"id":"1_4","text":"學科性質"}) // console.log(JSON.stringify(resultObj)); function createTree(arr) { //生成最終樹 let renderTree = {} arr=JSON.parse(JSON.stringify(arr)) arr.forEach((element, index) => { let result = arrToJson(element, index); if (Object.keys(renderTree).length > 0) { renderTree = getMergeTree(renderTree, result) } else { renderTree = getMergeTree(result, null) }
}); writeJson(renderTree) }
function arrToJson(arr, column) { //將數組轉換為嵌套的json對象 let MaxLength = arr.length - 1; let deep = {} for (let index = MaxLength; index >= 0; index--) { if (arr[index] === null) { break; } let obj = {}; if (Object.keys(deep).length > 0) { let childArr = [] obj['id'] = String(column) + '_' + String(index) obj['text'] = arr[index] childArr.push(deep) obj['children'] = childArr; deep = obj } else { obj['id'] = String(column) + '_' + String(index) obj['text'] = arr[index] deep = obj } } return deep;
}
function getMergeTree(parentobj, currentobj) { //生成合併的樹 if (currentobj == null) { return parentobj; } let resultObj = {} DFS(parentobj, currentobj);
function DFS(parentobj, currentobj) {
let idNumber; try { idNumber = Number(currentobj.id.split('_')[1]) - 1 } catch (error) { idNumber = -10; }
let child = parentobj.children; if (child !== undefined && child.length > 0) {
let childrenLength = child.length - 1 let parentId = Number(parentobj.id.split('_')[1]) if (parentId == idNumber) { child.push(currentobj) }
DFS(child[childrenLength], currentobj) resultObj = parentobj }
} return resultObj }
function writeJson(arrlist) { fs.writeFile('person.json', JSON.stringify(arrlist), function (err) { if (err) { console.error(err); } console.log('----------新增成功-------------'); }) }