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