添加 YAML 导器
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,4 +3,5 @@ output/
|
||||
node_modules/
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
*.xlsx
|
||||
*.xlsl
|
||||
7
.vscode/launch.json
vendored
7
.vscode/launch.json
vendored
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
@@ -8,10 +9,12 @@
|
||||
"skipFiles": [
|
||||
"<node_internals>/**"
|
||||
],
|
||||
"cwd": "D:/work/repositories/zombie/config/新配表",
|
||||
// "cwd": "D:/work/repositories/zombie/config/新配表",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"program": "${workspaceFolder}/dist/binary.js",
|
||||
"args": [
|
||||
"./excel-exporter.json"
|
||||
"./excel-exporter.yaml"
|
||||
// "./excel-exporter.json"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
66
README.md
66
README.md
@@ -4,6 +4,7 @@
|
||||
|
||||
## 支持将Excel配置表导出为:
|
||||
- [x] JSON 文件
|
||||
- [x] YAML 文件
|
||||
- [x] C# 类型声明
|
||||
- [x] TypeScript interface类型声明、class类型定义(可用 `instanceof` 进行类型检查)
|
||||
- [ ] Godot 引擎的 GDScript 脚本文件
|
||||
@@ -33,43 +34,40 @@ npm run build
|
||||
|
||||
## 使用
|
||||
- 按照上面介绍的规则填写 Excel 配置表
|
||||
- 修改 `excel-exporter.json` 修改工具配置,配置要读取的 Excel 文件列表,配置你需要的导出器
|
||||
- 修改 `excel-exporter.yaml` 修改工具配置,配置要读取的 Excel 文件列表,配置你需要的导出器
|
||||
- Windows 下双击 `转表.bat` 执行转换工作
|
||||
- Linux/macOS 下执行 `转表.sh` 执行转换工作
|
||||
|
||||
### 配置示例
|
||||
|
||||
```json
|
||||
{
|
||||
"input": [
|
||||
{ "file": "配置表.xlsx", "encode": "GBK"}
|
||||
],
|
||||
"parser": {
|
||||
"first_row_as_field_comment": true
|
||||
},
|
||||
"output": {
|
||||
"json": {
|
||||
"enabled": true,
|
||||
"directory": "output/json",
|
||||
"indent": "\t"
|
||||
},
|
||||
"csharp": {
|
||||
"enabled": true,
|
||||
"directory": "output/csharp",
|
||||
"namespace": "game.data",
|
||||
"base_type": "tiny.data.UniqueIDObject",
|
||||
"file_name": "data",
|
||||
"ignore_id": true
|
||||
},
|
||||
"typescript": {
|
||||
"enabled": true,
|
||||
"declaration": false,
|
||||
"type": "class",
|
||||
"class_name_prefix": "",
|
||||
"class_name_extension": "Data",
|
||||
"directory": "output/typescript",
|
||||
"file_name": "data"
|
||||
}
|
||||
}
|
||||
}
|
||||
```yaml
|
||||
parser:
|
||||
first_row_as_field_comment: true
|
||||
input:
|
||||
- file: 配置表.xlsx
|
||||
encode: GBK
|
||||
output:
|
||||
json:
|
||||
enabled: true
|
||||
directory: output/json
|
||||
indent: "\t"
|
||||
yaml:
|
||||
enabled: true
|
||||
directory: output/yaml
|
||||
indent: 2
|
||||
csharp:
|
||||
enabled: true
|
||||
directory: output/csharp
|
||||
namespace: game.data
|
||||
base_type: tiny.data.UniqueIDObject
|
||||
file_name: data
|
||||
ignore_id: true
|
||||
typescript:
|
||||
enabled: true
|
||||
declaration: false
|
||||
type: class
|
||||
class_name_prefix: ''
|
||||
class_name_extension: Data
|
||||
directory: output/typescript
|
||||
file_name: data
|
||||
```
|
||||
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"input": [
|
||||
{ "file": "配置表.xlsx", "encode": "GBK"}
|
||||
],
|
||||
"parser": {
|
||||
"first_row_as_field_comment": true
|
||||
},
|
||||
"output": {
|
||||
"json": {
|
||||
"enabled": true,
|
||||
"directory": "output/json",
|
||||
"indent": "\t"
|
||||
},
|
||||
"csharp": {
|
||||
"enabled": true,
|
||||
"directory": "output/csharp",
|
||||
"namespace": "game.data",
|
||||
"base_type": "tiny.data.UniqueIDObject",
|
||||
"file_name": "data",
|
||||
"ignore_id": true
|
||||
},
|
||||
"typescript": {
|
||||
"enabled": true,
|
||||
"declaration": false,
|
||||
"type": "class",
|
||||
"class_name_prefix": "",
|
||||
"class_name_extension": "Data",
|
||||
"directory": "output/typescript",
|
||||
"file_name": "data"
|
||||
}
|
||||
}
|
||||
}
|
||||
28
excel-exporter.yaml
Normal file
28
excel-exporter.yaml
Normal file
@@ -0,0 +1,28 @@
|
||||
parser:
|
||||
first_row_as_field_comment: true
|
||||
input:
|
||||
- 配置表.xlsx
|
||||
output:
|
||||
json:
|
||||
enabled: true
|
||||
directory: output/json
|
||||
indent: "\t"
|
||||
yaml:
|
||||
enabled: true
|
||||
directory: output/yaml
|
||||
indent: 2
|
||||
csharp:
|
||||
enabled: true
|
||||
directory: output/csharp
|
||||
namespace: game.data
|
||||
base_type: tiny.data.UniqueIDObject
|
||||
file_name: data
|
||||
ignore_id: true
|
||||
typescript:
|
||||
enabled: true
|
||||
declaration: false
|
||||
type: class
|
||||
class_name_prefix: ''
|
||||
class_name_extension: Data
|
||||
directory: output/typescript
|
||||
file_name: data
|
||||
@@ -9,6 +9,7 @@
|
||||
"build": "node ./tools/build.js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/js-yaml": "^3.12.5",
|
||||
"@types/node": "^14.0.1",
|
||||
"shelljs": "^0.8.4",
|
||||
"ts-loader": "^7.0.4",
|
||||
@@ -19,6 +20,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"colors": "^1.4.0",
|
||||
"js-yaml": "^3.14.0",
|
||||
"xlsx": "^0.16.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import { JSONExporter } from "./exporters/JSONExporter";
|
||||
import { CSharpExporter } from "./exporters/CSharpExporter";
|
||||
import * as colors from "colors";
|
||||
import { TypeScriptExporter } from "./exporters/TypeScriptExporter";
|
||||
import * as yaml from "js-yaml";
|
||||
import { YAMLExporter } from "./exporters/YAMLExporter";
|
||||
|
||||
export interface Configurations {
|
||||
/** 解析配置 */
|
||||
@@ -20,6 +22,7 @@ const exporters: {[key:string]: new(config: ExporterConfigs) => TableExporter }
|
||||
json: JSONExporter,
|
||||
csharp: CSharpExporter,
|
||||
typescript: TypeScriptExporter,
|
||||
yaml: YAMLExporter,
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +35,7 @@ export class ExcelExporterApplication {
|
||||
|
||||
constructor(config_file: string) {
|
||||
let file = FileAccess.open(config_file, ModeFlags.READ);
|
||||
this.configs = JSON.parse(file.get_as_utf8_string()) as Configurations;
|
||||
this.configs = yaml.load(file.get_as_utf8_string()) as Configurations;
|
||||
file.close();
|
||||
this.parser = new TableParser(this.configs.parser);
|
||||
|
||||
@@ -47,9 +50,9 @@ export class ExcelExporterApplication {
|
||||
}
|
||||
|
||||
parse() {
|
||||
for (const item of this.configs.input) {
|
||||
console.log(colors.grey(`解析配表文件: ${item.file}`));
|
||||
let sheets = this.parser.parse_xlsl(item.file);
|
||||
for (const file of this.configs.input) {
|
||||
console.log(colors.grey(`解析配表文件: ${file}`));
|
||||
let sheets = this.parser.parse_xlsl(file);
|
||||
for (const name in sheets) {
|
||||
this.tables[name] = sheets[name];
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ export class TableExporter {
|
||||
this.configs = configs;
|
||||
}
|
||||
|
||||
get extension(): string { return ''}
|
||||
|
||||
protected line(text = "", indent = 0) {
|
||||
let line = "";
|
||||
for (let i = 0; i < indent; i++) {
|
||||
|
||||
@@ -13,6 +13,7 @@ interface CSharpExporterConfigs extends ExporterConfigs {
|
||||
export class CSharpExporter extends TableExporter {
|
||||
protected declear_content = "";
|
||||
protected classes: string[] = [];
|
||||
get extension(): string { return 'cs' }
|
||||
|
||||
constructor(configs: ExporterConfigs) {
|
||||
super(configs);
|
||||
@@ -34,7 +35,6 @@ export class CSharpExporter extends TableExporter {
|
||||
this.declear_content += this.line("}");
|
||||
}
|
||||
|
||||
|
||||
export(name: string, table: TableData) {
|
||||
const base_type = (this.configs as CSharpExporterConfigs).base_type;
|
||||
let body = "";
|
||||
@@ -77,7 +77,7 @@ export class CSharpExporter extends TableExporter {
|
||||
|
||||
let file = path.join(this.configs.directory, (this.configs as CSharpExporterConfigs).file_name);
|
||||
if (!file.endsWith(".cs")) {
|
||||
file += ".cs";
|
||||
file += "." + this.extension;
|
||||
}
|
||||
this.save_text(file, this.declear_content.replace("%CLASSES%", class_text));
|
||||
console.log(colors.green(`\t${file}`));
|
||||
|
||||
@@ -17,6 +17,8 @@ export class JSONExporter extends TableExporter {
|
||||
}
|
||||
}
|
||||
|
||||
get extension(): string { return 'json'}
|
||||
|
||||
protected recursively_order_keys(unordered: object | Array<object>) {
|
||||
// If it's an array - recursively order any
|
||||
// dictionary items within the array
|
||||
@@ -37,18 +39,7 @@ export class JSONExporter extends TableExporter {
|
||||
return unordered;
|
||||
}
|
||||
|
||||
export(name: string, table: TableData) {
|
||||
const file = path.join(this.configs.directory, name + ".json");
|
||||
let headers = table.headers;
|
||||
let values = [];
|
||||
for (const row of table.values) {
|
||||
let new_row = {};
|
||||
for (let i = 0; i < headers.length; i++) {
|
||||
const field = headers[i];
|
||||
new_row[field.name] = row[i];
|
||||
}
|
||||
values.push(new_row);
|
||||
}
|
||||
protected get indent(): string {
|
||||
let indent = "";
|
||||
const configs = (this.configs as JSONExporterConfigs);
|
||||
if (configs.indent) {
|
||||
@@ -60,7 +51,26 @@ export class JSONExporter extends TableExporter {
|
||||
indent = configs.indent;
|
||||
}
|
||||
}
|
||||
const text = JSON.stringify(this.recursively_order_keys(values), null, indent);
|
||||
return indent;
|
||||
}
|
||||
|
||||
export_json_object(name: string, table: TableData) {
|
||||
let headers = table.headers;
|
||||
let values = [];
|
||||
for (const row of table.values) {
|
||||
let new_row = {};
|
||||
for (let i = 0; i < headers.length; i++) {
|
||||
const field = headers[i];
|
||||
new_row[field.name] = row[i];
|
||||
}
|
||||
values.push(new_row);
|
||||
}
|
||||
return this.recursively_order_keys(values);
|
||||
}
|
||||
|
||||
export(name: string, table: TableData) {
|
||||
const file = path.join(this.configs.directory, `${name}.${this.extension}`);
|
||||
const text = JSON.stringify(this.export_json_object(name, table), null, this.indent);
|
||||
this.save_text(file, text);
|
||||
console.log(colors.green(`\t ${name} ==> ${file}`));
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ interface TypeScriptExporterConfigs extends ExporterConfigs {
|
||||
export class TypeScriptExporter extends TableExporter {
|
||||
|
||||
classes: string[] = [];
|
||||
get extension(): string { return 'ts'}
|
||||
|
||||
constructor(configs: TypeScriptExporterConfigs) {
|
||||
super(configs);
|
||||
|
||||
36
src/excel-exporter/exporters/YAMLExporter.ts
Normal file
36
src/excel-exporter/exporters/YAMLExporter.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { ExporterConfigs } from "excel-exporter/TableExporter";
|
||||
import { TableData } from "excel-exporter/TableParser";
|
||||
import { path } from "tiny/path";
|
||||
import * as colors from "colors";
|
||||
import { JSONExporter } from "./JSONExporter";
|
||||
import * as yaml from "js-yaml";
|
||||
|
||||
interface YAMLExporterConfigs extends ExporterConfigs {
|
||||
/** 缩进字符 */
|
||||
indent: number;
|
||||
}
|
||||
|
||||
export class YAMLExporter extends JSONExporter {
|
||||
|
||||
get extension(): string { return 'yaml'}
|
||||
|
||||
constructor(configs: ExporterConfigs) {
|
||||
super(configs);
|
||||
if ( typeof ((this.configs as YAMLExporterConfigs).indent) != 'number') {
|
||||
(this.configs as YAMLExporterConfigs).indent = 2;
|
||||
}
|
||||
}
|
||||
|
||||
export(name: string, table: TableData) {
|
||||
const file = path.join(this.configs.directory, `${name}.${this.extension}`);
|
||||
const text = yaml.dump(
|
||||
this.export_json_object(name, table),
|
||||
{
|
||||
indent: this.indent.length,
|
||||
sortKeys: true,
|
||||
}
|
||||
);
|
||||
this.save_text(file, text);
|
||||
console.log(colors.green(`\t ${name} ==> ${file}`));
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import * as colors from "colors";
|
||||
(async function main(argv: string[]) {
|
||||
|
||||
let config_file = argv[argv.length - 1];
|
||||
if (config_file.endsWith(".json") && FileAccess.exists(config_file)) {
|
||||
if (config_file.endsWith(".yaml") && FileAccess.exists(config_file)) {
|
||||
let app = new ExcelExporterApplication(config_file);
|
||||
app.parse();
|
||||
app.export();
|
||||
|
||||
Reference in New Issue
Block a user