0.3.5 • Published 4 years ago

@ailhc/excel2all v0.3.5

Weekly downloads
-
License
MIT
Repository
github
Last release
4 years ago

excel2all

excel配置表转换库

简介

一个可以将各种Excel表转换成各种文件的工具库,默认支持将xlsx和csv格式的Excel表转换为json文件和ts声明文件

特性

  1. 支持增量解析转换(只转换改过的文件,我改一个表,解析100个表?不存在)
  2. 默认支持解析xlsx和csv格式Excel表转换为json文件和ts声明文件
  3. 满足大部分需求的默认配置表解析规则
  4. 支持自定义解析和转换逻辑
  5. 提供完善生命周期钩子,可以接入自动上传,自动svn提交之类的逻辑
  6. 支持不同Excel文件同名表合并(方便多分支版本管理)

CHANGELOG

默认表格规范

表头

第一列第一行 A1

这里定义配置表的类型和名字,用冒号:隔开

H 即: Horizontal 指这个表的字段是纵向扩展。比如 H:TableTypeSetting

V 即: Vertical 指这个表的字段纵向扩展。比如: V:ObjTypeSetting

如果不指定类型,则默认用H类型 比如: TableTypeSetting 类型是H

第一行也是注释行,可以写这个字段的注释,会生成到声明文件中

默认的字段类型和值转换规则

默认的字段类型与Javascript的类型对照

  1. int => number ; 需配置: 123 => 转换值: 123

  2. boolean => boolean ; 需配置: true => 转换值: true

  3. string => string ; 需配置: 字符串 => 转换值: 字符串

  4. int => number[] ; 需配置: 1,2,3 => 转换值: 1,2,3

  5. string => string[] ; 需配置: "a","b","c" => 转换值: "1","2","3"

  6. json => Object / {} ; 需配置: {"公众号":"玩转游戏开发"} => 转换值: {"公众号":"玩转游戏开发"}

    这个类型的转换处理:先使用JSON.parse转换,如果出错则直接返回未转换的值,会导致出错和报错

  7. 对象分列配置,比如

    多列对象:数字字段字符串字段
    mf:obj:intmf:obj:string
    obj:obj_field_intobj:obj_field_string

    生成JSON:

        "obj": {
                    "obj_field_int": 5,
                    "obj_field_string": "玩转游戏开发",
                    "obj_field_int_array": [
                        1,
                        2,
                        3
                    ],
                    "obj_field_string_array": [
                        "玩转游戏开发"
                    ],
                    "obj_field_json": {
                        "公众号": "玩转游戏开发"
                    }
                }

    生成声明:

    readonly obj?: {
            /** 多列对象:数字字段 */
            readonly obj_field_int?: number;
            /** 字符串字段 */
            readonly obj_field_string?: string;
            /** 数字数组字段 */
            readonly obj_field_int_array?: number[];
            /** 字符串数组字段 */
            readonly obj_field_string_array?: string[];
            /** json字段 */
            readonly obj_field_json?: any;
        }
  8. any => any ; 需配置: 2,\"11\" => 转换值: 2,"11"

    这个类型的转换处理:先使用JSON.parse转换,如果出错则直接返回未转换的值,但不会导致出错

非默认类型的值则会使用 JSON.parse() 去转换

非默认类型的类型声明也会原封不动的使用配置的不会转换

比如: Array<Object> => field: Array<Object>

字段横向扩展类型

  1. 标志 TYPE

    标志这一行是配置字段类型的

  2. 标志 CLIENT 标志这一行是配置字段名的

  3. 标志 NO

    标志这一行不解析

  4. 标志 END

    标志这一行是最后一行,解析完之后,就不再解析下一行

  5. 列结束标志: 当前列的值为空

    如果注释行也就是第一行,这一列的值为空则列结束,将不会继续解析

主键列

B为主键列

这一列的值将会作为,每一行的对象在Table对象中的key

具体可见下面的示例

配置表

