添加 YAML 导器

This commit is contained in:
2020-11-12 22:36:04 +08:00
parent 9209b17b06
commit 851670887b
13 changed files with 140 additions and 88 deletions

1
.gitignore vendored
View File

@@ -3,4 +3,5 @@ output/
node_modules/
yarn.lock
package-lock.json
*.xlsx
*.xlsl

7
.vscode/launch.json vendored
View File

@@ -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"
]
}
]

View File

@@ -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
```

View File

@@ -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
View 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

View File

@@ -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"
}
}

View File

@@ -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];
}

View File

@@ -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++) {

View File

@@ -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}`));

View 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}`));
}

View 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);

View 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}`));
}
}

View 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();