使用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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...