TableTypeSetting主键数字数字数组字符串字符串数组JSON多列对象:数字字段字符串字段数字数组字段字符串数组字段json字段json字段
TYPEintintintstringstringjsonmf:obj:intmf:obj:stringmf:obj:intmf:obj:stringmf:obj:jsonmf:obj:json
CLIENTidfield_intfield_int_arrayfield_stringfield_string_arrayfield_jsonobj:obj_field_intobj:obj_field_stringobj:obj_field_int_arrayobj:obj_field_string_arrayobj:obj_field_jsonobj:obj_field_json
SERVERidfield_intfield_int_array
151,2,3玩转游戏开发"玩转游戏开发"{"公众号":"玩转游戏开发"}5玩转游戏开发1,2,3"玩转游戏开发"{"公众号":"玩转游戏开发"}{"公众号":"玩转游戏开发"}
NO41,2,3玩转游戏开发"关注公众号:玩转游戏开发"{"公众号":"玩转游戏开发"}玩转游戏开发1,2,3"关注公众号:玩转游戏开发"{"公众号":"玩转游戏开发"}
END73001,8,3玩转游戏开发"关注公众号:玩转游戏开发"{"公众号":"玩转游戏开发"}300玩转游戏开发1,8,3"关注公众号:玩转游戏开发"{"公众号":"玩转游戏开发"}

转换值

  1. JSON

    {
        "1": {
            "id": 1,
            "field_int": 5,
            "field_int_array": [
                1,
                2,
                3
            ],
            "field_string": "玩转游戏开发",
            "field_string_array": [
                "玩转游戏开发"
            ],
            "field_json": {
                "公众号": "玩转游戏开发"
            },
            "obj": {
                "obj_field_int": 5,
                "obj_field_string": "玩转游戏开发",
                "obj_field_int_array": [
                    1,
                    2,
                    3
                ],
                "obj_field_string_array": [
                    "玩转游戏开发"
                ],
                "obj_field_json": {
                    "公众号": "玩转游戏开发"
                }
            }
        }
    }
  1. 声明

    interface IT_TableTypeSetting {
        /** 主键 */
        readonly id?: number;
        /** 数字 */
        readonly field_int?: number;
        /** 布尔值 */
        readonly field_bool?: boolean;
        /** 数字数组 */
        readonly field_int_array?: number[];
        /** 字符串 */
        readonly field_string?: string;
        /** 字符串数组 */
        readonly field_string_array?: string[];
        /** JSON */
        readonly field_json?: any;
        readonly obj?: {
            /** 多列对象:数字字段 */
            readonly obj_field_int?: number;
            /** 字符串字段 */
            readonly obj_field_string?: string;
            /** 数字数组字段 */
            readonly obj_field_int_array?: number[];
            /** 字符串数组字段 */
            readonly obj_field_string_array?: string[];
            /** json字段 */
            readonly obj_field_json?: any;
        }
    }

字段纵向扩展类型

规范

A列为注释列

B列为类型列

C列为字段列

D列为值

配置表

V:ObjTypeSettingTYPECLIENTVALUE
数字intProp11
布尔值booleanPropBooltrue
数字数组intProp21,2,3,4
字符串stringProp3string
字符串数组stringProp4"a","b","c"
json对象jsonProp5{"a":1,"b":2,"c":"c","d":1,"f":"f","f"}
嵌套对象测试:主键idmf:MyObject:intMyObject:id12
名字mf:MyObject:stringMyObject:name你么

转换值

  1. JSON

    {
        "Prop1": 1,
        "PropBool": true,
        "Prop2": [
            1,
            2,
            3,
            4
        ],
        "Prop3": "string",
        "Prop4": [
            "a",
            "b",
            "c"
        ],
        "Prop5": {
            "a": 1,
            "b": 2,
            "c": "c",
            "d": [
                1
            ],
            "f": [
                "f",
                "f"
            ]
        },
        "MyObject": {
            "id": 12,
            "name": "你么"
        }
    }
  2. 声明

    interface IT_ObjTypeSetting {
        /** 数字 */
        readonly Prop1?: number;
        /** 布尔值 */
        readonly PropBool?: boolean;
        /** 数字数组 */
        readonly Prop2?: number[];
        /** 字符串 */
        readonly Prop3?: string;
        /** 字符串数组 */
        readonly Prop4?: string[];
        /** json对象 */
        readonly Prop5?: any;
        readonly MyObject?: {
            /** 嵌套对象测试:主键id */
            readonly id?: number;
            /** 名字 */
            readonly name?: string;
        }
    }

自定义扩展

扩展值解析功能

interface ITableField {
        /**配置表中注释值 */
        text: string;
        /**配置表中类型值 */
        originType: string;
        /**配置表中字段名值 */
        originFieldName: string;
        /**解析后的类型值 */
        type?: string;
        /**解析后的字段名值 */
        fieldName?: string;
        /**对象的子字段名 */
        subFieldName?: string;
        /**多列对象 */
        isMutiColObj?: boolean;
}
/**值转换结果 */
interface ITransValueResult {
    /**错误信息*/
    error?: string;
    /**转换后的值*/
    value?: any;
}
/**值转换方法 */
type ValueTransFunc = (fieldItem: ITableField, cellValue: any) => ITransValueResult;
/**
 * 值转换方法字典
 * key是类型key
 * value是方法
 */
type ValueTransFuncMap = { [key: string]: ValueTransFunc };

具体可见__test__/convert_customValueTrans_test.js 配置:

const tableFileDir = path.join(process.cwd(), "__test__/test-excel-files");
/**
 * @type {IOutputConfig}
 */
const outputConfig = {
    /**自定义 配置字段类型和ts声明类型字符串映射字典 */
    customTypeStrMap: { "nums": "number[]" }
}
/**
 * @type {ITableParserConfig}
 */
const parserConfig = {
    customValueTransFuncMap: {
        'nums': function (field, cellValue) {
            /**
             * @type {ITransValueResult}
             */
            const transResult = {};
            if (cellValue && typeof cellValue === "string") {
                cellValue = (cellValue + "").replace(/,/g, ","); //为了防止策划误填,先进行转换
                /**
                 * @type {string[]}
                 */
                const numStrs = cellValue.split(",");
                const nums = numStrs.map((value) => { return Number(value) })
                transResult.value = nums;
            } else {
                transResult.error = `类型:nums,所配配置的值无法解析:${cellValue}`;
                transResult.value = cellValue;
            }
            return transResult;
        }
    }
}
/**
 * @type {ITableConvertConfig}
 */
const config = {
    projRoot: "./__test__",
    tableFileDir: tableFileDir,
    useCache: false,
    parserConfig:parserConfig
    outputConfig: outputConfig;
}
module.exports = config;

excel配置:

自定义类型,解析为number数组
nums
field_custom_type
1,2,3,4

解析结果:

"field_custom_type":[1,2,3,4],

自定义整个转换流程

可以只实现某个hook,其他没实现的则调用默认hook的逻辑

interface IConvertHook {
    /**
     * 开始转换
     * 处理好配置
     * @param context 上下文
     * @param cb 生命周期结束回调,必须调用
     */
    onStart?(context: IConvertContext, cb: VoidFunction): void;
    /**
     * 遍历文件之后,解析之前
     * @param context 上下文
     * @param cb 生命周期结束回调,必须调用
     */
    onParseBefore?(context: IConvertContext, cb: VoidFunction): void;
    /**
     * 配置表解析
     * @param context
     * @param cb
     */
    onParse?(context: IConvertContext, cb: VoidFunction): void;
    /**
     * 解析结束
     * 可以转换解析结果为多个任意文件
     * @param context 上下文
     * @param cb 生命周期结束回调,必须调用
     */
    onParseAfter?(context: IConvertContext, cb: VoidFunction): void;
    /**
     * 写入文件结束
     * @param context 上下文
     */
    onConvertEnd?(context: IConvertContext): void;
}
0.3.5

4 years ago

0.3.4

4 years ago

0.3.3

4 years ago

0.3.2

4 years ago

0.3.0

4 years ago

0.3.1

4 years ago

0.2.7

4 years ago

0.2.6

4 years ago

0.2.5

4 years ago

0.2.4

4 years ago

0.2.3

4 years ago

0.2.2

4 years ago