使用node.js將xmind導出的excel轉換為json樹

来源:https://www.cnblogs.com/zzh965390267/archive/2019/12/12/12028207.html
-Advertisement-
Play Games

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('----------新增成功-------------');     }) }
   

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 案例:移動元素,封裝動畫函數 1. div要移動,要脫離文檔流 position:absolute 2. 如果樣式的代碼是在style的標簽中設置,外面是獲取不到 3. 如果樣式的代碼是在style的屬性設置,外面是可以獲取 4. 獲取div的當前位置 console.log(my$("dv").o ...
  • 案例:設置div的寬度 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>title</title> <style> * { margin: 0; padding: 0; } div { width: 200p ...
  • 案例:點擊按鈕設置div背景色漸變 背景色漸變:設置透明度 <div id="dv"></div> <input type="button" value="漸變" id="btn" /> <script src="common.js"></script> <script> my$("btn").on ...
  • 案例:協議按鈕倒計時和禁用 <textarea name="texta" id="" cols="30" rows="10"> 這個世界就是這麼瘋狂,你不同意,我就讓你註冊,秦始皇,打錢 </textarea> <input type="button" value="請仔細閱讀協議(5)" id=" ...
  • 之前學的定時器:setInterval和清除定時器 clearInterval(定時器id); //常用的,反覆的執行 window.setInterval(function () { alert("哈哈"); }, 1000); window.clearInterval(定時器id);//清理定時 ...
  • angular package 1、xlsx npm install xlsx --save 2、file-saver npm install file-saver --save npm install @types/file-saver --save 3、實現導出多個sheet的數據 export ...
  • 在項目的時候一直都是在使用谷歌瀏覽器在調試,後來在現場部署到伺服器上的時候,客戶使用的是IE瀏覽器,版本是11 在測試的過程中,出現幾個問題,雖然是幾個問題,但是問題的原因就是AJAX第一次響應,第二次就不在響應 例如:下拉框的數據第一次載入會通過AJAX調用後端方法,但是第二次之後就不在調用後端 ...
  • part5 課程介紹 另一個定時器 第一個定時器的小案例 練習 封裝動畫函數 勻速的動畫函數,過渡到 >緩動的動畫函數 簡單的輪播圖 左右焦點的輪播圖 無縫連接的輪播圖 輪播圖 重點 三大系列中的第一個系列:offset系列 重點 封裝緩動動畫函數 筋斗雲,固定導航欄 升級4到5個版本 手風琴 旋轉 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:本文代碼示例演示瞭如何在WPF中使用LiveCharts庫創建動態條形圖。通過創建數據模型、ViewModel和在XAML中使用`CartesianChart`控制項,你可以輕鬆實現圖表的數據綁定和動態更新。我將通過清晰的步驟指南包括詳細的中文註釋,幫助你快速理解並應用這一功能。 先上效果: 在 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • openGauss(GaussDB ) openGauss是一款全面友好開放,攜手伙伴共同打造的企業級開源關係型資料庫。openGauss採用木蘭寬鬆許可證v2發行,提供面向多核架構的極致性能、全鏈路的業務、數據安全、基於AI的調優和高效運維的能力。openGauss深度融合華為在資料庫領域多年的研 ...
  • 概述:本示例演示了在WPF應用程式中實現多語言支持的詳細步驟。通過資源字典和數據綁定,以及使用語言管理器類,應用程式能夠在運行時動態切換語言。這種方法使得多語言支持更加靈活,便於維護,同時提供清晰的代碼結構。 在WPF中實現多語言的一種常見方法是使用資源字典和數據綁定。以下是一個詳細的步驟和示例源代 ...
  • 描述(做一個簡單的記錄): 事件(event)的本質是一個委托;(聲明一個事件: public event TestDelegate eventTest;) 委托(delegate)可以理解為一個符合某種簽名的方法類型;比如:TestDelegate委托的返回數據類型為string,參數為 int和 ...
  • 1、AOT適合場景 Aot適合工具類型的項目使用,優點禁止反編 ,第一次啟動快,業務型項目或者反射多的項目不適合用AOT AOT更新記錄: 實實在在經過實踐的AOT ORM 5.1.4.117 +支持AOT 5.1.4.123 +支持CodeFirst和非同步方法 5.1.4.129-preview1 ...
  • 總說周知,UWP 是運行在沙盒裡面的,所有許可權都有嚴格限制,和沙盒外交互也需要特殊的通道,所以從根本杜絕了 UWP 毒瘤的存在。但是實際上 UWP 只是一個應用模型,本身是沒有什麼許可權管理的,許可權管理全靠 App Container 沙盒控制,如果我們脫離了這個沙盒,UWP 就會放飛自我了。那麼有沒... ...
  • 目錄條款17:讓介面容易被正確使用,不易被誤用(Make interfaces easy to use correctly and hard to use incorrectly)限制類型和值規定能做和不能做的事提供行為一致的介面條款19:設計class猶如設計type(Treat class de ...
  • title: 從零開始:Django項目的創建與配置指南 date: 2024/5/2 18:29:33 updated: 2024/5/2 18:29:33 categories: 後端開發 tags: Django WebDev Python ORM Security Deployment Op ...
  • 1、BOM對象 BOM:Broswer object model,即瀏覽器提供我們開發者在javascript用於操作瀏覽器的對象。 1.1、window對象 視窗方法 // BOM Browser object model 瀏覽器對象模型 // js中最大的一個對象.整個瀏覽器視窗出現的所有東西都 ...