????????在使用oops框架的過程中,它的導出數據并生成數據結構的插件oops-plugin-excel-to-json有些小的坑點,為滿足我個人習慣,對此部分進行了一個小的修改,有需要的拿去用,記錄下供大家參考;
一、配置:其他基本配置請自行搜索,首先能導出其例子中的xlsx表格,基于此來看這篇文章。
我的項目環境配置,如下圖:
- 表的配置小坑:
核心文件
extensions\oops-plugin-excel-to-json\dist\ExcelToJson.js
extensions\oops-plugin-excel-to-json\src\ExcelToJson.ts
就是表格的關鍵字必須在表格的名字中標明:
"【KEY】"
否則只能導出結構,不能導出數據,結構的主鍵還不對;所以根據項目自己增加的表格,必須增加這個關鍵字,才能正確導出結構和數據;
- 一個表個內的多個表單同時導出:
1,修改調用處的輸出文件的絕對文件名,為輸出路徑,這里的輸出是項目配置中的輸出路徑+原表格名稱;現在不需要,只要路徑,名稱由內部的表單決定;
表單名決定數據文件名json和數據結構名ts;
核心是將獲得表單的數量,然后循環處理下即可:
整體源碼如下:復制過去覆蓋,重新開啟編輯器即可。
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.run = run;
const path_1 = __importDefault(require("path"));
const JsonToTs_1 = require("./JsonToTs");
const main_1 = require("./main");
const fs = require('fs');
const excel = require('exceljs');
/*** Excel轉Json數據* @param {*} src 讀取的excel文件目錄* @param {*} dst 導出的json文件目錄* @param {*} name excel文件名* @param {*} isClient 是否為客戶端數據*/
async function convert(src, dst, name, isClient) {console.warn("src = ", src, " dst = ", dst, " name = ", name);const workbook = new excel.Workbook();// 讀取excelawait workbook.xlsx.readFile(src);console.warn("本次 xlsx的 文件路徑 : src = ", src, " 包含>>> ", workbook.worksheets.length , " <<<< 個分表 sheet", " workbook.worksheets = ", workbook.worksheets);for(let sheet_id = 1; sheet_id <= workbook.worksheets.length; sheet_id++){let r = {};let names = []; // 文名字段名let keys = []; // 字段名let types = []; // 通用字段數據類型let types_client = {}; // 客戶端數據類型let servers = []; // 是否輸出服務器字段數據let clients = []; // 是否輸出客戶端字段數據let primary = []; // 多主鍵配置let primary_index = [];const worksheet = workbook.getWorksheet(sheet_id); // 獲取第一個worksheet console.log("src = ", src, " tablename = ", worksheet.name);worksheet.eachRow((row, rowNumber) => {let data = {};row.eachCell((cell, colNumber) => {const value = cell.text;// console.warn(cell.text, cell.string, cell.number, cell.result, cell.formula)if (rowNumber === 1) { // 字段中文名names.push(value);if (value.indexOf("【KEY】") > -1)primary_index.push(colNumber);}else if (rowNumber === 2) { // 字段英文名keys.push(value);if (primary_index.indexOf(colNumber) > -1)primary.push(value);}else if (rowNumber === 3) { // 通用字段數據類型types.push(value);}else if (isClient == false && rowNumber === 4) { // 是否輸出服務器字段數據servers.push(value);}else if (isClient == true && rowNumber === 5) { // 客戶端數據類型 clients.push(value);}else if (rowNumber > 5) {let index = colNumber - 1;let type = types[index];let server = servers[index];let client = clients[index];// 驗證是否輸出這個字段let isWrite = isClient && client === "client" || isClient == false && server === "server";if (isWrite) {let key = keys[index];switch (type) {case "int":// console.warn(`${index}int`, key, value, cell.string, cell.number, cell.result)if (cell.formula) {data[key] = parseInt(cell.result);}else {data[key] = parseInt(value);}types_client[key] = {en: "number",zh: names[index]};break;case "float":// console.warn(`${index}int`, key, value, cell.string, cell.number, cell.result)if (cell.formula) {data[key] = parseFloat(cell.result);}else {data[key] = parseFloat(value);}types_client[key] = {en: "number",zh: names[index]};break;case "string":// console.warn(`${index}int`, key, value, cell.string, cell.number, cell.result)data[key] = value;types_client[key] = {en: "string",zh: names[index]};break;case "any":// console.warn(`${index}int`, key, value, cell.string, cell.number, cell.result)try {data[key] = JSON.parse(value);types_client[key] = {en: "any",zh: names[index]};}catch (_a) {console.log('Cell ' + cell.address + ' has value ' + cell.text);console.warn(`文件【${src}】的【${key}】字段【${data[key]}】類型數據【${value}】JSON轉字段串錯誤【${client}】`);}break;}}}});// 生成數據(多主鍵)if (rowNumber > 5) {let temp = null;for (var i = 0; i < primary.length; i++) {let k = primary[i];let id = data[k];delete data[k]; // 主鍵數據刪除if (primary.length == 1) {r[id] = data;}else {if (i == primary.length - 1) {temp[id] = data;}else if (i == 0) {if (r[id] == undefined) {r[id] = {};}temp = r[id];}else {temp[id] = {};temp = temp[id];}}}}});// 寫入流if (r["undefined"] == null) {await fs.writeFileSync(dst+ worksheet.name+ ".json", JSON.stringify(r));// 生成客戶端腳本if (isClient) {(0, JsonToTs_1.createTsClient)( worksheet.name, types_client, r, primary);}else {(0, JsonToTs_1.createTsServer)( worksheet.name, types_client, r, primary);}console.log(isClient ? "客戶端數據" : "服務器數據", "生成成功", dst);}else {console.log(isClient ? "客戶端數據" : "服務器數據", "無數據2", dst);}}}
function run() {var inputExcelPath = path_1.default.join(__dirname, main_1.config.PathExcel.replace("project://", "../../../") + "/");var outJsonPathClient = path_1.default.join(__dirname, main_1.config.PathJsonClient.replace("project://", "../../../") + "/");var outJsonPathServer = null;if (main_1.config.PathJsonServer != null && main_1.config.PathJsonServer.length > 0) {outJsonPathServer = path_1.default.join(__dirname, main_1.config.PathJsonServer.replace("project://", "../../../") + "/");}const files = fs.readdirSync(inputExcelPath);files.forEach((f) => {let name = f.substring(0, f.indexOf("."));let ext = f.toString().substring(f.lastIndexOf(".") + 1);if (ext == "xlsx") {if (outJsonPathServer)convert(inputExcelPath + f, outJsonPathServer , name, false); // 服務器數據convert(inputExcelPath + f, outJsonPathClient, name, true); // 客戶端數據}});
}
最后說明下:這里面還有一個不完善的地方就是:關于excel表中的分表的編號問題:
就是說必須是連續的表單順序,如果不連續就會有報錯,要新建一張表,把各個分表拷貝過去,保證它的表單ID順序是連續的。也就是說策劃可以改分表,但是輕易不要刪除分表,重新建一張分表。如果必須要刪除分表,要重新做一個新表文件,把分表逐一拷貝一份進去即可。保證分表順序是從1開始連續的即可。
祝各位用餐快樂!