npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@ailhc/excel2all

v0.3.5

Published

将excel转换成任意文件格式工具

Downloads

28

Readme

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:int | mf:obj:string | | obj:obj_field_int | obj: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字段 | |------------------|------|-----------|-----------------|--------------|-----------------------------|---------------------------|-------------------|----------------------|-------------------------|-----------------------------|---------------------------|---------------------------| | TYPE | int | int | [int] | string | [string] | json | mf:obj:int | mf:obj:string | mf:obj:[int] | mf:obj:[string] | mf:obj:json | mf:obj:json | | CLIENT | id | field_int | field_int_array | field_string | field_string_array | field_json | obj:obj_field_int | obj:obj_field_string | obj:obj_field_int_array | obj:obj_field_string_array | obj:obj_field_json | obj:obj_field_json | | SERVER | id | field_int | field_int_array | | | | | | | | | | | | 1 | 5 | [1,2,3] | 玩转游戏开发 | ["玩转游戏开发"] | {"公众号":"玩转游戏开发"} | 5 | 玩转游戏开发 | [1,2,3] | ["玩转游戏开发"] | {"公众号":"玩转游戏开发"} | {"公众号":"玩转游戏开发"} | | NO | 4 | | [1,2,3] | 玩转游戏开发 | ["关注公众号:玩转游戏开发"] | {"公众号":"玩转游戏开发"} | | 玩转游戏开发 | [1,2,3] | ["关注公众号:玩转游戏开发"] | {"公众号":"玩转游戏开发"} | | | END | 7 | 300 | [1,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": {
                    "公众号": "玩转游戏开发"
                }
            }
        }
    }
  2. 声明

       
    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:ObjTypeSetting | TYPE | CLIENT | VALUE | |--------------------- |-------------------- |--------------- |--------------------------------------------- | | 数字 | int | Prop1 | 1 | | 布尔值 | boolean | PropBool | true | | 数字数组 | [int] | Prop2 | [1,2,3,4] | | 字符串 | string | Prop3 | string | | 字符串数组 | [string] | Prop4 | ["a","b","c"] | | json对象 | json | Prop5 | {"a":1,"b":2,"c":"c","d":[1],"f":["f","f"]} | | 嵌套对象测试:主键id | mf:MyObject:int | MyObject:id | 12 | | 名字 | mf:MyObject:string | MyObject: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;
}