添加 first_column_as_id 配置,将第一列导出为 id 字段

修正基础类型数据的数组长度导出错误
This commit is contained in:
2021-01-25 16:38:34 +08:00
parent b660860389
commit 7c26b9ea48
2 changed files with 45 additions and 30 deletions

View File

@@ -1,9 +1,10 @@
parser:
first_row_as_field_comment: true
constant_array_length:
- EffectSequence
input: input:
- 配置表.xlsx - 配置表.xlsx
parser:
first_column_as_id: true # 第一列用作 ID 列
constant_array_length: [
# 这里填入需要固定数组长度的表名称
]
output: output:
json: json:
enabled: true enabled: true

View File

@@ -2,6 +2,24 @@ import * as xlsl from "xlsx";
import { FileAccess, ModeFlags } from "tiny/io"; import { FileAccess, ModeFlags } from "tiny/io";
import * as colors from "colors"; import * as colors from "colors";
export enum Keywords {
SKIP = '@skip',
FIELD = '@field',
COMMENT = '@comment'
}
const SKIP_WORDS = [ Keywords.SKIP, Keywords.FIELD, Keywords.COMMENT ];
export enum DataType {
null = 'null',
int = 'int',
bool = 'bool',
float = 'float',
string = 'string',
struct = 'struct',
}
interface RawTableCell extends xlsl.CellObject { interface RawTableCell extends xlsl.CellObject {
/** Column number */ /** Column number */
column: number; column: number;
@@ -12,21 +30,12 @@ interface RawTableCell extends xlsl.CellObject {
type RawTableData = RawTableCell[][]; type RawTableData = RawTableCell[][];
export interface ParserConfigs { export interface ParserConfigs {
/** 第一作为注释 */ /** 第一作为ID */
first_row_as_field_comment: boolean; first_column_as_id: boolean;
/** 固定数组长度的表名称 */ /** 固定数组长度的表名称 */
constant_array_length: string[]; constant_array_length: string[];
} }
export enum DataType {
null = 'null',
int = 'int',
bool = 'bool',
float = 'float',
string = 'string',
struct = 'struct',
}
export class Field { export class Field {
static readonly TYPE_ORDER = [ DataType.struct, DataType.string, DataType.float, DataType.int, DataType.bool, DataType.null ]; static readonly TYPE_ORDER = [ DataType.struct, DataType.string, DataType.float, DataType.int, DataType.bool, DataType.null ];
@@ -120,7 +129,12 @@ export class Field {
/** 解析一条数据 */ /** 解析一条数据 */
public parse_row(row: RawTableCell[]) { public parse_row(row: RawTableCell[]) {
if (this.type != DataType.struct) { if (this.type != DataType.struct) {
return this.get_cell_value(row[this.columns.start], this.type); const cell = row[this.columns.start];
let value = this.get_cell_value(cell, this.type);
if (this.is_array && !this.constant_array_length && (!cell || cell.t === 'z')) {
value = null;
}
return value;
} else if (this.children && this.children.length) { } else if (this.children && this.children.length) {
let obj = {}; let obj = {};
let isAllNullish = true; let isAllNullish = true;
@@ -177,14 +191,6 @@ export interface TableData {
data: {[key: string]: any}[]; data: {[key: string]: any}[];
} }
export enum Keywords {
SKIP = '@skip',
FIELD = '@feild',
COMMENT = '@comment'
}
const SKIP_WORDS = [ Keywords.SKIP, Keywords.FIELD, Keywords.COMMENT ];
export class TableParser { export class TableParser {
configs: ParserConfigs = null; configs: ParserConfigs = null;
@@ -244,13 +250,21 @@ export class TableParser {
const root = new Field(); const root = new Field();
root.name = name; root.name = name;
root.columns = { start: range.s.c, end: range.e.c }; root.columns = { start: range.s.c, end: range.e.c };
if (this.configs.first_column_as_id) {
let id = new Field();
id.name = 'id';
id.columns = { start: 0, end: 0 };
root.add_field(id);
}
const get_cell_range = (c: number, r: number): xlsl.Range => { const get_cell_range = (c: number, r: number): xlsl.Range => {
const merges = sheet['!merges'];
let ranges = new Map<number, xlsl.Range>(); let ranges = new Map<number, xlsl.Range>();
for (const m of merges) { const merges = sheet['!merges'];
if (c >= m.s.c && c <= m.e.c && r >= m.s.r && r <= m.e.r) { if (merges) {
ranges.set(Math.pow(m.s.c - c, 2) + Math.pow(m.s.r - r, 2), m); for (const m of merges) {
if (c >= m.s.c && c <= m.e.c && r >= m.s.r && r <= m.e.r) {
ranges.set(Math.pow(m.s.c - c, 2) + Math.pow(m.s.r - r, 2), m);
}
} }
} }
let range = ranges.get(Math.min( ...(ranges.keys()) )); let range = ranges.get(Math.min( ...(ranges.keys()) ));
@@ -266,12 +280,12 @@ export class TableParser {
for (let r = range.s.r; r <= range.e.r; r++) { for (let r = range.s.r; r <= range.e.r; r++) {
let R = xlsl.utils.encode_row(r); let R = xlsl.utils.encode_row(r);
let first = sheet[`${xlsl.utils.encode_col(range.s.c)}${R}`] as xlsl.CellObject; let first = sheet[`${xlsl.utils.encode_col(range.s.c)}${R}`] as xlsl.CellObject;
if (!first || first.t !== 's' || (first.v as string).trim() !== '@feild') { if (!first || first.t !== 's' || (first.v as string).trim() !== Keywords.FIELD) {
continue; continue;
} }
const upperROW = xlsl.utils.encode_row(r-1); const upperROW = xlsl.utils.encode_row(r-1);
const upper_first = sheet[`${xlsl.utils.encode_col(range.s.c)}${upperROW}`] as xlsl.CellObject; const upper_first = sheet[`${xlsl.utils.encode_col(range.s.c)}${upperROW}`] as xlsl.CellObject;
const has_comment = upper_first && upper_first.t === 's' && (upper_first.v as string).trim() === '@comment'; const has_comment = upper_first && upper_first.t === 's' && (upper_first.v as string).trim() === Keywords.COMMENT;
for (let c = range.s.c + 1; c <= range.e.c; c++) { for (let c = range.s.c + 1; c <= range.e.c; c++) {
const C = xlsl.utils.encode_col(c); const C = xlsl.utils.encode_col(c);