cocos3.X的oops框架oops-plugin-excel-to-json改进兼容多表单导出功能

在使用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();
    // 读取excel
    await 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开始连续的即可。

祝各位用餐快乐!

相关推荐
崔庆才丨静觅5 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60616 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了6 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅6 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅7 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅7 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment7 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅7 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊7 小时前
jwt介绍
前端
爱敲代码的小鱼7 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax