Merge branch 'main' of http://43.140.215.244:7040/wangyukun/PRA-only-demo
This commit is contained in:
commit
aaa0f2c3c7
2 files changed
+44
-5
No files matched your search
@@ -31,4 +31,30 @@ describe("common Excel aliases", () => {
|
|||||||
await run("Excel_WriteCellNew", { workbook: handle, sheet: "Sheet1", row: 1, column: "A", content: "alias", save: "1" });
|
await run("Excel_WriteCellNew", { workbook: handle, sheet: "Sheet1", row: 1, column: "A", content: "alias", save: "1" });
|
||||||
await expect(run("Excel_ReadCellNew", { workbook: handle, sheet: "Sheet1", row: 1, column: "A" })).resolves.toBe("alias");
|
await expect(run("Excel_ReadCellNew", { workbook: handle, sheet: "Sheet1", row: 1, column: "A" })).resolves.toBe("alias");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("accepts the Excel_NewExcel catalog keys (filePath / isMakedirs)", async () => {
|
||||||
|
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-excel-new-")); dirs.push(directory);
|
||||||
|
const handle = await run("Excel_NewExcel", { filePath: directory, name: "catalog-keys.xlsx", isMakedirs: "True" }) as { path: string };
|
||||||
|
expect(handle.path).toBe(path.resolve(directory, "catalog-keys.xlsx"));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects a missing directory when isMakedirs is False", async () => {
|
||||||
|
const directory = path.join(await mkdtemp(path.join(os.tmpdir(), "rpa-excel-new-")), "missing");
|
||||||
|
dirs.push(directory);
|
||||||
|
await expect(run("Excel_NewExcel", { filePath: directory, name: "none.xlsx", isMakedirs: "False" })).rejects.toThrow("目录不存在");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("opens a workbook through the Excel_OpenExcel filePath key", async () => {
|
||||||
|
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-excel-open-")); dirs.push(directory);
|
||||||
|
const created = await run("Excel_NewExcel", { filePath: directory, name: "open-me.xlsx" }) as { path: string };
|
||||||
|
await expect(run("Excel_OpenExcel", { filePath: created.path })).resolves.toMatchObject({ path: created.path });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("writes a range through the Excel_WriteRange catalog keys (objExcel/cellPos/data/isSave)", async () => {
|
||||||
|
const directory = await mkdtemp(path.join(os.tmpdir(), "rpa-excel-range-")); dirs.push(directory);
|
||||||
|
const created = await run("Excel_NewExcel", { filePath: directory, name: "range.xlsx" }) as { path: string };
|
||||||
|
await run("Excel_WriteRange", { objExcel: created, sheet: "Sheet1", cellPos: "B2", data: [[1, "壹"], [2, "贰"]], isSave: "True" });
|
||||||
|
const reopened = await run("Excel_OpenExcel", { filePath: created.path }) as { id: string };
|
||||||
|
await expect(run("Excel_Cs_ReadContentV2", { workbook: reopened, sheet: "Sheet1", excelRng: "B2:C3" })).resolves.toEqual([[1, "壹"], [2, "贰"]]);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
@@ -24,6 +24,7 @@ function text(args: Record<string, unknown>, keys: string[], fallback = ""): str
|
|||||||
|
|
||||||
function bool(valueToRead: unknown, fallback = false): boolean {
|
function bool(valueToRead: unknown, fallback = false): boolean {
|
||||||
if (valueToRead === undefined || valueToRead === null || valueToRead === "") return fallback;
|
if (valueToRead === undefined || valueToRead === null || valueToRead === "") return fallback;
|
||||||
|
if (typeof valueToRead === "string") return ["true", "1", "yes", "是", "开启"].includes(valueToRead.trim().toLowerCase());
|
||||||
return [true, "true", "1", 1, "是", "开启"].includes(valueToRead as never);
|
return [true, "true", "1", 1, "是", "开启"].includes(valueToRead as never);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,9 +102,17 @@ function rowsFrom(valueToRead: unknown): unknown[][] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const newExcel: CapabilityHandler = async (_ctx, node, args) => {
|
const newExcel: CapabilityHandler = async (_ctx, node, args) => {
|
||||||
const folder = required(value(args, ["path", "folder"]), "Excel目录", node.id, node.componentId);
|
const folder = required(value(args, ["filePath", "path", "folder"]), "文件路径", node.id, node.componentId);
|
||||||
const name = text(args, ["name"], "新建工作簿.xlsx");
|
const name = text(args, ["name"], "新建工作簿.xlsx");
|
||||||
const filePath = path.resolve(folder, path.extname(name) ? name : `${name}.xlsx`);
|
const filePath = path.resolve(folder, path.extname(name) ? name : `${name}.xlsx`);
|
||||||
|
const makedirs = bool(value(args, ["isMakedirs"]), true);
|
||||||
|
if (!makedirs) {
|
||||||
|
try {
|
||||||
|
await fs.access(path.dirname(filePath));
|
||||||
|
} catch {
|
||||||
|
throw new RuntimeError("validation_error", `目录不存在:${path.dirname(filePath)}`, { nodeId: node.id, componentId: node.componentId, recommendation: "将「是否创建该路径」设为 True,或先创建目录" });
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!bool(value(args, ["override"]), true)) {
|
if (!bool(value(args, ["override"]), true)) {
|
||||||
try {
|
try {
|
||||||
await fs.access(filePath);
|
await fs.access(filePath);
|
||||||
@@ -120,7 +129,7 @@ const newExcel: CapabilityHandler = async (_ctx, node, args) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const openExcel: CapabilityHandler = async (_ctx, node, args) => {
|
const openExcel: CapabilityHandler = async (_ctx, node, args) => {
|
||||||
const filePath = required(value(args, ["file", "path"]), "Excel文件", node.id, node.componentId);
|
const filePath = required(value(args, ["file", "filePath", "path"]), "Excel文件", node.id, node.componentId);
|
||||||
const workbook = new ExcelJS.Workbook();
|
const workbook = new ExcelJS.Workbook();
|
||||||
await workbook.xlsx.readFile(path.resolve(filePath));
|
await workbook.xlsx.readFile(path.resolve(filePath));
|
||||||
return newHandle(path.resolve(filePath), workbook);
|
return newHandle(path.resolve(filePath), workbook);
|
||||||
@@ -144,14 +153,18 @@ const writeCell: CapabilityHandler = async (_ctx, node, args) => {
|
|||||||
const writeRange: CapabilityHandler = async (_ctx, node, args) => {
|
const writeRange: CapabilityHandler = async (_ctx, node, args) => {
|
||||||
const { handle, workbook } = await resolveWorkbook(args, node.id, node.componentId);
|
const { handle, workbook } = await resolveWorkbook(args, node.id, node.componentId);
|
||||||
const sheet = sheetOf(workbook, text(args, ["sheet", "sheetName"]));
|
const sheet = sheetOf(workbook, text(args, ["sheet", "sheetName"]));
|
||||||
const start = `${text(args, ["column"], "A")}${text(args, ["row"], "1")}`;
|
const cellPos = text(args, ["cellPos"]);
|
||||||
|
const cellMatch = cellPos.match(/^([A-Za-z]+)(\d+)$/);
|
||||||
|
const column = cellMatch ? cellMatch[1] : text(args, ["column"], "A");
|
||||||
|
const row = cellMatch ? cellMatch[2] : text(args, ["row"], "1");
|
||||||
|
const start = `${column}${row}`;
|
||||||
const startCell = sheet.getCell(start);
|
const startCell = sheet.getCell(start);
|
||||||
const startRow = startCell.row;
|
const startRow = startCell.row;
|
||||||
const startColumn = startCell.col;
|
const startColumn = startCell.col;
|
||||||
for (const [rowIndex, row] of rowsFrom(value(args, ["contents", "table"])).entries()) {
|
for (const [rowIndex, row] of rowsFrom(value(args, ["contents", "data", "table"])).entries()) {
|
||||||
for (const [columnIndex, cell] of row.entries()) sheet.getCell(startRow + rowIndex, startColumn + columnIndex).value = cell as ExcelJS.CellValue;
|
for (const [columnIndex, cell] of row.entries()) sheet.getCell(startRow + rowIndex, startColumn + columnIndex).value = cell as ExcelJS.CellValue;
|
||||||
}
|
}
|
||||||
if (bool(value(args, ["save"]), true)) await workbook.xlsx.writeFile(handle.path);
|
if (bool(value(args, ["save", "isSave"]), true)) await workbook.xlsx.writeFile(handle.path);
|
||||||
return handle;
|
return handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user