Merge branch 'excel-exporter' of https://github.com/Tiny-Fun-Technologies/excel-exporter into excel-exporter
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
dist/
|
||||
output/
|
||||
node_modules/
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
18
README.md
18
README.md
@@ -5,7 +5,7 @@
|
||||
## 支持将Excel配置表导出为:
|
||||
- [x] JSON 文件
|
||||
- [x] C# 类型声明
|
||||
- [ ] TypeScript 声明文件、类型文件(可用 `instanceof` 进行类型检查)
|
||||
- [x] TypeScript interface类型声明、class类型定义(可用 `instanceof` 进行类型检查)
|
||||
- [ ] Godot 引擎的 GDScript 脚本文件
|
||||
|
||||
## 表格格式说明
|
||||
@@ -42,8 +42,7 @@ npm run build
|
||||
```json
|
||||
{
|
||||
"input": [
|
||||
{ "file": "装备表.xlsx", "encode": "GBK"},
|
||||
{ "file": "关卡表.xlsx", "encode": "GBK"},
|
||||
{ "file": "配置表.xlsx", "encode": "GBK"}
|
||||
],
|
||||
"parser": {
|
||||
"first_row_as_field_comment": true
|
||||
@@ -51,16 +50,25 @@ npm run build
|
||||
"output": {
|
||||
"json": {
|
||||
"enabled": true,
|
||||
"directory": "../../client/Assets/Resources/data/json",
|
||||
"directory": "output/json",
|
||||
"indent": "\t"
|
||||
},
|
||||
"csharp": {
|
||||
"enabled": true,
|
||||
"directory": "../../client/Assets/Resources/data/csharp",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,16 +8,25 @@
|
||||
"output": {
|
||||
"json": {
|
||||
"enabled": true,
|
||||
"directory": "../../client/Assets/Resources/data/json",
|
||||
"directory": "output/json",
|
||||
"indent": "\t"
|
||||
},
|
||||
"csharp": {
|
||||
"enabled": true,
|
||||
"directory": "../../client/Assets/Resources/data/csharp",
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import { ExporterConfigs, TableExporter } from "./TableExporter";
|
||||
import { JSONExporter } from "./exporters/JSONExporter";
|
||||
import { CSharpExporter } from "./exporters/CSharpExporter";
|
||||
import * as colors from "colors";
|
||||
import { TypeScriptExporter } from "./exporters/TypeScriptExporter";
|
||||
|
||||
export interface Configurations {
|
||||
/** 解析配置 */
|
||||
@@ -18,6 +19,7 @@ export interface Configurations {
|
||||
const exporters: {[key:string]: new(config: ExporterConfigs) => TableExporter } = {
|
||||
json: JSONExporter,
|
||||
csharp: CSharpExporter,
|
||||
typescript: TypeScriptExporter,
|
||||
}
|
||||
|
||||
|
||||
|
||||
104
src/excel-exporter/exporters/TypeScriptExporter.ts
Normal file
104
src/excel-exporter/exporters/TypeScriptExporter.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import { TableExporter, ExporterConfigs } from "excel-exporter/TableExporter";
|
||||
import { TableData, DataType } from "excel-exporter/TableParser";
|
||||
import * as colors from "colors";
|
||||
import { path } from "tiny/path";
|
||||
|
||||
interface TypeScriptExporterConfigs extends ExporterConfigs {
|
||||
type: "interface" | "class",
|
||||
declaration: boolean,
|
||||
file_name: string,
|
||||
class_name_prefix: string,
|
||||
class_name_extension: string,
|
||||
}
|
||||
|
||||
export class TypeScriptExporter extends TableExporter {
|
||||
|
||||
classes: string[] = [];
|
||||
|
||||
constructor(configs: TypeScriptExporterConfigs) {
|
||||
super(configs);
|
||||
configs.class_name_prefix = configs.class_name_prefix || "";
|
||||
configs.class_name_extension = configs.class_name_extension || "";
|
||||
}
|
||||
|
||||
export (name: string, table: TableData) {
|
||||
this.export_table(
|
||||
name,
|
||||
table,
|
||||
(this.configs as TypeScriptExporterConfigs).type,
|
||||
(this.configs as TypeScriptExporterConfigs).declaration,
|
||||
);
|
||||
}
|
||||
|
||||
protected export_table(name: string, table: TableData, export_type: "class" | "interface", declaration: boolean) {
|
||||
let configs = (this.configs as TypeScriptExporterConfigs);
|
||||
let class_name = `${configs.class_name_prefix}${name}${configs.class_name_extension}`;
|
||||
|
||||
let body = "";
|
||||
for (const field of table.headers) {
|
||||
let type = "any";
|
||||
switch (field.type) {
|
||||
case DataType.bool:
|
||||
type = "boolean";
|
||||
case DataType.string:
|
||||
type = "string";
|
||||
break;
|
||||
case DataType.float:
|
||||
case DataType.int:
|
||||
type = "number";
|
||||
break;
|
||||
default:
|
||||
type = "any";
|
||||
break;
|
||||
}
|
||||
if (field.is_array) {
|
||||
type += "[]";
|
||||
}
|
||||
if (field.comment) {
|
||||
if (field.comment.trim().length) {
|
||||
let comments = field.comment.split("\n");
|
||||
if (comments.length > 1) {
|
||||
body += this.line("/** ", 1);
|
||||
for (const comment of comments) {
|
||||
body += this.line(" * " + comment.trim() + " ", 1);
|
||||
}
|
||||
body += this.line(" */", 1);
|
||||
} else {
|
||||
body += this.line(`/** ${comments[0].trim()} */`, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
body += this.line(`${field.name}: ${type};`, 1);
|
||||
}
|
||||
if (export_type == "class" && !declaration) {
|
||||
body += this.line();
|
||||
body += this.line(`static $bind_rows(rows: object[]) {`, 1);
|
||||
body += this.line(`for (const row of rows) {`, 2);
|
||||
body += this.line(`Object.setPrototypeOf(row, ${class_name}.prototype);`, 3);
|
||||
body += this.line("}", 2);
|
||||
body += this.line("}", 1);
|
||||
}
|
||||
let export_method = declaration ? "declare" : "export";
|
||||
let class_text = this.line(`${export_method} ${export_type} ${class_name} {\n${body}\n}`);
|
||||
this.classes.push(class_text);
|
||||
}
|
||||
|
||||
finalize() {
|
||||
let configs = (this.configs as TypeScriptExporterConfigs);
|
||||
const extension = configs.declaration ? ".d.ts" : ".ts";
|
||||
let class_text = this.line("// Tool generated file DO NOT MODIFY");
|
||||
class_text += this.line();
|
||||
|
||||
for (const cls of this.classes) {
|
||||
class_text += cls;
|
||||
class_text += this.line();
|
||||
}
|
||||
let file = path.join(this.configs.directory, (this.configs as TypeScriptExporterConfigs).file_name);
|
||||
if (!file.endsWith(extension)) {
|
||||
file += extension;
|
||||
}
|
||||
this.save_text(file, class_text);
|
||||
console.log(colors.green(`\t${file}`));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user