From 5898db4150392f41d6bd015c22b43f93e25cf771 Mon Sep 17 00:00:00 2001 From: A-M-A-X Date: Wed, 2 Aug 2023 18:04:38 +0200 Subject: [PATCH 1/8] initial commit. Test model ran successful. Propper error handling etc. missing. Lint still failing due to cycle dependendies + type any warning. --- .../src/lib/debugging/debug-log-visitor.ts | 5 + .../execution/src/lib/types/io-types/index.ts | 1 + .../types/io-types/io-type-implementation.ts | 2 + .../execution/src/lib/types/io-types/sheet.ts | 6 +- .../src/lib/types/io-types/workbook.ts | 46 +++++ libs/extensions/tabular/exec/src/extension.ts | 4 + .../exec/src/lib/sheet-picker-executor.ts | 42 +++++ .../exec/src/lib/xlsx-interpreter-executor.ts | 54 ++++++ libs/extensions/tabular/lang/src/extension.ts | 4 + .../lang/src/lib/sheet-picker-meta-inf.ts | 51 ++++++ .../lang/src/lib/xlsx-interpreter-meta-inf.ts | 69 ++++++++ .../language-server/src/lib/ast/model-util.ts | 1 + package-lock.json | 158 +++++++++++++++++- package.json | 3 +- 14 files changed, 443 insertions(+), 3 deletions(-) create mode 100644 libs/execution/src/lib/types/io-types/workbook.ts create mode 100644 libs/extensions/tabular/exec/src/lib/sheet-picker-executor.ts create mode 100644 libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts create mode 100644 libs/extensions/tabular/lang/src/lib/sheet-picker-meta-inf.ts create mode 100644 libs/extensions/tabular/lang/src/lib/xlsx-interpreter-meta-inf.ts diff --git a/libs/execution/src/lib/debugging/debug-log-visitor.ts b/libs/execution/src/lib/debugging/debug-log-visitor.ts index 44141b16d..80e27bcde 100644 --- a/libs/execution/src/lib/debugging/debug-log-visitor.ts +++ b/libs/execution/src/lib/debugging/debug-log-visitor.ts @@ -5,6 +5,7 @@ import { internalValueToString } from '@jvalue/jayvee-language-server'; import { Logger } from '../logger'; +import { Workbook } from '../types'; import { FileSystem } from '../types/io-types/filesystem'; import { BinaryFile } from '../types/io-types/filesystem-node-file-binary'; import { TextFile } from '../types/io-types/filesystem-node-file-text'; @@ -134,6 +135,10 @@ export class DebugLogVisitor implements IoTypeVisitor { this.log('... (omitted in peek mode)'); } + visitWorkbook(workbook: Workbook): void { + this.log('visited Workbook'); + workbook.acceptVisitor(this); + } private log(text: string): void { this.logger.logDebug(`[${this.logPrefix}] ${text}`); diff --git a/libs/execution/src/lib/types/io-types/index.ts b/libs/execution/src/lib/types/io-types/index.ts index fd270c9a1..c4d8d7deb 100644 --- a/libs/execution/src/lib/types/io-types/index.ts +++ b/libs/execution/src/lib/types/io-types/index.ts @@ -6,6 +6,7 @@ export * from './filesystem'; export * from './filesystem-inmemory'; export * from './io-type-implementation'; export * from './none'; +export * from './workbook'; export * from './sheet'; export * from './table'; export * from './filesystem-node-file-binary'; diff --git a/libs/execution/src/lib/types/io-types/io-type-implementation.ts b/libs/execution/src/lib/types/io-types/io-type-implementation.ts index 7f27edac4..c13df9605 100644 --- a/libs/execution/src/lib/types/io-types/io-type-implementation.ts +++ b/libs/execution/src/lib/types/io-types/io-type-implementation.ts @@ -10,6 +10,7 @@ import { type TextFile } from './filesystem-node-file-text'; import { type None } from './none'; import { type Sheet } from './sheet'; import { type Table } from './table'; +import { Workbook } from './workbook'; export interface IOTypeImplementation { ioType: T; @@ -20,6 +21,7 @@ export interface IOTypeImplementation { export interface IoTypeVisitor { visitTable(table: Table): R; visitSheet(sheet: Sheet): R; + visitWorkbook(workbook: Workbook): R; visitNone(none: None): R; visitFileSystem(fileSystem: FileSystem): R; visitBinaryFile(binaryFile: BinaryFile): R; diff --git a/libs/execution/src/lib/types/io-types/sheet.ts b/libs/execution/src/lib/types/io-types/sheet.ts index 662709621..b3a869b55 100644 --- a/libs/execution/src/lib/types/io-types/sheet.ts +++ b/libs/execution/src/lib/types/io-types/sheet.ts @@ -22,13 +22,17 @@ export class Sheet implements IOTypeImplementation { public readonly ioType = IOType.SHEET; private numberOfRows: number; private numberOfColumns: number; - constructor(private data: string[][]) { + constructor(private data: string[][], private sheetName?: string) { this.numberOfRows = data.length; this.numberOfColumns = data.reduce((prev, curr) => { return curr.length > prev ? curr.length : prev; }, 0); } + getSheetName(): string | undefined { + return this.sheetName; + } + getData(): ReadonlyArray> { return this.data; } diff --git a/libs/execution/src/lib/types/io-types/workbook.ts b/libs/execution/src/lib/types/io-types/workbook.ts new file mode 100644 index 000000000..bff2d51fb --- /dev/null +++ b/libs/execution/src/lib/types/io-types/workbook.ts @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +import { strict as assert } from 'assert'; + +import { IOType } from '@jvalue/jayvee-language-server'; + +import { IOTypeImplementation, IoTypeVisitor } from './io-type-implementation'; +import { Sheet } from './sheet'; + +export class Workbook implements IOTypeImplementation { + public readonly ioType = IOType.WORKBOOK; + private numberOfWorksheets: number; + constructor(private sheets: Sheet[]) { + this.numberOfWorksheets = sheets.length; + } + + getSheets(): ReadonlyArray { + return this.sheets; + } + + getSheetByName(sheetName: string): Sheet { + const sheet = this.sheets.filter( + (sheet) => sheet.getSheetName() === sheetName, + )[0]; + assert(sheet instanceof Sheet); + return sheet; + /* return Array.prototype.filter.call(this.sheets, sheet => { + if(sheet.getSheetName() ==sheetName) return sheetName; + else return null; + })[0];*/ + } + + getNumberOfWorkbooks(): number { + return this.numberOfWorksheets; + } + + clone(): Workbook { + return new Workbook(structuredClone(this.sheets)); + } + + acceptVisitor(visitor: IoTypeVisitor): R { + return visitor.visitWorkbook(this); + } +} diff --git a/libs/extensions/tabular/exec/src/extension.ts b/libs/extensions/tabular/exec/src/extension.ts index 680fb41ff..80746ca92 100644 --- a/libs/extensions/tabular/exec/src/extension.ts +++ b/libs/extensions/tabular/exec/src/extension.ts @@ -12,8 +12,10 @@ import { CellWriterExecutor } from './lib/cell-writer-executor'; import { ColumnDeleterExecutor } from './lib/column-deleter-executor'; import { CSVInterpreterExecutor } from './lib/csv-interpreter-executor'; import { RowDeleterExecutor } from './lib/row-deleter-executor'; +import { SheetPickerExecutor } from './lib/sheet-picker-executor'; import { TableInterpreterExecutor } from './lib/table-interpreter-executor'; import { TableTransformerExecutor } from './lib/table-transformer-executor'; +import { XLSXInterpreterExecutor } from './lib/xlsx-interpreter-executor'; export class TabularExecExtension implements JayveeExecExtension { getBlockExecutors(): BlockExecutorClass[] { @@ -25,6 +27,8 @@ export class TabularExecExtension implements JayveeExecExtension { TableInterpreterExecutor, CSVInterpreterExecutor, TableTransformerExecutor, + XLSXInterpreterExecutor, + SheetPickerExecutor, ]; } } diff --git a/libs/extensions/tabular/exec/src/lib/sheet-picker-executor.ts b/libs/extensions/tabular/exec/src/lib/sheet-picker-executor.ts new file mode 100644 index 000000000..b6e16d10d --- /dev/null +++ b/libs/extensions/tabular/exec/src/lib/sheet-picker-executor.ts @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +import { strict as assert } from 'assert'; + +import * as R from '@jvalue/jayvee-execution'; +import { + AbstractBlockExecutor, + BlockExecutorClass, + ExecutionContext, + Sheet, + Workbook, + implementsStatic, +} from '@jvalue/jayvee-execution'; +import { IOType, PrimitiveValuetypes } from '@jvalue/jayvee-language-server'; + +@implementsStatic() +export class SheetPickerExecutor extends AbstractBlockExecutor< + IOType.WORKBOOK, + IOType.SHEET +> { + public static readonly type = 'SheetPicker'; + + constructor() { + super(IOType.WORKBOOK, IOType.SHEET); + } + + // eslint-disable-next-line @typescript-eslint/require-await + async doExecute( + workbook: Workbook, + context: ExecutionContext, + ): Promise> { + const sheetName = context.getPropertyValue( + 'sheetName', + PrimitiveValuetypes.Text, + ); + const sheet = workbook.getSheetByName(sheetName); + assert(sheet instanceof Sheet); + return R.ok(sheet); + } +} diff --git a/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts b/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts new file mode 100644 index 000000000..9c853d4fc --- /dev/null +++ b/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts @@ -0,0 +1,54 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +import { strict as assert } from 'assert'; + +import * as R from '@jvalue/jayvee-execution'; +import { + AbstractBlockExecutor, + BinaryFile, + BlockExecutorClass, + ExecutionContext, + Sheet, + Workbook, + implementsStatic, +} from '@jvalue/jayvee-execution'; +import { IOType } from '@jvalue/jayvee-language-server'; +import * as xlsx from 'xlsx'; + +@implementsStatic() +export class XLSXInterpreterExecutor extends AbstractBlockExecutor< + IOType.FILE, + IOType.WORKBOOK +> { + public static readonly type = 'XLSXInterpreter'; + + constructor() { + super(IOType.FILE, IOType.WORKBOOK); + } + + async doExecute( + file: BinaryFile, + context: ExecutionContext, + ): Promise> { + context.logger.logDebug(`reading from xlsx file`); + const workSheetsFromFile = xlsx.read(file.content, { dense: true }); + const wsName = workSheetsFromFile.SheetNames[0] ?? ''; + const ws = workSheetsFromFile.Sheets[wsName]; + assert(ws instanceof Sheet); + + const wsAA = Array.prototype.map.call( + ws, + (x: xlsx.CellObject[]): string[] => { + return x.map((y: xlsx.CellObject) => { + return y.v?.toString() ?? ''; + }); + }, + ); + const currentSheet = new Sheet(wsAA, wsName); + const wb = new Workbook([currentSheet]); + + return Promise.resolve(R.ok(wb)); + } +} diff --git a/libs/extensions/tabular/lang/src/extension.ts b/libs/extensions/tabular/lang/src/extension.ts index f2b9f1a1f..959be5362 100644 --- a/libs/extensions/tabular/lang/src/extension.ts +++ b/libs/extensions/tabular/lang/src/extension.ts @@ -13,8 +13,10 @@ import { CellWriterMetaInformation } from './lib/cell-writer-meta-inf'; import { ColumnDeleterMetaInformation } from './lib/column-deleter-meta-inf'; import { CSVInterpreterMetaInformation } from './lib/csv-interpreter-meta-inf'; import { RowDeleterMetaInformation } from './lib/row-deleter-meta-inf'; +import { SheetPickerMetaInformation } from './lib/sheet-picker-meta-inf'; import { TableInterpreterMetaInformation } from './lib/table-interpreter-meta-inf'; import { TableTransformerMetaInformation } from './lib/table-transformer-meta-inf'; +import { XLSXInterpreterMetaInformation } from './lib/xlsx-interpreter-meta-inf'; export class TabularLangExtension implements JayveeLangExtension { getBlockMetaInf(): Array> { @@ -26,6 +28,8 @@ export class TabularLangExtension implements JayveeLangExtension { TableInterpreterMetaInformation, CSVInterpreterMetaInformation, TableTransformerMetaInformation, + XLSXInterpreterMetaInformation, + SheetPickerMetaInformation, ]; } } diff --git a/libs/extensions/tabular/lang/src/lib/sheet-picker-meta-inf.ts b/libs/extensions/tabular/lang/src/lib/sheet-picker-meta-inf.ts new file mode 100644 index 000000000..8da81146b --- /dev/null +++ b/libs/extensions/tabular/lang/src/lib/sheet-picker-meta-inf.ts @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +import { + BlockMetaInformation, + IOType, + PrimitiveValuetypes, +} from '@jvalue/jayvee-language-server'; + +export class SheetPickerMetaInformation extends BlockMetaInformation { + constructor() { + super( + // How the block type should be called: + 'SheetPicker', + + // Property definitions: + { + sheetName: { + type: PrimitiveValuetypes.Text, + docs: { + description: 'The name of the sheet to select.', + }, + }, + sheetNumber: { + type: PrimitiveValuetypes.Integer, + docs: { + description: 'The number of the sheet to select.', + }, + }, + }, + // Input type: + IOType.WORKBOOK, + + // Output type: + IOType.SHEET, + ); + + this.docs.description = + 'Selects one `Sheet` from a `xlsx-File` based on its `name`. If no sheet matches the relative path, no output is created and the execution of the pipeline is aborted.'; + this.docs.examples = [ + { + code: `block AgencySheetPicker oftype SheetPicker { + sheetName: "AgencyNames"; +}`, + description: + 'Tries to pick the sheet `AgencyNames` from the provided `Workbook`. If `AgencyNames` exists it is passed on as `Sheet`, if it does not exist the execution of the pipeline is aborted.', + }, + ]; + } +} diff --git a/libs/extensions/tabular/lang/src/lib/xlsx-interpreter-meta-inf.ts b/libs/extensions/tabular/lang/src/lib/xlsx-interpreter-meta-inf.ts new file mode 100644 index 000000000..584ee673d --- /dev/null +++ b/libs/extensions/tabular/lang/src/lib/xlsx-interpreter-meta-inf.ts @@ -0,0 +1,69 @@ +// SPDX-FileCopyrightText: 2023 Friedrich-Alexander-Universitat Erlangen-Nurnberg +// +// SPDX-License-Identifier: AGPL-3.0-only + +import { + BlockMetaInformation, + IOType, + PrimitiveValuetypes, +} from '@jvalue/jayvee-language-server'; + +export class XLSXInterpreterMetaInformation extends BlockMetaInformation { + constructor() { + super( + // How the block type should be called: + 'XLSXInterpreter', + // Property definitions: + { + delimiter: { + type: PrimitiveValuetypes.Text, + defaultValue: ',', + docs: { + description: 'The delimiter for values in the CSV file.', + examples: [ + { + code: 'delimiter: ","', + description: + 'Commas are used to separate values in the CSV file.', + }, + ], + }, + }, + enclosing: { + type: PrimitiveValuetypes.Text, + defaultValue: '', + docs: { + description: + 'The enclosing character that may be used for values in the CSV file.', + }, + }, + enclosingEscape: { + type: PrimitiveValuetypes.Text, + defaultValue: '', + docs: { + description: + 'The character to escape enclosing characters in values.', + }, + }, + }, + // Input type: + IOType.FILE, + + // Output type: + IOType.WORKBOOK, + ); + + this.docs.description = + 'Interprets an input file as a csv-file containing string-values delimited by `delimiter` and outputs a `Sheet`.'; + this.docs.examples = [ + { + code: blockExample, + description: + 'Interprets an input file as a csv-file containing string-values delimited by `;` and outputs `Sheet`.', + }, + ]; + } +} +const blockExample = `block AgencyXLSXInterpreter oftype XLSXInterpreter { + delimiter: ";"; + }`; diff --git a/libs/language-server/src/lib/ast/model-util.ts b/libs/language-server/src/lib/ast/model-util.ts index 9dc2a3467..ff748af05 100644 --- a/libs/language-server/src/lib/ast/model-util.ts +++ b/libs/language-server/src/lib/ast/model-util.ts @@ -145,6 +145,7 @@ export enum IOType { TEXT_FILE = 'TextFile', FILE_SYSTEM = 'FileSystem', SHEET = 'Sheet', + WORKBOOK = 'Workbook', TABLE = 'Table', } diff --git a/package-lock.json b/package-lock.json index 0dbfeda59..eb3400c54 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,7 +35,8 @@ "vscode-languageclient": "^8.0.2", "vscode-languageserver": "^8.0.2", "vscode-languageserver-protocol": "^3.17.2", - "vscode-uri": "^3.0.2" + "vscode-uri": "^3.0.2", + "xlsx": "^0.18.5" }, "devDependencies": { "@babel/preset-react": "^7.14.5", @@ -7133,6 +7134,14 @@ "node": ">= 10.0.0" } }, + "node_modules/adler-32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", + "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -8439,6 +8448,18 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/cfb": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", + "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", + "dependencies": { + "adler-32": "~1.3.0", + "crc-32": "~1.2.0" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -8877,6 +8898,14 @@ "node": ">= 0.12.0" } }, + "node_modules/codepage": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", + "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/collapse-white-space": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", @@ -9285,6 +9314,17 @@ "node": ">=10" } }, + "node_modules/crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "bin": { + "crc32": "bin/crc32.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -12743,6 +12783,14 @@ "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.13.1.tgz", "integrity": "sha512-0eu5ULPS2c/jsa1lGFneEFFEdTbembJv8e4QKXeVJ3lm/5hyve06dlKZrpxmMwJt6rYen7sxmHHK2CLaXvWuWQ==" }, + "node_modules/frac": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", + "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/fraction.js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", @@ -21799,6 +21847,17 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" }, + "node_modules/ssf": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", + "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", + "dependencies": { + "frac": "~1.1.2" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/ssri": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", @@ -24294,6 +24353,22 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" }, + "node_modules/wmf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", + "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/word": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", + "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==", + "engines": { + "node": ">=0.8" + } + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -24364,6 +24439,26 @@ "node": ">=8" } }, + "node_modules/xlsx": { + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", + "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", + "dependencies": { + "adler-32": "~1.3.0", + "cfb": "~1.2.1", + "codepage": "~1.15.0", + "crc-32": "~1.2.1", + "ssf": "~0.11.2", + "wmf": "~1.0.1", + "word": "~0.3.0" + }, + "bin": { + "xlsx": "bin/xlsx.njs" + }, + "engines": { + "node": ">=0.8" + } + }, "node_modules/xml-js": { "version": "1.6.11", "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", @@ -29816,6 +29911,11 @@ "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==" }, + "adler-32": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz", + "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==" + }, "agent-base": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", @@ -30788,6 +30888,15 @@ "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==" }, + "cfb": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz", + "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==", + "requires": { + "adler-32": "~1.3.0", + "crc-32": "~1.2.0" + } + }, "chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -31100,6 +31209,11 @@ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true }, + "codepage": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz", + "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==" + }, "collapse-white-space": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", @@ -31417,6 +31531,11 @@ "yaml": "^1.10.0" } }, + "crc-32": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", + "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==" + }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -33876,6 +33995,11 @@ "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-2.13.1.tgz", "integrity": "sha512-0eu5ULPS2c/jsa1lGFneEFFEdTbembJv8e4QKXeVJ3lm/5hyve06dlKZrpxmMwJt6rYen7sxmHHK2CLaXvWuWQ==" }, + "frac": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz", + "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==" + }, "fraction.js": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", @@ -40596,6 +40720,14 @@ } } }, + "ssf": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz", + "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==", + "requires": { + "frac": "~1.1.2" + } + }, "ssri": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", @@ -42347,6 +42479,16 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==" }, + "wmf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz", + "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==" + }, + "word": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz", + "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==" + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -42387,6 +42529,20 @@ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==" }, + "xlsx": { + "version": "0.18.5", + "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz", + "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==", + "requires": { + "adler-32": "~1.3.0", + "cfb": "~1.2.1", + "codepage": "~1.15.0", + "crc-32": "~1.2.1", + "ssf": "~0.11.2", + "wmf": "~1.0.1", + "word": "~0.3.0" + } + }, "xml-js": { "version": "1.6.11", "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", diff --git a/package.json b/package.json index 1edf42734..9cc2a5b88 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "vscode-languageclient": "^8.0.2", "vscode-languageserver": "^8.0.2", "vscode-languageserver-protocol": "^3.17.2", - "vscode-uri": "^3.0.2" + "vscode-uri": "^3.0.2", + "xlsx": "^0.18.5" }, "devDependencies": { "@babel/preset-react": "^7.14.5", From a74a470bde372cbbafc2eb98d632d4d0efd9471e Mon Sep 17 00:00:00 2001 From: A-M-A-X Date: Thu, 3 Aug 2023 14:44:36 +0200 Subject: [PATCH 2/8] fixed lint warnings/errors fixed missing sheets on xlsx import of wb --- .../src/lib/debugging/debug-log-visitor.ts | 6 ++-- .../types/io-types/io-type-implementation.ts | 2 +- .../execution/src/lib/types/io-types/sheet.ts | 4 +-- .../src/lib/types/io-types/workbook.ts | 19 +++++------ .../exec/src/lib/xlsx-interpreter-executor.ts | 34 +++++++++++-------- 5 files changed, 35 insertions(+), 30 deletions(-) diff --git a/libs/execution/src/lib/debugging/debug-log-visitor.ts b/libs/execution/src/lib/debugging/debug-log-visitor.ts index 80e27bcde..862cbd772 100644 --- a/libs/execution/src/lib/debugging/debug-log-visitor.ts +++ b/libs/execution/src/lib/debugging/debug-log-visitor.ts @@ -136,8 +136,10 @@ export class DebugLogVisitor implements IoTypeVisitor { this.log('... (omitted in peek mode)'); } visitWorkbook(workbook: Workbook): void { - this.log('visited Workbook'); - workbook.acceptVisitor(this); + this.log(`WorkSheets in WorkBook:`); + workbook + .getSheets() + .forEach((sheet) => console.log(`WorkSheet: ${sheet.getSheetName()}`)); } private log(text: string): void { diff --git a/libs/execution/src/lib/types/io-types/io-type-implementation.ts b/libs/execution/src/lib/types/io-types/io-type-implementation.ts index c13df9605..e769f7ed2 100644 --- a/libs/execution/src/lib/types/io-types/io-type-implementation.ts +++ b/libs/execution/src/lib/types/io-types/io-type-implementation.ts @@ -10,7 +10,7 @@ import { type TextFile } from './filesystem-node-file-text'; import { type None } from './none'; import { type Sheet } from './sheet'; import { type Table } from './table'; -import { Workbook } from './workbook'; +import { type Workbook } from './workbook'; export interface IOTypeImplementation { ioType: T; diff --git a/libs/execution/src/lib/types/io-types/sheet.ts b/libs/execution/src/lib/types/io-types/sheet.ts index b3a869b55..4e2c4636a 100644 --- a/libs/execution/src/lib/types/io-types/sheet.ts +++ b/libs/execution/src/lib/types/io-types/sheet.ts @@ -29,8 +29,8 @@ export class Sheet implements IOTypeImplementation { }, 0); } - getSheetName(): string | undefined { - return this.sheetName; + getSheetName(): string { + return this.sheetName ?? 'Sheet has no Name'; } getData(): ReadonlyArray> { diff --git a/libs/execution/src/lib/types/io-types/workbook.ts b/libs/execution/src/lib/types/io-types/workbook.ts index bff2d51fb..9a2a06ed6 100644 --- a/libs/execution/src/lib/types/io-types/workbook.ts +++ b/libs/execution/src/lib/types/io-types/workbook.ts @@ -11,9 +11,9 @@ import { Sheet } from './sheet'; export class Workbook implements IOTypeImplementation { public readonly ioType = IOType.WORKBOOK; - private numberOfWorksheets: number; - constructor(private sheets: Sheet[]) { - this.numberOfWorksheets = sheets.length; + private sheets: Sheet[]; + constructor() { + this.sheets = []; } getSheets(): ReadonlyArray { @@ -26,18 +26,15 @@ export class Workbook implements IOTypeImplementation { )[0]; assert(sheet instanceof Sheet); return sheet; - /* return Array.prototype.filter.call(this.sheets, sheet => { - if(sheet.getSheetName() ==sheetName) return sheetName; - else return null; - })[0];*/ } - getNumberOfWorkbooks(): number { - return this.numberOfWorksheets; + addSheet(sheet: Sheet) { + this.sheets.push(sheet); } - clone(): Workbook { - return new Workbook(structuredClone(this.sheets)); + addNewSheet(data: string[][], sheetName?: string) { + const sheetNameOrDefault = sheetName ?? `Sheet${this.sheets.length + 1}`; + this.sheets.push(new Sheet(data, sheetNameOrDefault)); } acceptVisitor(visitor: IoTypeVisitor): R { diff --git a/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts b/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts index 9c853d4fc..be35fe36c 100644 --- a/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts +++ b/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts @@ -10,7 +10,6 @@ import { BinaryFile, BlockExecutorClass, ExecutionContext, - Sheet, Workbook, implementsStatic, } from '@jvalue/jayvee-execution'; @@ -33,22 +32,29 @@ export class XLSXInterpreterExecutor extends AbstractBlockExecutor< context: ExecutionContext, ): Promise> { context.logger.logDebug(`reading from xlsx file`); - const workSheetsFromFile = xlsx.read(file.content, { dense: true }); - const wsName = workSheetsFromFile.SheetNames[0] ?? ''; - const ws = workSheetsFromFile.Sheets[wsName]; - assert(ws instanceof Sheet); + const workBookFromFile = xlsx.read(file.content, { dense: true }); + const workbook = new Workbook(); + for (const workSheetName of workBookFromFile.SheetNames) { + const workSheet = workBookFromFile.Sheets[workSheetName]; + assert(workSheet !== undefined); - const wsAA = Array.prototype.map.call( - ws, - (x: xlsx.CellObject[]): string[] => { + const workSheetDataArray = Array.prototype.map.call< + xlsx.WorkSheet, + [ + callbackfn: ( + value: xlsx.CellObject[], + index: number, + array: xlsx.WorkSheet[], + ) => string[], + ], + string[][] + >(workSheet, (x: xlsx.CellObject[]): string[] => { return x.map((y: xlsx.CellObject) => { return y.v?.toString() ?? ''; }); - }, - ); - const currentSheet = new Sheet(wsAA, wsName); - const wb = new Workbook([currentSheet]); - - return Promise.resolve(R.ok(wb)); + }); + workbook.addNewSheet(workSheetDataArray, workSheetName); + } + return Promise.resolve(R.ok(workbook)); } } From bc9c93b0326886e339cbc4ff4fd3fa6706faf226 Mon Sep 17 00:00:00 2001 From: A-M-A-X Date: Thu, 10 Aug 2023 15:43:55 +0200 Subject: [PATCH 3/8] minor changes to xlsx and sheet meta file --- .../src/lib/types/io-types/workbook.ts | 2 +- .../lang/src/lib/sheet-picker-meta-inf.ts | 9 +--- .../lang/src/lib/xlsx-interpreter-meta-inf.ts | 44 ++----------------- 3 files changed, 6 insertions(+), 49 deletions(-) diff --git a/libs/execution/src/lib/types/io-types/workbook.ts b/libs/execution/src/lib/types/io-types/workbook.ts index 9a2a06ed6..3bd323e94 100644 --- a/libs/execution/src/lib/types/io-types/workbook.ts +++ b/libs/execution/src/lib/types/io-types/workbook.ts @@ -34,7 +34,7 @@ export class Workbook implements IOTypeImplementation { addNewSheet(data: string[][], sheetName?: string) { const sheetNameOrDefault = sheetName ?? `Sheet${this.sheets.length + 1}`; - this.sheets.push(new Sheet(data, sheetNameOrDefault)); + this.addSheet(new Sheet(data, sheetNameOrDefault)); } acceptVisitor(visitor: IoTypeVisitor): R { diff --git a/libs/extensions/tabular/lang/src/lib/sheet-picker-meta-inf.ts b/libs/extensions/tabular/lang/src/lib/sheet-picker-meta-inf.ts index 8da81146b..518560040 100644 --- a/libs/extensions/tabular/lang/src/lib/sheet-picker-meta-inf.ts +++ b/libs/extensions/tabular/lang/src/lib/sheet-picker-meta-inf.ts @@ -13,7 +13,6 @@ export class SheetPickerMetaInformation extends BlockMetaInformation { super( // How the block type should be called: 'SheetPicker', - // Property definitions: { sheetName: { @@ -22,12 +21,6 @@ export class SheetPickerMetaInformation extends BlockMetaInformation { description: 'The name of the sheet to select.', }, }, - sheetNumber: { - type: PrimitiveValuetypes.Integer, - docs: { - description: 'The number of the sheet to select.', - }, - }, }, // Input type: IOType.WORKBOOK, @@ -37,7 +30,7 @@ export class SheetPickerMetaInformation extends BlockMetaInformation { ); this.docs.description = - 'Selects one `Sheet` from a `xlsx-File` based on its `name`. If no sheet matches the relative path, no output is created and the execution of the pipeline is aborted.'; + 'Selects one `Sheet` from a `Workbook` based on its `sheetName`. If no sheet matches the name, no output is created and the execution of the pipeline is aborted.'; this.docs.examples = [ { code: `block AgencySheetPicker oftype SheetPicker { diff --git a/libs/extensions/tabular/lang/src/lib/xlsx-interpreter-meta-inf.ts b/libs/extensions/tabular/lang/src/lib/xlsx-interpreter-meta-inf.ts index 584ee673d..f3e2366e0 100644 --- a/libs/extensions/tabular/lang/src/lib/xlsx-interpreter-meta-inf.ts +++ b/libs/extensions/tabular/lang/src/lib/xlsx-interpreter-meta-inf.ts @@ -2,11 +2,7 @@ // // SPDX-License-Identifier: AGPL-3.0-only -import { - BlockMetaInformation, - IOType, - PrimitiveValuetypes, -} from '@jvalue/jayvee-language-server'; +import { BlockMetaInformation, IOType } from '@jvalue/jayvee-language-server'; export class XLSXInterpreterMetaInformation extends BlockMetaInformation { constructor() { @@ -14,38 +10,7 @@ export class XLSXInterpreterMetaInformation extends BlockMetaInformation { // How the block type should be called: 'XLSXInterpreter', // Property definitions: - { - delimiter: { - type: PrimitiveValuetypes.Text, - defaultValue: ',', - docs: { - description: 'The delimiter for values in the CSV file.', - examples: [ - { - code: 'delimiter: ","', - description: - 'Commas are used to separate values in the CSV file.', - }, - ], - }, - }, - enclosing: { - type: PrimitiveValuetypes.Text, - defaultValue: '', - docs: { - description: - 'The enclosing character that may be used for values in the CSV file.', - }, - }, - enclosingEscape: { - type: PrimitiveValuetypes.Text, - defaultValue: '', - docs: { - description: - 'The character to escape enclosing characters in values.', - }, - }, - }, + {}, // Input type: IOType.FILE, @@ -54,16 +19,15 @@ export class XLSXInterpreterMetaInformation extends BlockMetaInformation { ); this.docs.description = - 'Interprets an input file as a csv-file containing string-values delimited by `delimiter` and outputs a `Sheet`.'; + "Interprets an input file as a xlsx-file and outputs a `Workbook` containing `Sheet`'s."; this.docs.examples = [ { code: blockExample, description: - 'Interprets an input file as a csv-file containing string-values delimited by `;` and outputs `Sheet`.', + "Interprets an input file as a xlsx-file and outputs a `Workbook` containing `Sheet`'s.", }, ]; } } const blockExample = `block AgencyXLSXInterpreter oftype XLSXInterpreter { - delimiter: ";"; }`; From 4d82690827da90b7f24cb12de86b7df8d3f8575e Mon Sep 17 00:00:00 2001 From: A-M-A-X Date: Thu, 10 Aug 2023 16:07:33 +0200 Subject: [PATCH 4/8] minor change --- libs/execution/src/lib/types/io-types/sheet.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/execution/src/lib/types/io-types/sheet.ts b/libs/execution/src/lib/types/io-types/sheet.ts index 4e2c4636a..b3a869b55 100644 --- a/libs/execution/src/lib/types/io-types/sheet.ts +++ b/libs/execution/src/lib/types/io-types/sheet.ts @@ -29,8 +29,8 @@ export class Sheet implements IOTypeImplementation { }, 0); } - getSheetName(): string { - return this.sheetName ?? 'Sheet has no Name'; + getSheetName(): string | undefined { + return this.sheetName; } getData(): ReadonlyArray> { From fd5c19f319744dfc11172e0bc7076472476041f3 Mon Sep 17 00:00:00 2001 From: A-M-A-X Date: Thu, 10 Aug 2023 16:31:34 +0200 Subject: [PATCH 5/8] fixed lint error --- libs/execution/src/lib/types/io-types/sheet.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/execution/src/lib/types/io-types/sheet.ts b/libs/execution/src/lib/types/io-types/sheet.ts index b3a869b55..f294bbbc2 100644 --- a/libs/execution/src/lib/types/io-types/sheet.ts +++ b/libs/execution/src/lib/types/io-types/sheet.ts @@ -29,8 +29,8 @@ export class Sheet implements IOTypeImplementation { }, 0); } - getSheetName(): string | undefined { - return this.sheetName; + getSheetName(): string { + return this.sheetName ?? ''; } getData(): ReadonlyArray> { From 0abeb51bacbc4f04e3af8dd08cc76e78e9bc443d Mon Sep 17 00:00:00 2001 From: A-M-A-X Date: Mon, 14 Aug 2023 13:42:15 +0200 Subject: [PATCH 6/8] added first feedback from PR --- libs/execution/src/lib/types/io-types/workbook.ts | 4 ++++ .../tabular/exec/src/lib/sheet-picker-executor.ts | 3 --- .../tabular/exec/src/lib/xlsx-interpreter-executor.ts | 7 ++++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libs/execution/src/lib/types/io-types/workbook.ts b/libs/execution/src/lib/types/io-types/workbook.ts index 3bd323e94..404567631 100644 --- a/libs/execution/src/lib/types/io-types/workbook.ts +++ b/libs/execution/src/lib/types/io-types/workbook.ts @@ -34,6 +34,10 @@ export class Workbook implements IOTypeImplementation { addNewSheet(data: string[][], sheetName?: string) { const sheetNameOrDefault = sheetName ?? `Sheet${this.sheets.length + 1}`; + if ( + this.sheets.some((sheet) => sheet.getSheetName() === sheetNameOrDefault) + ) + return; this.addSheet(new Sheet(data, sheetNameOrDefault)); } diff --git a/libs/extensions/tabular/exec/src/lib/sheet-picker-executor.ts b/libs/extensions/tabular/exec/src/lib/sheet-picker-executor.ts index b6e16d10d..f6a167ab2 100644 --- a/libs/extensions/tabular/exec/src/lib/sheet-picker-executor.ts +++ b/libs/extensions/tabular/exec/src/lib/sheet-picker-executor.ts @@ -2,8 +2,6 @@ // // SPDX-License-Identifier: AGPL-3.0-only -import { strict as assert } from 'assert'; - import * as R from '@jvalue/jayvee-execution'; import { AbstractBlockExecutor, @@ -36,7 +34,6 @@ export class SheetPickerExecutor extends AbstractBlockExecutor< PrimitiveValuetypes.Text, ); const sheet = workbook.getSheetByName(sheetName); - assert(sheet instanceof Sheet); return R.ok(sheet); } } diff --git a/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts b/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts index be35fe36c..72186e150 100644 --- a/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts +++ b/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts @@ -48,11 +48,12 @@ export class XLSXInterpreterExecutor extends AbstractBlockExecutor< ) => string[], ], string[][] - >(workSheet, (x: xlsx.CellObject[]): string[] => { - return x.map((y: xlsx.CellObject) => { - return y.v?.toString() ?? ''; + >(workSheet, (row: xlsx.CellObject[]): string[] => { + return row.map((cell: xlsx.CellObject) => { + return cell.v?.toString() ?? ''; }); }); + workbook.addNewSheet(workSheetDataArray, workSheetName); } return Promise.resolve(R.ok(workbook)); From f1f0a5cd5b16be9e92f0da0fcc32d1a977f5428e Mon Sep 17 00:00:00 2001 From: A-M-A-X Date: Mon, 14 Aug 2023 13:44:52 +0200 Subject: [PATCH 7/8] . --- .../tabular/exec/src/lib/xlsx-interpreter-executor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts b/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts index 72186e150..1e3836797 100644 --- a/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts +++ b/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts @@ -53,7 +53,7 @@ export class XLSXInterpreterExecutor extends AbstractBlockExecutor< return cell.v?.toString() ?? ''; }); }); - + workbook.addNewSheet(workSheetDataArray, workSheetName); } return Promise.resolve(R.ok(workbook)); From a7898a2cbe395eefb577e3ac94087d52fe3c2fec Mon Sep 17 00:00:00 2001 From: A-M-A-X Date: Mon, 14 Aug 2023 14:25:51 +0200 Subject: [PATCH 8/8] formatted code --- .../tabular/exec/src/lib/xlsx-interpreter-executor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts b/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts index 1e3836797..72186e150 100644 --- a/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts +++ b/libs/extensions/tabular/exec/src/lib/xlsx-interpreter-executor.ts @@ -53,7 +53,7 @@ export class XLSXInterpreterExecutor extends AbstractBlockExecutor< return cell.v?.toString() ?? ''; }); }); - + workbook.addNewSheet(workSheetDataArray, workSheetName); } return Promise.resolve(R.ok(workbook));