fix: 统一 Excel 工作簿共享存储,修复多组件互相覆盖
office.ts(内存句柄表)、office-file-extended.ts(每次重读磁盘)、 excel-common.ts(按路径独立缓存)、extended.ts(loadSheet 每次重建) 各自持有工作簿实例并整簿写回同一文件,后保存者会整体覆盖先保存者: 列宽/行高/合并被背景色冲掉、复制的 Sheet 被新建 Sheet 冲掉等。 - 新增 excel-store.ts:按路径共享同一 ExcelJS 实例,四个模块统一接入 - resolveWorkbook 返回流程变量持有的原始句柄对象,另存为改写 path 能同步到后续节点(此前改在副本上,下游仍写旧路径) - 另存为后以新路径重新登记实例并释放旧路径缓存 - ReadColumn 裁掉尾部空值(共享实例下触碰空行会撑大 rowCount) - 新增 3 个共享存储回归测试(格式保持/复制Sheet保持/另存后续写)
This commit is contained in:
1 parent
54571eff8d
commit
9de0eeaa88
6 files changed
+128
-24
No files matched your search
@@ -4,6 +4,7 @@ import path from "node:path";
|
||||
import { PDFDocument } from "pdf-lib";
|
||||
import { register } from "../engine/registry";
|
||||
import { RuntimeError, type CapabilityHandler } from "../engine/types";
|
||||
import { acquireWorkbook } from "./excel-store";
|
||||
|
||||
type WorkbookSource = { workbook: ExcelJS.Workbook; filePath: string };
|
||||
|
||||
@@ -29,8 +30,7 @@ function requiredPath(candidate: unknown, label: string, nodeId: string, compone
|
||||
|
||||
async function loadWorkbook(args: Record<string, unknown>, nodeId: string, componentId: string): Promise<WorkbookSource> {
|
||||
const filePath = requiredPath(value(args, ["workbook", "objExcel", "objExcelWorkBook", "file", "path"]), "Excel path", nodeId, componentId);
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.readFile(filePath);
|
||||
const workbook = await acquireWorkbook(filePath);
|
||||
return { workbook, filePath };
|
||||
}
|
||||
|
||||
@@ -134,11 +134,12 @@ const readColumn: CapabilityHandler = async (_ctx, node, args) => {
|
||||
const sheet = worksheetOf(source.workbook, args);
|
||||
const column = columnNumber(value(args, ["columnName", "column", "cellPos"], "A"));
|
||||
const startRow = Math.max(1, Number(value(args, ["row", "startRow"], 1)));
|
||||
return Array.from({ length: Math.max(0, sheet.rowCount - startRow + 1) }, (_, index) => cellValue(sheet.getCell(startRow + index, column).value));
|
||||
const values = Array.from({ length: Math.max(0, sheet.rowCount - startRow + 1) }, (_, index) => cellValue(sheet.getCell(startRow + index, column).value));
|
||||
// 触碰过尾部空行(如定位空单元格)会撑大 rowCount,裁掉尾部空值避免误报
|
||||
while (values.length > 0 && (values[values.length - 1] === "" || values[values.length - 1] === null || values[values.length - 1] === undefined)) values.pop();
|
||||
return values;
|
||||
};
|
||||
register(["Excel_Cs_ReadColumn", "Excel_GetColDataNew"], readColumn);
|
||||
|
||||
register("Excel_Cs_DeleteRow", async (_ctx, node, args) => {
|
||||
register(["Excel_Cs_ReadColumn", "Excel_GetColDataNew"], readColumn);register("Excel_Cs_DeleteRow", async (_ctx, node, args) => {
|
||||
const source = await loadWorkbook(args, node.id, node.componentId);
|
||||
const sheet = worksheetOf(source.workbook, args);
|
||||
const mode = text(args, ["mode"]);
|
||||
|
||||
Reference in new issue
Block a user