@4399ywkf/editor 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +164 -11
- package/dist/PptxView-ZH4FZKNO.js +3 -0
- package/dist/PptxView-ZH4FZKNO.js.map +1 -0
- package/dist/SheetView-SDBRSTVS.js +3 -0
- package/dist/{SheetView-DSADIZNS.js.map → SheetView-SDBRSTVS.js.map} +1 -1
- package/dist/chunk-5HMKRNIH.js +27 -0
- package/dist/chunk-5HMKRNIH.js.map +1 -0
- package/dist/chunk-5XG4YMAB.js +149 -0
- package/dist/chunk-5XG4YMAB.js.map +1 -0
- package/dist/chunk-DGUNVCOM.js +711 -0
- package/dist/chunk-DGUNVCOM.js.map +1 -0
- package/dist/chunk-HPSPOM2O.js +128 -0
- package/dist/chunk-HPSPOM2O.js.map +1 -0
- package/dist/chunk-KRP5V7VF.js +130 -0
- package/dist/chunk-KRP5V7VF.js.map +1 -0
- package/dist/chunk-SBTKDJAL.js +107 -0
- package/dist/chunk-SBTKDJAL.js.map +1 -0
- package/dist/{chunk-L6ZR5HHW.js → chunk-SYCK6Y5F.js} +15 -10
- package/dist/chunk-SYCK6Y5F.js.map +1 -0
- package/dist/chunk-WF7PIIFR.js +21 -0
- package/dist/chunk-WF7PIIFR.js.map +1 -0
- package/dist/csv-parse-D0zTBvDB.d.ts +216 -0
- package/dist/csv.d.ts +86 -0
- package/dist/csv.js +34 -0
- package/dist/csv.js.map +1 -0
- package/dist/docx.d.ts +15 -0
- package/dist/docx.js +61 -3
- package/dist/docx.js.map +1 -1
- package/dist/import-GVZDLWA2.js +6 -0
- package/dist/import-GVZDLWA2.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +21 -2
- package/dist/index.js.map +1 -1
- package/dist/pdf.d.ts +1 -1
- package/dist/pptx.d.ts +36 -0
- package/dist/pptx.js +3 -0
- package/dist/pptx.js.map +1 -0
- package/dist/{registry-BBL8yeIT.d.ts → registry-XJFJXtZ_.d.ts} +6 -0
- package/dist/sheet-runtime.d.ts +212 -0
- package/dist/sheet-runtime.js +416 -0
- package/dist/sheet-runtime.js.map +1 -0
- package/dist/sheet.d.ts +7 -5
- package/dist/sheet.js +1 -1
- package/dist/xlsx.d.ts +127 -189
- package/dist/xlsx.js +8 -104
- package/dist/xlsx.js.map +1 -1
- package/package.json +19 -3
- package/dist/SheetView-DSADIZNS.js +0 -3
- package/dist/chunk-L6ZR5HHW.js.map +0 -1
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
import { parseRange, cellRef, parseCellRef } from './chunk-SBTKDJAL.js';
|
|
2
|
+
import { escapeCsvField, activeSheetId } from './chunk-HPSPOM2O.js';
|
|
3
|
+
import { snapshotFromUniver } from './chunk-WF7PIIFR.js';
|
|
4
|
+
import { numericKeys, richTextToPlain } from './chunk-5HMKRNIH.js';
|
|
5
|
+
|
|
6
|
+
// src/sheet-runtime/facade.ts
|
|
7
|
+
function method(obj, name) {
|
|
8
|
+
const fn = obj?.[name];
|
|
9
|
+
return typeof fn === "function" ? fn.bind(obj) : void 0;
|
|
10
|
+
}
|
|
11
|
+
function need(obj, names, what) {
|
|
12
|
+
for (const name of names) {
|
|
13
|
+
const fn = method(obj, name);
|
|
14
|
+
if (fn) return fn;
|
|
15
|
+
}
|
|
16
|
+
throw new Error(`当前 Univer 版本不支持${what}(缺少 ${names.join(" / ")} 方法)`);
|
|
17
|
+
}
|
|
18
|
+
function activeWorkbook(univerAPI) {
|
|
19
|
+
const get = need(univerAPI, ["getActiveWorkbook"], "取当前工作簿");
|
|
20
|
+
const book = get();
|
|
21
|
+
if (!book) throw new Error("拿不到当前工作簿:univerAPI 无效,或表格尚未就绪");
|
|
22
|
+
return book;
|
|
23
|
+
}
|
|
24
|
+
function toHandle(fws) {
|
|
25
|
+
return {
|
|
26
|
+
facade: fws,
|
|
27
|
+
id: String(need(fws, ["getSheetId"], "读工作表 id")() ?? ""),
|
|
28
|
+
name: String(need(fws, ["getSheetName"], "读工作表名")() ?? "")
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
function listSheets(workbook) {
|
|
32
|
+
const sheets = need(workbook, ["getSheets"], "枚举工作表")() ?? [];
|
|
33
|
+
return sheets.map(toHandle);
|
|
34
|
+
}
|
|
35
|
+
function activeSheet(workbook) {
|
|
36
|
+
const fws = need(workbook, ["getActiveSheet"], "取活动工作表")();
|
|
37
|
+
if (!fws) throw new Error("拿不到活动工作表");
|
|
38
|
+
return toHandle(fws);
|
|
39
|
+
}
|
|
40
|
+
function sheetByRef(workbook, ref) {
|
|
41
|
+
if (!ref) return activeSheet(workbook);
|
|
42
|
+
const all = listSheets(workbook);
|
|
43
|
+
const hit = all.find((s) => s.id === ref) ?? all.find((s) => s.name === ref);
|
|
44
|
+
if (!hit) {
|
|
45
|
+
const names = all.map((s) => `「${s.name}」`).join(" ");
|
|
46
|
+
throw new Error(`找不到工作表「${ref}」。现有工作表:${names}`);
|
|
47
|
+
}
|
|
48
|
+
return hit;
|
|
49
|
+
}
|
|
50
|
+
function rangeOf(sheet, row, column, numRows, numColumns) {
|
|
51
|
+
const getRange = need(
|
|
52
|
+
sheet.facade,
|
|
53
|
+
["getRange"],
|
|
54
|
+
"取区域"
|
|
55
|
+
);
|
|
56
|
+
return getRange(row, column, numRows, numColumns);
|
|
57
|
+
}
|
|
58
|
+
function setRangeValues(range, cells) {
|
|
59
|
+
need(range, ["setValues"], "写区域值")(cells);
|
|
60
|
+
}
|
|
61
|
+
function insertRows(sheet, before, count) {
|
|
62
|
+
need(
|
|
63
|
+
sheet.facade,
|
|
64
|
+
["insertRowsBefore", "insertRows"],
|
|
65
|
+
"插入行"
|
|
66
|
+
)(before, count);
|
|
67
|
+
}
|
|
68
|
+
function deleteRows(sheet, start, count) {
|
|
69
|
+
need(sheet.facade, ["deleteRows"], "删除行")(start, count);
|
|
70
|
+
}
|
|
71
|
+
function insertColumns(sheet, before, count) {
|
|
72
|
+
need(
|
|
73
|
+
sheet.facade,
|
|
74
|
+
["insertColumnsBefore", "insertColumns"],
|
|
75
|
+
"插入列"
|
|
76
|
+
)(before, count);
|
|
77
|
+
}
|
|
78
|
+
function deleteColumns(sheet, start, count) {
|
|
79
|
+
need(sheet.facade, ["deleteColumns"], "删除列")(start, count);
|
|
80
|
+
}
|
|
81
|
+
function addSheet(workbook, name) {
|
|
82
|
+
const insert = need(workbook, ["insertSheet", "create"], "新建工作表");
|
|
83
|
+
const fws = insert(name);
|
|
84
|
+
if (!fws) throw new Error("新建工作表失败(insertSheet 没有返回工作表实例)");
|
|
85
|
+
return toHandle(fws);
|
|
86
|
+
}
|
|
87
|
+
function renameSheet(sheet, name) {
|
|
88
|
+
need(sheet.facade, ["setName"], "重命名工作表")(name);
|
|
89
|
+
}
|
|
90
|
+
function deleteSheet(workbook, sheet) {
|
|
91
|
+
need(workbook, ["deleteSheet"], "删除工作表")(sheet.facade);
|
|
92
|
+
}
|
|
93
|
+
function activateSheet(workbook, sheet) {
|
|
94
|
+
const setActive = method(workbook, "setActiveSheet") ?? method(sheet.facade, "activate");
|
|
95
|
+
if (!setActive) {
|
|
96
|
+
throw new Error("当前 Univer 版本不支持切换活动表(缺少 setActiveSheet / activate 方法)");
|
|
97
|
+
}
|
|
98
|
+
if (method(workbook, "setActiveSheet")) setActive(sheet.facade);
|
|
99
|
+
else setActive();
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// src/sheet-runtime/operations.ts
|
|
103
|
+
function cellText(cell) {
|
|
104
|
+
if (!cell) return "";
|
|
105
|
+
const rich = richTextToPlain(cell);
|
|
106
|
+
if (rich !== void 0) return rich;
|
|
107
|
+
const v = cell.v;
|
|
108
|
+
if (v === void 0 || v === null) return "";
|
|
109
|
+
if (typeof v === "boolean") return v ? "TRUE" : "FALSE";
|
|
110
|
+
return String(v);
|
|
111
|
+
}
|
|
112
|
+
function usedExtent(sheet) {
|
|
113
|
+
const cellData = sheet.cellData ?? {};
|
|
114
|
+
const rows = numericKeys(cellData);
|
|
115
|
+
let maxCol = -1;
|
|
116
|
+
for (const r of rows) {
|
|
117
|
+
const cols = numericKeys(cellData[r]);
|
|
118
|
+
const last = cols[cols.length - 1];
|
|
119
|
+
if (last !== void 0 && last > maxCol) maxCol = last;
|
|
120
|
+
}
|
|
121
|
+
const maxRow = rows.length ? rows[rows.length - 1] : -1;
|
|
122
|
+
return { rows: maxRow + 1, cols: maxCol + 1 };
|
|
123
|
+
}
|
|
124
|
+
function snapshotSheet(workbook, univerAPI, ref) {
|
|
125
|
+
const order = (workbook.sheetOrder?.length ? workbook.sheetOrder : Object.keys(workbook.sheets ?? {})).filter((id2) => workbook.sheets?.[id2]);
|
|
126
|
+
const wanted = ref ?? activeSheetId(univerAPI);
|
|
127
|
+
const id = wanted && (order.find((i) => i === wanted) ?? order.find((i) => workbook.sheets?.[i]?.name === wanted)) || order[0];
|
|
128
|
+
if (!id) throw new Error("工作簿里没有工作表");
|
|
129
|
+
if (ref && id !== ref && workbook.sheets?.[id]?.name !== ref) {
|
|
130
|
+
const names = order.map((i) => `「${workbook.sheets?.[i]?.name ?? i}」`);
|
|
131
|
+
throw new Error(`找不到工作表「${ref}」。现有工作表:${names.join(" ")}`);
|
|
132
|
+
}
|
|
133
|
+
return { id, sheet: workbook.sheets?.[id] };
|
|
134
|
+
}
|
|
135
|
+
var MAX_READ_ROWS = 300;
|
|
136
|
+
var MAX_READ_COLS = 100;
|
|
137
|
+
function readSheet(univerAPI, args = {}) {
|
|
138
|
+
const workbook = snapshotFromUniver(univerAPI);
|
|
139
|
+
const { id, sheet } = snapshotSheet(workbook, univerAPI, args.sheet);
|
|
140
|
+
const extent = usedExtent(sheet);
|
|
141
|
+
let startRow = 0;
|
|
142
|
+
let startCol = 0;
|
|
143
|
+
let endRow = extent.rows - 1;
|
|
144
|
+
let endCol = extent.cols - 1;
|
|
145
|
+
if (args.range) {
|
|
146
|
+
const range = parseRange(args.range);
|
|
147
|
+
if (!range) throw new Error(`range 不合法:「${args.range}」。要 A1 形式,如 "B2:F40"`);
|
|
148
|
+
startRow = range.startRow;
|
|
149
|
+
startCol = range.startColumn;
|
|
150
|
+
endRow = range.endRow;
|
|
151
|
+
endCol = range.endColumn;
|
|
152
|
+
}
|
|
153
|
+
const truncated = endRow - startRow + 1 > MAX_READ_ROWS || endCol - startCol + 1 > MAX_READ_COLS;
|
|
154
|
+
endRow = Math.min(endRow, startRow + MAX_READ_ROWS - 1);
|
|
155
|
+
endCol = Math.min(endCol, startCol + MAX_READ_COLS - 1);
|
|
156
|
+
const cellData = sheet.cellData ?? {};
|
|
157
|
+
const lines = [];
|
|
158
|
+
const formulas = [];
|
|
159
|
+
for (let r = startRow; r <= endRow; r++) {
|
|
160
|
+
const fields = [];
|
|
161
|
+
for (let c = startCol; c <= endCol; c++) {
|
|
162
|
+
const cell = cellData[r]?.[c];
|
|
163
|
+
fields.push(escapeCsvField(cellText(cell)));
|
|
164
|
+
if (cell?.f) formulas.push({ ref: cellRef(r, c), formula: cell.f });
|
|
165
|
+
}
|
|
166
|
+
lines.push(fields.join(","));
|
|
167
|
+
}
|
|
168
|
+
const overview = listWorkbookSheets(workbook, univerAPI);
|
|
169
|
+
return {
|
|
170
|
+
sheets: overview,
|
|
171
|
+
sheet: sheet.name ?? id,
|
|
172
|
+
/** 本次实际读到的区域(A1 形式) */
|
|
173
|
+
range: extent.rows === 0 ? null : `${cellRef(startRow, startCol)}:${cellRef(Math.max(endRow, startRow), Math.max(endCol, startCol))}`,
|
|
174
|
+
/** CSV 文本。首行是区域第一行,**不是表头行标注** —— 列含义自己看内容 */
|
|
175
|
+
csv: lines.join("\n"),
|
|
176
|
+
...args.includeFormulas === false ? {} : { formulas },
|
|
177
|
+
...truncated ? {
|
|
178
|
+
truncated: true,
|
|
179
|
+
note: `区域超过 ${MAX_READ_ROWS}×${MAX_READ_COLS} 上限,已截断。用 range 参数分段读取`
|
|
180
|
+
} : {}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function listWorkbookSheets(workbook, univerAPI) {
|
|
184
|
+
const active = activeSheetId(univerAPI);
|
|
185
|
+
const order = (workbook.sheetOrder?.length ? workbook.sheetOrder : Object.keys(workbook.sheets ?? {})).filter((id) => workbook.sheets?.[id]);
|
|
186
|
+
return order.map((id) => {
|
|
187
|
+
const s = workbook.sheets?.[id];
|
|
188
|
+
const extent = usedExtent(s);
|
|
189
|
+
return {
|
|
190
|
+
id,
|
|
191
|
+
name: s.name ?? id,
|
|
192
|
+
rows: extent.rows,
|
|
193
|
+
cols: extent.cols,
|
|
194
|
+
...s.hidden === 1 ? { hidden: true } : {},
|
|
195
|
+
...id === active ? { active: true } : {}
|
|
196
|
+
};
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
function findInWorkbook(univerAPI, args) {
|
|
200
|
+
if (!args?.query) throw new Error("find 需要 query");
|
|
201
|
+
const workbook = snapshotFromUniver(univerAPI);
|
|
202
|
+
const limit = args.limit ?? 20;
|
|
203
|
+
const query = args.query.toLowerCase();
|
|
204
|
+
const matches = [];
|
|
205
|
+
const order = (workbook.sheetOrder?.length ? workbook.sheetOrder : Object.keys(workbook.sheets ?? {})).filter((id) => workbook.sheets?.[id]);
|
|
206
|
+
for (const id of order) {
|
|
207
|
+
const sheet = workbook.sheets?.[id];
|
|
208
|
+
const cellData = sheet.cellData ?? {};
|
|
209
|
+
for (const r of numericKeys(cellData)) {
|
|
210
|
+
for (const c of numericKeys(cellData[r])) {
|
|
211
|
+
const cell = cellData[r]?.[c];
|
|
212
|
+
const text = cellText(cell);
|
|
213
|
+
const formula = cell?.f;
|
|
214
|
+
if (!text.toLowerCase().includes(query) && !(formula ?? "").toLowerCase().includes(query)) {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
matches.push({
|
|
218
|
+
sheet: sheet.name ?? id,
|
|
219
|
+
ref: cellRef(r, c),
|
|
220
|
+
value: text,
|
|
221
|
+
...formula ? { formula } : {}
|
|
222
|
+
});
|
|
223
|
+
if (matches.length >= limit) return { matches, total: matches.length, capped: true };
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return { matches, total: matches.length };
|
|
228
|
+
}
|
|
229
|
+
function setValues(univerAPI, args) {
|
|
230
|
+
const start = args?.start ? parseCellRef(args.start) : void 0;
|
|
231
|
+
if (!start) throw new Error(`start 不合法:「${args?.start ?? ""}」。要单格 A1 形式,如 "B2"`);
|
|
232
|
+
const rows = args.values;
|
|
233
|
+
if (!Array.isArray(rows) || !rows.length || !Array.isArray(rows[0])) {
|
|
234
|
+
throw new Error("values 要是二维数组:[[行1格1, 行1格2], [行2格1, …]]");
|
|
235
|
+
}
|
|
236
|
+
const width = rows[0].length;
|
|
237
|
+
if (!width) throw new Error("values 的行不能是空数组");
|
|
238
|
+
for (const [i, row] of rows.entries()) {
|
|
239
|
+
if (!Array.isArray(row) || row.length !== width) {
|
|
240
|
+
throw new Error(
|
|
241
|
+
`values 各行要等长:第 1 行 ${width} 格,第 ${i + 1} 行 ${Array.isArray(row) ? row.length : "?"} 格。不想改的格子请缩小区域分多次写,null 表示清空`
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
const book = activeWorkbook(univerAPI);
|
|
246
|
+
const sheet = sheetByRef(book, args.sheet);
|
|
247
|
+
const cells = rows.map(
|
|
248
|
+
(row) => row.map((value) => {
|
|
249
|
+
if (typeof value === "string" && value.startsWith("=")) return { f: value };
|
|
250
|
+
return { v: value };
|
|
251
|
+
})
|
|
252
|
+
);
|
|
253
|
+
const range = rangeOf(sheet, start.row, start.column, rows.length, width);
|
|
254
|
+
setRangeValues(range, cells);
|
|
255
|
+
const endRef = cellRef(start.row + rows.length - 1, start.column + width - 1);
|
|
256
|
+
return {
|
|
257
|
+
sheet: sheet.name,
|
|
258
|
+
range: `${cellRef(start.row, start.column)}:${endRef}`,
|
|
259
|
+
written: rows.length * width
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
function editRowsCols(univerAPI, args) {
|
|
263
|
+
const index = args?.index;
|
|
264
|
+
if (!Number.isInteger(index) || index < 0) throw new Error("index 要是 ≥0 的整数(0-based)");
|
|
265
|
+
const count = args.count ?? 1;
|
|
266
|
+
if (!Number.isInteger(count) || count < 1) throw new Error("count 要是 ≥1 的整数");
|
|
267
|
+
const book = activeWorkbook(univerAPI);
|
|
268
|
+
const sheet = sheetByRef(book, args.sheet);
|
|
269
|
+
switch (args.action) {
|
|
270
|
+
case "insert_rows":
|
|
271
|
+
insertRows(sheet, index, count);
|
|
272
|
+
break;
|
|
273
|
+
case "delete_rows":
|
|
274
|
+
deleteRows(sheet, index, count);
|
|
275
|
+
break;
|
|
276
|
+
case "insert_cols":
|
|
277
|
+
insertColumns(sheet, index, count);
|
|
278
|
+
break;
|
|
279
|
+
case "delete_cols":
|
|
280
|
+
deleteColumns(sheet, index, count);
|
|
281
|
+
break;
|
|
282
|
+
default:
|
|
283
|
+
throw new Error(`未知 action「${String(args.action)}」`);
|
|
284
|
+
}
|
|
285
|
+
return { sheet: sheet.name, action: args.action, index, count };
|
|
286
|
+
}
|
|
287
|
+
function manageSheets(univerAPI, args) {
|
|
288
|
+
const book = activeWorkbook(univerAPI);
|
|
289
|
+
const done = (detail) => ({
|
|
290
|
+
...detail,
|
|
291
|
+
sheets: listSheets(book).map((s) => ({ id: s.id, name: s.name }))
|
|
292
|
+
});
|
|
293
|
+
switch (args?.action) {
|
|
294
|
+
case "add":
|
|
295
|
+
return done({ action: "add", added: addSheet(book, args.name).name });
|
|
296
|
+
case "rename": {
|
|
297
|
+
if (!args.name) throw new Error("rename 需要 name(新表名)");
|
|
298
|
+
const sheet = sheetByRef(book, args.sheet);
|
|
299
|
+
renameSheet(sheet, args.name);
|
|
300
|
+
return done({ action: "rename", from: sheet.name, to: args.name });
|
|
301
|
+
}
|
|
302
|
+
case "delete": {
|
|
303
|
+
if (!args.sheet) throw new Error("delete 需要 sheet(表 id 或表名)—— 不允许默认删活动表");
|
|
304
|
+
const sheet = sheetByRef(book, args.sheet);
|
|
305
|
+
deleteSheet(book, sheet);
|
|
306
|
+
return done({ action: "delete", deleted: sheet.name });
|
|
307
|
+
}
|
|
308
|
+
case "activate": {
|
|
309
|
+
const sheet = sheetByRef(book, args.sheet);
|
|
310
|
+
activateSheet(book, sheet);
|
|
311
|
+
return done({ action: "activate", active: sheet.name });
|
|
312
|
+
}
|
|
313
|
+
default:
|
|
314
|
+
throw new Error(`未知 action「${String(args?.action)}」,可用:add rename delete activate`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
function bytesToBase64(bytes) {
|
|
318
|
+
const B = globalThis.Buffer;
|
|
319
|
+
if (B) return B.from(bytes).toString("base64");
|
|
320
|
+
let bin = "";
|
|
321
|
+
const CHUNK = 32768;
|
|
322
|
+
for (let i = 0; i < bytes.length; i += CHUNK) {
|
|
323
|
+
bin += String.fromCharCode(...bytes.subarray(i, i + CHUNK));
|
|
324
|
+
}
|
|
325
|
+
return btoa(bin);
|
|
326
|
+
}
|
|
327
|
+
function sanitizeFilename(name) {
|
|
328
|
+
if (!name) return null;
|
|
329
|
+
const base = name.split(/[/\\]/).pop()?.trim();
|
|
330
|
+
if (!base || base === "." || base === "..") return null;
|
|
331
|
+
return /\.xlsx$/i.test(base) ? base : `${base}.xlsx`;
|
|
332
|
+
}
|
|
333
|
+
async function exportXlsxBase64(univerAPI, args = {}) {
|
|
334
|
+
const { exportXlsx } = await import('./xlsx.js');
|
|
335
|
+
const { bytes, warnings, stats } = exportXlsx(univerAPI);
|
|
336
|
+
return {
|
|
337
|
+
filename: sanitizeFilename(args.filename) ?? "工作簿.xlsx",
|
|
338
|
+
base64: bytesToBase64(bytes),
|
|
339
|
+
bytes: bytes.length,
|
|
340
|
+
warnings,
|
|
341
|
+
stats
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// src/sheet-runtime/runtime.ts
|
|
346
|
+
var SheetRuntime = class {
|
|
347
|
+
univerAPI;
|
|
348
|
+
constructor(univerAPI) {
|
|
349
|
+
this.univerAPI = univerAPI ?? null;
|
|
350
|
+
}
|
|
351
|
+
/** Univer 实例就绪 / 卸载时调用。配合 `<DocumentView onReady>` 用。 */
|
|
352
|
+
setUniverAPI(univerAPI) {
|
|
353
|
+
this.univerAPI = univerAPI;
|
|
354
|
+
}
|
|
355
|
+
isReady() {
|
|
356
|
+
return Boolean(this.univerAPI);
|
|
357
|
+
}
|
|
358
|
+
use() {
|
|
359
|
+
if (!this.univerAPI) throw new Error("表格尚未就绪:先调 setUniverAPI(univerAPI)");
|
|
360
|
+
return this.univerAPI;
|
|
361
|
+
}
|
|
362
|
+
/* ------------------------------ 读 ------------------------------ */
|
|
363
|
+
/** 工作簿概览 + 一张表的 CSV 视图与公式清单。要写之前先调它看清现状。 */
|
|
364
|
+
read(args = {}) {
|
|
365
|
+
return readSheet(this.use(), args);
|
|
366
|
+
}
|
|
367
|
+
/** 全簿检索(值和公式都搜),返回可回填给写工具的 sheet + ref。 */
|
|
368
|
+
find(args) {
|
|
369
|
+
return findInWorkbook(this.use(), args);
|
|
370
|
+
}
|
|
371
|
+
/* ------------------------------ 写 ------------------------------ */
|
|
372
|
+
/** 从 start 起写一块二维值。"=…" 是公式,null 清空。 */
|
|
373
|
+
setValues(args) {
|
|
374
|
+
return setValues(this.use(), args);
|
|
375
|
+
}
|
|
376
|
+
/** 插入 / 删除行列。 */
|
|
377
|
+
editRowsCols(args) {
|
|
378
|
+
return editRowsCols(this.use(), args);
|
|
379
|
+
}
|
|
380
|
+
/** 新建 / 重命名 / 删除 / 激活工作表。 */
|
|
381
|
+
manageSheets(args) {
|
|
382
|
+
return manageSheets(this.use(), args);
|
|
383
|
+
}
|
|
384
|
+
/* ------------------------------ 导出 ------------------------------ */
|
|
385
|
+
/** 导出 .xlsx(base64 给传输层,模型只看路径 —— 和 doc_export_docx 同一约定)。 */
|
|
386
|
+
exportXlsx(args = {}) {
|
|
387
|
+
return exportXlsxBase64(this.use(), args);
|
|
388
|
+
}
|
|
389
|
+
/* ---------------------------- 统一入口 ---------------------------- */
|
|
390
|
+
/**
|
|
391
|
+
* 工具名 → 方法。给传输层(MCP 桥、agent executor)用的单一分发口,
|
|
392
|
+
* 和 `DocRuntime.call` 同构 —— 桥不需要知道自己面对的是文档还是表格。
|
|
393
|
+
*/
|
|
394
|
+
async call(tool, args = {}) {
|
|
395
|
+
switch (tool) {
|
|
396
|
+
case "sheet_read":
|
|
397
|
+
return this.read(args);
|
|
398
|
+
case "sheet_find":
|
|
399
|
+
return this.find(args);
|
|
400
|
+
case "sheet_set_values":
|
|
401
|
+
return this.setValues(args);
|
|
402
|
+
case "sheet_edit_rows_cols":
|
|
403
|
+
return this.editRowsCols(args);
|
|
404
|
+
case "sheet_manage_sheets":
|
|
405
|
+
return this.manageSheets(args);
|
|
406
|
+
case "sheet_export_xlsx":
|
|
407
|
+
return this.exportXlsx(args);
|
|
408
|
+
default:
|
|
409
|
+
throw new Error(`未知工具 ${tool}`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
export { SheetRuntime, editRowsCols, exportXlsxBase64, findInWorkbook, manageSheets, readSheet, setValues };
|
|
415
|
+
//# sourceMappingURL=sheet-runtime.js.map
|
|
416
|
+
//# sourceMappingURL=sheet-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sheet-runtime/facade.ts","../src/sheet-runtime/operations.ts","../src/sheet-runtime/runtime.ts"],"names":["id"],"mappings":"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","file":"sheet-runtime.js","sourcesContent":["/**\n * 对 Univer facade(FUniver / FWorkbook / FWorksheet / FRange)的全部探测。\n *\n * **为什么集中在这一个文件**:`@univerjs/presets` 是可选 peer,写具体类型会让\n * 没装它的项目 typecheck 直接红,所以整个 sheet-runtime 只能拿 `unknown` 过日子。\n * unknown 上的方法探测是最容易随 Univer 版本漂移的部位 —— 全钉在这里,\n * 漂了只改一个文件,operations 层完全不感知 facade 的形状。\n *\n * 探测失败一律抛**可读的错**(「当前 Univer 版本没有 xxx」),\n * 不静默降级 —— AI 收到错误文本本身就是教学。\n */\n\n/** obj 上的同名方法,绑定 this。没有返回 undefined */\nfunction method<T extends (...args: never[]) => unknown>(\n obj: unknown,\n name: string,\n): T | undefined {\n const fn = (obj as Record<string, unknown> | null)?.[name]\n return typeof fn === \"function\" ? (fn.bind(obj) as T) : undefined\n}\n\n/** 探测一串候选名(新旧 API 名并存时用),全都没有就抛可读错误 */\nfunction need<T extends (...args: never[]) => unknown>(\n obj: unknown,\n names: string[],\n what: string,\n): T {\n for (const name of names) {\n const fn = method<T>(obj, name)\n if (fn) return fn\n }\n throw new Error(`当前 Univer 版本不支持${what}(缺少 ${names.join(\" / \")} 方法)`)\n}\n\n/* ------------------------------ 工作簿 ------------------------------ */\n\nexport function activeWorkbook(univerAPI: unknown): unknown {\n const get = need(univerAPI, [\"getActiveWorkbook\"], \"取当前工作簿\")\n const book = get()\n if (!book) throw new Error(\"拿不到当前工作簿:univerAPI 无效,或表格尚未就绪\")\n return book\n}\n\nexport interface SheetHandle {\n facade: unknown\n id: string\n name: string\n}\n\nfunction toHandle(fws: unknown): SheetHandle {\n return {\n facade: fws,\n id: String(need(fws, [\"getSheetId\"], \"读工作表 id\")() ?? \"\"),\n name: String(need(fws, [\"getSheetName\"], \"读工作表名\")() ?? \"\"),\n }\n}\n\nexport function listSheets(workbook: unknown): SheetHandle[] {\n const sheets = need<() => unknown[]>(workbook, [\"getSheets\"], \"枚举工作表\")() ?? []\n return sheets.map(toHandle)\n}\n\nexport function activeSheet(workbook: unknown): SheetHandle {\n const fws = need(workbook, [\"getActiveSheet\"], \"取活动工作表\")()\n if (!fws) throw new Error(\"拿不到活动工作表\")\n return toHandle(fws)\n}\n\n/**\n * 按 id 或表名找工作表;`ref` 省略时用活动表。\n * 找不到时把现有表名列出来 —— 模型下一步就知道该传什么。\n */\nexport function sheetByRef(workbook: unknown, ref?: string): SheetHandle {\n if (!ref) return activeSheet(workbook)\n const all = listSheets(workbook)\n const hit = all.find((s) => s.id === ref) ?? all.find((s) => s.name === ref)\n if (!hit) {\n const names = all.map((s) => `「${s.name}」`).join(\" \")\n throw new Error(`找不到工作表「${ref}」。现有工作表:${names}`)\n }\n return hit\n}\n\n/* ------------------------------ 区域读写 ------------------------------ */\n\n/** (0-based 起点 + 尺寸) → FRange */\nexport function rangeOf(\n sheet: SheetHandle,\n row: number,\n column: number,\n numRows: number,\n numColumns: number,\n): unknown {\n const getRange = need<(r: number, c: number, nr: number, nc: number) => unknown>(\n sheet.facade,\n [\"getRange\"],\n \"取区域\",\n )\n return getRange(row, column, numRows, numColumns)\n}\n\n/**\n * 往区域写值。`cells` 与区域同尺寸:\n * `{ f }` 是公式、`{ v }` 是值(null 即清空该格)。\n */\nexport function setRangeValues(range: unknown, cells: Array<Array<Record<string, unknown>>>): void {\n need<(v: unknown) => unknown>(range, [\"setValues\"], \"写区域值\")(cells)\n}\n\n/* ------------------------------ 结构操作 ------------------------------ */\n\nexport function insertRows(sheet: SheetHandle, before: number, count: number): void {\n need<(p: number, n: number) => unknown>(\n sheet.facade,\n [\"insertRowsBefore\", \"insertRows\"],\n \"插入行\",\n )(before, count)\n}\n\nexport function deleteRows(sheet: SheetHandle, start: number, count: number): void {\n need<(p: number, n: number) => unknown>(sheet.facade, [\"deleteRows\"], \"删除行\")(start, count)\n}\n\nexport function insertColumns(sheet: SheetHandle, before: number, count: number): void {\n need<(p: number, n: number) => unknown>(\n sheet.facade,\n [\"insertColumnsBefore\", \"insertColumns\"],\n \"插入列\",\n )(before, count)\n}\n\nexport function deleteColumns(sheet: SheetHandle, start: number, count: number): void {\n need<(p: number, n: number) => unknown>(sheet.facade, [\"deleteColumns\"], \"删除列\")(start, count)\n}\n\n/* ------------------------------ 工作表管理 ------------------------------ */\n\nexport function addSheet(workbook: unknown, name?: string): SheetHandle {\n const insert = need<(n?: string) => unknown>(workbook, [\"insertSheet\", \"create\"], \"新建工作表\")\n const fws = insert(name)\n if (!fws) throw new Error(\"新建工作表失败(insertSheet 没有返回工作表实例)\")\n return toHandle(fws)\n}\n\nexport function renameSheet(sheet: SheetHandle, name: string): void {\n need<(n: string) => unknown>(sheet.facade, [\"setName\"], \"重命名工作表\")(name)\n}\n\nexport function deleteSheet(workbook: unknown, sheet: SheetHandle): void {\n need<(s: unknown) => unknown>(workbook, [\"deleteSheet\"], \"删除工作表\")(sheet.facade)\n}\n\nexport function activateSheet(workbook: unknown, sheet: SheetHandle): void {\n const setActive =\n method<(s: unknown) => unknown>(workbook, \"setActiveSheet\") ??\n method<(s: unknown) => unknown>(sheet.facade, \"activate\")\n if (!setActive) {\n throw new Error(\"当前 Univer 版本不支持切换活动表(缺少 setActiveSheet / activate 方法)\")\n }\n // setActiveSheet 挂在 workbook 上收 sheet;activate 挂在 sheet 上不收参数\n if (method(workbook, \"setActiveSheet\")) setActive(sheet.facade)\n else (setActive as () => unknown)()\n}\n","/**\n * sheet 工具面的操作实现。每个工具一个函数,`runtime.ts` 只做分发。\n *\n * 读写分两条路,这是有意的:\n *\n * - **读走快照**(`snapshotFromUniver`):纯数据,不碰 facade 的方法面 ——\n * Univer 版本漂移伤不到读路径;输出是 CSV 文本 + 公式清单,token 成本\n * 是 JSON 单元格矩阵的几分之一。\n * - **写走 facade**(`facade.ts`):写必须进 Univer 的 command 体系才有\n * 撤销栈和协同广播,直接改快照是死路。facade 探测集中在 facade.ts。\n */\n\nimport { numericKeys, richTextToPlain } from \"../xlsx/cell.ts\"\nimport { activeSheetId, escapeCsvField } from \"../xlsx/csv.ts\"\nimport { snapshotFromUniver } from \"../xlsx/snapshot.ts\"\nimport type { CellData, WorkbookData, WorksheetData } from \"../xlsx/types.ts\"\nimport { cellRef, parseCellRef, parseRange } from \"../xlsx/xml.ts\"\nimport {\n activateSheet,\n activeWorkbook,\n addSheet,\n deleteColumns,\n deleteRows,\n deleteSheet,\n insertColumns,\n insertRows,\n listSheets,\n rangeOf,\n renameSheet,\n type SheetHandle,\n setRangeValues,\n sheetByRef,\n} from \"./facade.ts\"\n\n/* ------------------------------ 公用小件 ------------------------------ */\n\n/** 单元格的展示文本。公式格取缓存值;富文本压平 */\nfunction cellText(cell: CellData | undefined): string {\n if (!cell) return \"\"\n const rich = richTextToPlain(cell)\n if (rich !== undefined) return rich\n const v = cell.v\n if (v === undefined || v === null) return \"\"\n if (typeof v === \"boolean\") return v ? \"TRUE\" : \"FALSE\"\n return String(v)\n}\n\n/** 快照里某张表的已用范围(有值/有格式的格子撑出来的) */\nfunction usedExtent(sheet: WorksheetData): { rows: number; cols: number } {\n const cellData = sheet.cellData ?? {}\n const rows = numericKeys(cellData)\n let maxCol = -1\n for (const r of rows) {\n const cols = numericKeys(cellData[r])\n const last = cols[cols.length - 1]\n if (last !== undefined && last > maxCol) maxCol = last\n }\n const maxRow = rows.length ? (rows[rows.length - 1] as number) : -1\n return { rows: maxRow + 1, cols: maxCol + 1 }\n}\n\n/** 快照 + 表引用(id / 名 / 缺省活动表)→ 表。找不到给出现有表名 */\nfunction snapshotSheet(\n workbook: WorkbookData,\n univerAPI: unknown,\n ref?: string,\n): { id: string; sheet: WorksheetData } {\n const order = (\n workbook.sheetOrder?.length ? workbook.sheetOrder : Object.keys(workbook.sheets ?? {})\n ).filter((id) => workbook.sheets?.[id])\n\n const wanted = ref ?? activeSheetId(univerAPI)\n const id =\n (wanted &&\n (order.find((i) => i === wanted) ??\n order.find((i) => (workbook.sheets?.[i] as WorksheetData)?.name === wanted))) ||\n order[0]\n if (!id) throw new Error(\"工作簿里没有工作表\")\n if (ref && id !== ref && (workbook.sheets?.[id] as WorksheetData)?.name !== ref) {\n const names = order.map((i) => `「${(workbook.sheets?.[i] as WorksheetData)?.name ?? i}」`)\n throw new Error(`找不到工作表「${ref}」。现有工作表:${names.join(\" \")}`)\n }\n return { id, sheet: workbook.sheets?.[id] as WorksheetData }\n}\n\n/* -------------------------------- 读 -------------------------------- */\n\n/** 一次读取塞给模型的上限。超出就截断并明说 —— 比悄悄截断或撑爆上下文都好 */\nconst MAX_READ_ROWS = 300\nconst MAX_READ_COLS = 100\n\nexport interface SheetReadArgs {\n /** 工作表 id 或表名,省略用活动表 */\n sheet?: string\n /** A1 区域(如 \"B2:F40\"),省略读整个已用范围 */\n range?: string\n /** 是否附带公式清单,默认 true */\n includeFormulas?: boolean\n}\n\nexport function readSheet(univerAPI: unknown, args: SheetReadArgs = {}) {\n const workbook = snapshotFromUniver(univerAPI)\n const { id, sheet } = snapshotSheet(workbook, univerAPI, args.sheet)\n const extent = usedExtent(sheet)\n\n let startRow = 0\n let startCol = 0\n let endRow = extent.rows - 1\n let endCol = extent.cols - 1\n if (args.range) {\n const range = parseRange(args.range)\n if (!range) throw new Error(`range 不合法:「${args.range}」。要 A1 形式,如 \"B2:F40\"`)\n startRow = range.startRow\n startCol = range.startColumn\n endRow = range.endRow\n endCol = range.endColumn\n }\n\n const truncated = endRow - startRow + 1 > MAX_READ_ROWS || endCol - startCol + 1 > MAX_READ_COLS\n endRow = Math.min(endRow, startRow + MAX_READ_ROWS - 1)\n endCol = Math.min(endCol, startCol + MAX_READ_COLS - 1)\n\n const cellData = sheet.cellData ?? {}\n const lines: string[] = []\n const formulas: Array<{ ref: string; formula: string }> = []\n for (let r = startRow; r <= endRow; r++) {\n const fields: string[] = []\n for (let c = startCol; c <= endCol; c++) {\n const cell = cellData[r]?.[c]\n fields.push(escapeCsvField(cellText(cell)))\n if (cell?.f) formulas.push({ ref: cellRef(r, c), formula: cell.f })\n }\n lines.push(fields.join(\",\"))\n }\n\n const overview = listWorkbookSheets(workbook, univerAPI)\n return {\n sheets: overview,\n sheet: sheet.name ?? id,\n /** 本次实际读到的区域(A1 形式) */\n range:\n extent.rows === 0\n ? null\n : `${cellRef(startRow, startCol)}:${cellRef(Math.max(endRow, startRow), Math.max(endCol, startCol))}`,\n /** CSV 文本。首行是区域第一行,**不是表头行标注** —— 列含义自己看内容 */\n csv: lines.join(\"\\n\"),\n ...(args.includeFormulas === false ? {} : { formulas }),\n ...(truncated\n ? {\n truncated: true,\n note: `区域超过 ${MAX_READ_ROWS}×${MAX_READ_COLS} 上限,已截断。用 range 参数分段读取`,\n }\n : {}),\n }\n}\n\nfunction listWorkbookSheets(workbook: WorkbookData, univerAPI: unknown) {\n const active = activeSheetId(univerAPI)\n const order = (\n workbook.sheetOrder?.length ? workbook.sheetOrder : Object.keys(workbook.sheets ?? {})\n ).filter((id) => workbook.sheets?.[id])\n return order.map((id) => {\n const s = workbook.sheets?.[id] as WorksheetData\n const extent = usedExtent(s)\n return {\n id,\n name: s.name ?? id,\n rows: extent.rows,\n cols: extent.cols,\n ...(s.hidden === 1 ? { hidden: true } : {}),\n ...(id === active ? { active: true } : {}),\n }\n })\n}\n\nexport interface SheetFindArgs {\n query: string\n /** 最多返回几条,默认 20 */\n limit?: number\n}\n\nexport function findInWorkbook(univerAPI: unknown, args: SheetFindArgs) {\n if (!args?.query) throw new Error(\"find 需要 query\")\n const workbook = snapshotFromUniver(univerAPI)\n const limit = args.limit ?? 20\n const query = args.query.toLowerCase()\n\n const matches: Array<{ sheet: string; ref: string; value: string; formula?: string }> = []\n const order = (\n workbook.sheetOrder?.length ? workbook.sheetOrder : Object.keys(workbook.sheets ?? {})\n ).filter((id) => workbook.sheets?.[id])\n\n for (const id of order) {\n const sheet = workbook.sheets?.[id] as WorksheetData\n const cellData = sheet.cellData ?? {}\n for (const r of numericKeys(cellData)) {\n for (const c of numericKeys(cellData[r])) {\n const cell = cellData[r]?.[c]\n const text = cellText(cell)\n const formula = cell?.f\n if (!text.toLowerCase().includes(query) && !(formula ?? \"\").toLowerCase().includes(query)) {\n continue\n }\n matches.push({\n sheet: sheet.name ?? id,\n ref: cellRef(r, c),\n value: text,\n ...(formula ? { formula } : {}),\n })\n if (matches.length >= limit) return { matches, total: matches.length, capped: true }\n }\n }\n }\n return { matches, total: matches.length }\n}\n\n/* -------------------------------- 写 -------------------------------- */\n\nexport type SheetCellInput = string | number | boolean | null\n\nexport interface SetValuesArgs {\n sheet?: string\n /** 写入区域左上角,A1 形式(如 \"B2\") */\n start: string\n /** 二维数组,各行等长。\"=…\" 是公式,null 清空该格 */\n values: SheetCellInput[][]\n}\n\nexport function setValues(univerAPI: unknown, args: SetValuesArgs) {\n const start = args?.start ? parseCellRef(args.start) : undefined\n if (!start) throw new Error(`start 不合法:「${args?.start ?? \"\"}」。要单格 A1 形式,如 \"B2\"`)\n const rows = args.values\n if (!Array.isArray(rows) || !rows.length || !Array.isArray(rows[0])) {\n throw new Error(\"values 要是二维数组:[[行1格1, 行1格2], [行2格1, …]]\")\n }\n const width = (rows[0] as SheetCellInput[]).length\n if (!width) throw new Error(\"values 的行不能是空数组\")\n for (const [i, row] of rows.entries()) {\n if (!Array.isArray(row) || row.length !== width) {\n throw new Error(\n `values 各行要等长:第 1 行 ${width} 格,第 ${i + 1} 行 ${Array.isArray(row) ? row.length : \"?\"} 格。` +\n \"不想改的格子请缩小区域分多次写,null 表示清空\",\n )\n }\n }\n\n const book = activeWorkbook(univerAPI)\n const sheet = sheetByRef(book, args.sheet)\n const cells = rows.map((row) =>\n row.map((value) => {\n if (typeof value === \"string\" && value.startsWith(\"=\")) return { f: value }\n return { v: value }\n }),\n )\n const range = rangeOf(sheet, start.row, start.column, rows.length, width)\n setRangeValues(range, cells)\n\n const endRef = cellRef(start.row + rows.length - 1, start.column + width - 1)\n return {\n sheet: sheet.name,\n range: `${cellRef(start.row, start.column)}:${endRef}`,\n written: rows.length * width,\n }\n}\n\nexport interface EditRowsColsArgs {\n sheet?: string\n action: \"insert_rows\" | \"delete_rows\" | \"insert_cols\" | \"delete_cols\"\n /** 0-based。insert 在此位置**之前**插入;delete 从此位置开始删 */\n index: number\n /** 默认 1 */\n count?: number\n}\n\nexport function editRowsCols(univerAPI: unknown, args: EditRowsColsArgs) {\n const index = args?.index\n if (!Number.isInteger(index) || index < 0) throw new Error(\"index 要是 ≥0 的整数(0-based)\")\n const count = args.count ?? 1\n if (!Number.isInteger(count) || count < 1) throw new Error(\"count 要是 ≥1 的整数\")\n\n const book = activeWorkbook(univerAPI)\n const sheet = sheetByRef(book, args.sheet)\n\n switch (args.action) {\n case \"insert_rows\":\n insertRows(sheet, index, count)\n break\n case \"delete_rows\":\n deleteRows(sheet, index, count)\n break\n case \"insert_cols\":\n insertColumns(sheet, index, count)\n break\n case \"delete_cols\":\n deleteColumns(sheet, index, count)\n break\n default:\n throw new Error(`未知 action「${String(args.action)}」`)\n }\n return { sheet: sheet.name, action: args.action, index, count }\n}\n\nexport interface ManageSheetsArgs {\n action: \"add\" | \"rename\" | \"delete\" | \"activate\"\n /** rename / delete / activate 的目标(id 或表名) */\n sheet?: string\n /** add 的表名 / rename 的新名 */\n name?: string\n}\n\nexport function manageSheets(univerAPI: unknown, args: ManageSheetsArgs) {\n const book = activeWorkbook(univerAPI)\n\n const done = (detail: Record<string, unknown>) => ({\n ...detail,\n sheets: listSheets(book).map((s: SheetHandle) => ({ id: s.id, name: s.name })),\n })\n\n switch (args?.action) {\n case \"add\":\n return done({ action: \"add\", added: addSheet(book, args.name).name })\n case \"rename\": {\n if (!args.name) throw new Error(\"rename 需要 name(新表名)\")\n const sheet = sheetByRef(book, args.sheet)\n renameSheet(sheet, args.name)\n return done({ action: \"rename\", from: sheet.name, to: args.name })\n }\n case \"delete\": {\n if (!args.sheet) throw new Error(\"delete 需要 sheet(表 id 或表名)—— 不允许默认删活动表\")\n const sheet = sheetByRef(book, args.sheet)\n deleteSheet(book, sheet)\n return done({ action: \"delete\", deleted: sheet.name })\n }\n case \"activate\": {\n const sheet = sheetByRef(book, args.sheet)\n activateSheet(book, sheet)\n return done({ action: \"activate\", active: sheet.name })\n }\n default:\n throw new Error(`未知 action「${String(args?.action)}」,可用:add rename delete activate`)\n }\n}\n\n/* ------------------------------ 导出 ------------------------------ */\n\n/** 字节 → base64。浏览器没有 Buffer,得分块 btoa(一把梭会爆调用栈) */\nfunction bytesToBase64(bytes: Uint8Array): string {\n const B = (globalThis as { Buffer?: { from(b: Uint8Array): { toString(e: string): string } } })\n .Buffer\n if (B) return B.from(bytes).toString(\"base64\")\n let bin = \"\"\n const CHUNK = 0x8000\n for (let i = 0; i < bytes.length; i += CHUNK) {\n bin += String.fromCharCode(...bytes.subarray(i, i + CHUNK))\n }\n return btoa(bin)\n}\n\n/** 文件名消毒:只留基名,挡掉路径分隔符和 `..`。hub 那边还会再校验一次 */\nfunction sanitizeFilename(name: string | undefined): string | null {\n if (!name) return null\n const base = name.split(/[/\\\\]/).pop()?.trim()\n if (!base || base === \".\" || base === \"..\") return null\n return /\\.xlsx$/i.test(base) ? base : `${base}.xlsx`\n}\n\nexport async function exportXlsxBase64(univerAPI: unknown, args: { filename?: string } = {}) {\n // 动态 import:fflate 的 zip 只在真的导出时才需要\n const { exportXlsx } = await import(\"../xlsx/index.ts\")\n const { bytes, warnings, stats } = exportXlsx(univerAPI)\n return {\n filename: sanitizeFilename(args.filename) ?? \"工作簿.xlsx\",\n base64: bytesToBase64(bytes),\n bytes: bytes.length,\n warnings,\n stats,\n }\n}\n","/**\n * SheetRuntime —— 包着一个 Univer facade(FUniver)实例的结构化操作面。\n *\n * **这层不知道 MCP 存在**,也不知道 HTTP、WebSocket、tool schema 存在。\n * 和 `DocRuntime` 完全对称:`setUniverAPI` / `isReady` / 一组方法 / `call` 分发。\n * 工具定义和传输在 `@4399ywkf/editor-mcp`。\n *\n * ```tsx\n * const runtime = useMemo(() => new SheetRuntime(), [])\n * <DocumentView format=\"sheet\" onReady={(api) => runtime.setUniverAPI(api)} />\n * ```\n */\n\nimport {\n type EditRowsColsArgs,\n editRowsCols,\n exportXlsxBase64,\n findInWorkbook,\n type ManageSheetsArgs,\n manageSheets,\n readSheet,\n type SetValuesArgs,\n type SheetFindArgs,\n type SheetReadArgs,\n setValues,\n} from \"./operations.ts\"\n\nexport class SheetRuntime {\n private univerAPI: unknown\n\n constructor(univerAPI?: unknown) {\n this.univerAPI = univerAPI ?? null\n }\n\n /** Univer 实例就绪 / 卸载时调用。配合 `<DocumentView onReady>` 用。 */\n setUniverAPI(univerAPI: unknown): void {\n this.univerAPI = univerAPI\n }\n\n isReady(): boolean {\n return Boolean(this.univerAPI)\n }\n\n private use(): unknown {\n if (!this.univerAPI) throw new Error(\"表格尚未就绪:先调 setUniverAPI(univerAPI)\")\n return this.univerAPI\n }\n\n /* ------------------------------ 读 ------------------------------ */\n\n /** 工作簿概览 + 一张表的 CSV 视图与公式清单。要写之前先调它看清现状。 */\n read(args: SheetReadArgs = {}) {\n return readSheet(this.use(), args)\n }\n\n /** 全簿检索(值和公式都搜),返回可回填给写工具的 sheet + ref。 */\n find(args: SheetFindArgs) {\n return findInWorkbook(this.use(), args)\n }\n\n /* ------------------------------ 写 ------------------------------ */\n\n /** 从 start 起写一块二维值。\"=…\" 是公式,null 清空。 */\n setValues(args: SetValuesArgs) {\n return setValues(this.use(), args)\n }\n\n /** 插入 / 删除行列。 */\n editRowsCols(args: EditRowsColsArgs) {\n return editRowsCols(this.use(), args)\n }\n\n /** 新建 / 重命名 / 删除 / 激活工作表。 */\n manageSheets(args: ManageSheetsArgs) {\n return manageSheets(this.use(), args)\n }\n\n /* ------------------------------ 导出 ------------------------------ */\n\n /** 导出 .xlsx(base64 给传输层,模型只看路径 —— 和 doc_export_docx 同一约定)。 */\n exportXlsx(args: { filename?: string } = {}) {\n return exportXlsxBase64(this.use(), args)\n }\n\n /* ---------------------------- 统一入口 ---------------------------- */\n\n /**\n * 工具名 → 方法。给传输层(MCP 桥、agent executor)用的单一分发口,\n * 和 `DocRuntime.call` 同构 —— 桥不需要知道自己面对的是文档还是表格。\n */\n async call(tool: string, args: Record<string, unknown> = {}): Promise<unknown> {\n switch (tool) {\n case \"sheet_read\":\n return this.read(args as SheetReadArgs)\n case \"sheet_find\":\n return this.find(args as unknown as SheetFindArgs)\n case \"sheet_set_values\":\n return this.setValues(args as unknown as SetValuesArgs)\n case \"sheet_edit_rows_cols\":\n return this.editRowsCols(args as unknown as EditRowsColsArgs)\n case \"sheet_manage_sheets\":\n return this.manageSheets(args as unknown as ManageSheetsArgs)\n case \"sheet_export_xlsx\":\n return this.exportXlsx(args as { filename?: string })\n default:\n throw new Error(`未知工具 ${tool}`)\n }\n }\n}\n"]}
|
package/dist/sheet.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { D as DocumentViewProps } from './registry-
|
|
2
|
-
export { S as SheetOptions, c as SheetUiOptions } from './registry-
|
|
1
|
+
import { D as DocumentViewProps } from './registry-XJFJXtZ_.js';
|
|
2
|
+
export { S as SheetOptions, c as SheetUiOptions } from './registry-XJFJXtZ_.js';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -9,12 +9,14 @@ import * as react from 'react';
|
|
|
9
9
|
* 前者要自建 Univer Server 且需商业授权,后者 63MB、license 字段为 None、
|
|
10
10
|
* 90/91 个 JS 被混淆、还会向 univer.ai 上报遥测 —— 不能进生产链路。
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* 导入导出都在本包 `./xlsx`:导出直接读 Univer 快照拼 OOXML,导入把
|
|
13
|
+
* xlsx/csv/tsv 解析成快照(`source` prop 走的就是这条路,File / Blob / URL
|
|
14
|
+
* 都收)。两个方向都不引 SheetJS,文档不出内网。导入丢了什么(图片、
|
|
15
|
+
* 条件格式等独立部件)通过 `onWarnings` 如实报告。
|
|
14
16
|
*
|
|
15
17
|
* 配置见 `SheetOptions`:UI 开关直接透传给 preset(Univer 的 class 是
|
|
16
18
|
* `univer-` 前缀的原子类,没有稳定选择器,CSS 硬藏靠不住),额外能力靠追加 preset。
|
|
17
19
|
*/
|
|
18
|
-
declare function SheetView({ content, readOnly, className, sheet, onReady, onError, }: DocumentViewProps): react.JSX.Element;
|
|
20
|
+
declare function SheetView({ source, content, readOnly, className, sheet, onReady, onError, onWarnings, }: DocumentViewProps): react.JSX.Element;
|
|
19
21
|
|
|
20
22
|
export { DocumentViewProps, SheetView };
|
package/dist/sheet.js
CHANGED