ooxml-excel-editor 1.1.0 → 1.3.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/CHANGELOG.md +154 -0
- package/README.md +206 -18
- package/dist/assets/exceljs.min-DH9BABny.js +23046 -0
- package/dist/assets/parse.worker-DIaMHX0x.js +2646 -0
- package/dist/chunks/plugin-overlay-DLb6sRhU.js +9005 -0
- package/dist/chunks/toolbar-icons-BcnMin5s.js +223 -0
- package/dist/components/ExcelViewer.vue.d.ts +172 -19
- package/dist/components/ExportProgressOverlay.vue.d.ts +11 -0
- package/dist/components/FilterPopup.vue.d.ts +4 -4
- package/dist/components/ViewerToolbar.vue.d.ts +2 -0
- package/dist/composables/useExcelDocument.d.ts +1 -0
- package/dist/core/edit/clipboard-html.d.ts +24 -0
- package/dist/core/edit/commands.d.ts +45 -1
- package/dist/core/edit/context-menu.d.ts +19 -0
- package/dist/core/edit/edit-controller.d.ts +70 -2
- package/dist/core/edit/editor-context.d.ts +18 -3
- package/dist/core/edit/editor-host.d.ts +6 -1
- package/dist/core/edit/permissions.d.ts +41 -2
- package/dist/core/edit/types.d.ts +62 -0
- package/dist/core/export/abort.d.ts +21 -0
- package/dist/core/export/exporter.d.ts +2 -1
- package/dist/core/export/types.d.ts +8 -0
- package/dist/core/export/wps-cellimages.d.ts +6 -0
- package/dist/core/export/xlsx-writer.d.ts +9 -0
- package/dist/core/format/color.d.ts +5 -0
- package/dist/core/format/number-format.d.ts +3 -0
- package/dist/core/layout/autofit.d.ts +3 -0
- package/dist/core/layout/grid-metrics.d.ts +14 -2
- package/dist/core/loader-json.d.ts +23 -0
- package/dist/core/model/clone.d.ts +3 -4
- package/dist/core/model/inspect.d.ts +43 -0
- package/dist/core/model/mutations.d.ts +16 -1
- package/dist/core/model/types.d.ts +44 -2
- package/dist/core/parser/cell-image-parser.d.ts +9 -0
- package/dist/core/parser/row-meta-parser.d.ts +3 -0
- package/dist/core/plugin.d.ts +144 -6
- package/dist/core/progress.d.ts +23 -0
- package/dist/core/render/canvas-renderer.d.ts +56 -2
- package/dist/core/render/conditional.d.ts +7 -0
- package/dist/core/template/style-overlay.d.ts +9 -0
- package/dist/core/viewer/controller.d.ts +209 -6
- package/dist/core/viewer/lightbox-host.d.ts +16 -0
- package/dist/core.js +1 -1
- package/dist/index.js +1169 -841
- package/dist/react/ExcelViewer.d.ts +143 -3
- package/dist/react/ExportProgressOverlay.d.ts +6 -0
- package/dist/react/use-excel-document.d.ts +2 -0
- package/dist/react.js +938 -335
- package/dist/style.css +1 -1
- package/dist/vue2.css +1 -0
- package/dist/vue2.js +10433 -0
- package/package.json +18 -6
- package/dist/chunks/plugin-overlay-Cfnn9EOi.js +0 -7144
- package/dist/chunks/worker-client.stub-BQVZfaLd.js +0 -7
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 右键上下文菜单宿主(框架无关 DOM)—— 挂到 document.body 的 fixed 菜单,点项执行 action + 关闭,
|
|
3
|
+
* 点外部 / Esc 关闭,贴边自动翻转。Vue / React 壳只把 contextmenu 事件转给 controller,菜单逻辑全在这。
|
|
4
|
+
*/
|
|
5
|
+
export interface MenuItem {
|
|
6
|
+
label?: string;
|
|
7
|
+
action?: () => void;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
/** true = 分隔线 */
|
|
10
|
+
separator?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare class ContextMenuHost {
|
|
13
|
+
private el;
|
|
14
|
+
private cleanup;
|
|
15
|
+
isOpen(): boolean;
|
|
16
|
+
show(x: number, y: number, items: MenuItem[]): void;
|
|
17
|
+
close(): void;
|
|
18
|
+
dispose(): void;
|
|
19
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { CellStyleOverride, ColumnInfo, ImageAnchor, MergeRange, RowInfo, SheetModel, WorkbookModel } from '../model/types';
|
|
2
2
|
import { CellValue } from '../model/data-access';
|
|
3
3
|
import { CellSnapshot } from '../model/snapshot';
|
|
4
|
-
import {
|
|
4
|
+
import { ParsedClipboard } from './clipboard-html';
|
|
5
|
+
import { CellPos, DimAxis, EditCommand } from './commands';
|
|
5
6
|
import { StructOp } from '../model/structure';
|
|
6
7
|
import { FormulaEngineFactory } from '../formula/engine';
|
|
7
|
-
export type EditEventName = 'cell-change' | 'edit-start' | 'edit-commit' | 'dim-change' | 'dirty-change' | 'image-change' | 'struct-change';
|
|
8
|
+
export type EditEventName = 'cell-change' | 'edit-start' | 'edit-commit' | 'dim-change' | 'dirty-change' | 'image-change' | 'struct-change' | 'permission-denied';
|
|
8
9
|
export type EditSource = 'api' | 'ui' | 'undo' | 'redo';
|
|
9
10
|
/** 结构变更事件载荷(增删行列;restore = 撤销/重做的整体还原) */
|
|
10
11
|
export interface StructChangePayload {
|
|
@@ -93,6 +94,14 @@ export declare class EditController {
|
|
|
93
94
|
editCell(row: number, col: number, value: CellValue): boolean;
|
|
94
95
|
/** 区域批量设值(2D,左上对齐 range.top/left);跳过只读格,返回是否有改动 */
|
|
95
96
|
editRange(range: MergeRange, values: CellValue[][]): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* 富粘贴(Excel/WPS 复制的 HTML 解析后):值 + 样式 + 合并 + 图片,**整体单次撤销**。
|
|
99
|
+
* start = 落点左上角。跳过只读格。一次 cloneWorkbook 快照 → 应用全部 → 压一条 restore-wb 逆。
|
|
100
|
+
*/
|
|
101
|
+
pasteRich(start: {
|
|
102
|
+
row: number;
|
|
103
|
+
col: number;
|
|
104
|
+
}, parsed: ParsedClipboard): boolean;
|
|
96
105
|
/** 清空区域(跳过只读) */
|
|
97
106
|
clearRange(range: MergeRange): boolean;
|
|
98
107
|
/** 给区域套样式覆盖(E5;跳过只读格)。返回是否有改动。前后 style 不同 → 发 cell-change。 */
|
|
@@ -102,6 +111,12 @@ export declare class EditController {
|
|
|
102
111
|
insertCols(at: number, count?: number): boolean;
|
|
103
112
|
deleteCols(at: number, count?: number): boolean;
|
|
104
113
|
private structEdit;
|
|
114
|
+
/** 合并区域(吸收相交旧合并,清空被覆盖格只留左上锚点)。单格不合并。
|
|
115
|
+
* Phase A 补漏 (2026-06-08): 区域内任一格只读 → 拒绝整次合并 + emit permission-denied. */
|
|
116
|
+
mergeCells(range: MergeRange): boolean;
|
|
117
|
+
/** 拆分:移除与区域相交的所有合并。
|
|
118
|
+
* Phase A 补漏 (2026-06-08): 区域内任一格只读 → 拒绝整次拆分 + emit permission-denied. */
|
|
119
|
+
unmergeCells(range: MergeRange): boolean;
|
|
105
120
|
/** 读当前表全部图片锚点(克隆,防外部改)。 */
|
|
106
121
|
getImages(): ImageAnchor[];
|
|
107
122
|
/** 加一张图,返回插入索引(失败 -1)。 */
|
|
@@ -113,8 +128,57 @@ export declare class EditController {
|
|
|
113
128
|
* baseline 须在变更前由调用方 ensureBaseline() 捕获。
|
|
114
129
|
*/
|
|
115
130
|
recordImageEdit(index: number, before: ImageAnchor, after: ImageAnchor): void;
|
|
131
|
+
/**
|
|
132
|
+
* 浮动图 → 单元格内嵌图(DISPIMG):把第 imageIndex 张浮动图塞进 (row,col) 格。
|
|
133
|
+
* 图缺字节不可转 → 返 false。入命令栈(undo 走整簿快照还原)。
|
|
134
|
+
*/
|
|
135
|
+
convertImageToCell(imageIndex: number, row: number, col: number): boolean;
|
|
136
|
+
/**
|
|
137
|
+
* 批量把多张浮动图嵌入各自的目标格(整表/整列);一次进撤销栈。返回成功嵌入的张数。
|
|
138
|
+
* targets 的 imageIndex 是调用前的浮动图索引(内部按降序 splice,索引互不干扰)。
|
|
139
|
+
* Phase A 补漏: 过滤掉目标格只读的 targets, denied 一次性 emit.
|
|
140
|
+
*/
|
|
141
|
+
convertImagesToCells(targets: {
|
|
142
|
+
imageIndex: number;
|
|
143
|
+
row: number;
|
|
144
|
+
col: number;
|
|
145
|
+
}[]): number;
|
|
146
|
+
/**
|
|
147
|
+
* 单元格内嵌图 → 浮动图:把 (row,col) 的 DISPIMG 拎出来变成浮动图(默认 96×96px)。
|
|
148
|
+
* 非内嵌图格 → 返 false。入命令栈。
|
|
149
|
+
* Phase A 补漏: 源格只读 → 拒绝 (拎出来意味着该格内容变了,属于修改).
|
|
150
|
+
*/
|
|
151
|
+
convertCellImageToFloat(row: number, col: number, size?: {
|
|
152
|
+
width: number;
|
|
153
|
+
height: number;
|
|
154
|
+
}): boolean;
|
|
155
|
+
/**
|
|
156
|
+
* 批量把多格 DISPIMG 拎成浮动图(选区批量反向);非内嵌图格自动跳过;一次进撤销栈。
|
|
157
|
+
* 返回成功转换的张数。
|
|
158
|
+
* Phase A 补漏: 过滤掉源格只读的, denied 一次性 emit.
|
|
159
|
+
*/
|
|
160
|
+
convertCellImagesToFloats(cells: {
|
|
161
|
+
row: number;
|
|
162
|
+
col: number;
|
|
163
|
+
size?: {
|
|
164
|
+
width: number;
|
|
165
|
+
height: number;
|
|
166
|
+
};
|
|
167
|
+
}[]): number;
|
|
116
168
|
/** 程序化设列宽/行高(API 路径:apply-via-command)。返回是否生效。 */
|
|
117
169
|
setDimension(axis: DimAxis, index: number, size: number): boolean;
|
|
170
|
+
/**
|
|
171
|
+
* 批量设维度尺寸 (Phase B, 2026-06-08). target 接 number | number[] | {from,to}.
|
|
172
|
+
* 多 index 时聚合成单次 restore-wb undo (跟 convertImagesToCells 范式一致).
|
|
173
|
+
* strictDimensions=true + 白名单未覆盖某 index → skip 那个 + 累计 deniedDims; 整次结束 emit 一次 permission-denied.
|
|
174
|
+
* 返回成功条数 (0 = 全 skip / editable=false).
|
|
175
|
+
*/
|
|
176
|
+
setDimensions(axis: DimAxis, indices: number[], size: number, canDim: (i: number) => boolean): number;
|
|
177
|
+
/**
|
|
178
|
+
* 重置某些列宽/行高到默认 (Phase B, 2026-06-08) — 移除 columns/rows Map 条目, 渲染回落 defaultColWidth/Height.
|
|
179
|
+
* 多 index 时单次 restore-wb undo.
|
|
180
|
+
*/
|
|
181
|
+
resetDimensions(axis: DimAxis, indices: number[], canDim: (i: number) => boolean): number;
|
|
118
182
|
/**
|
|
119
183
|
* 补登一次维度变更(拖拽/autofit 路径:模型已被 renderer 改完,这里只补 undo 项 + 发事件)。
|
|
120
184
|
* baseline 须在变更前(拖拽起始/autofit 前)由调用方 ensureBaseline() 捕获。
|
|
@@ -132,6 +196,10 @@ export declare class EditController {
|
|
|
132
196
|
redo(): void;
|
|
133
197
|
private collectEditable;
|
|
134
198
|
private pushUndo;
|
|
199
|
+
/** 公开版 pushUndo (Phase B 2026-06-08): 给 controller 的批量 autoFit 用. 一般业务不要直调. */
|
|
200
|
+
pushUndoExternal(inverse: EditCommand): void;
|
|
201
|
+
/** 公开版 markDirty: 给 controller 的批量 autoFit 用. 一般业务不要直调. */
|
|
202
|
+
markDirtyExternal(): void;
|
|
135
203
|
/** 应用一条命令:建前快照 → apply → 重绘 → 发事件(cell 族 cell-change / dim 族 dim-change)。返回逆命令。 */
|
|
136
204
|
private exec;
|
|
137
205
|
}
|
|
@@ -27,12 +27,27 @@ export interface CellEditorContext {
|
|
|
27
27
|
commit(value: EditorCommitValue, move?: 'down' | 'right'): void;
|
|
28
28
|
/** 取消编辑(不改模型) */
|
|
29
29
|
cancel(): void;
|
|
30
|
+
/**
|
|
31
|
+
* 请求 host 重新 position 编辑器 (Phase 1 长文本撑高用, 2026-06-08).
|
|
32
|
+
* 编辑器在内容变化(input 事件)后调一次, host 会重新读 `getDesiredHeight()` 并撑高.
|
|
33
|
+
* 不实现 `getDesiredHeight` 的编辑器调它无效(仍按 cell rect 尺寸).
|
|
34
|
+
*/
|
|
35
|
+
reposition?(): void;
|
|
30
36
|
}
|
|
31
|
-
/**
|
|
32
|
-
|
|
37
|
+
/**
|
|
38
|
+
* 编辑器工厂的返回类型:可以是裸 HTMLElement, 或带钩子的对象.
|
|
39
|
+
* - `destroy`: 卸载时清理(可选)
|
|
40
|
+
* - `getDesiredHeight`: Phase 1 长文本撑高用. host 在 position 时调, 传入当前列宽 (px),
|
|
41
|
+
* 编辑器返回内容期望的总高度 (px). host 取 max(原 cell h, desired) 作为最终高度.
|
|
42
|
+
* 不实现 = 高度锁定为单元格高度(老行为).
|
|
43
|
+
*/
|
|
44
|
+
export interface CellEditorReturn {
|
|
33
45
|
el: HTMLElement;
|
|
34
46
|
destroy?: () => void;
|
|
35
|
-
|
|
47
|
+
getDesiredHeight?(widthPx: number): number;
|
|
48
|
+
}
|
|
49
|
+
/** 编辑器工厂:返回 DOM 元素,或 { el, destroy?, getDesiredHeight? }(destroy 在卸载时清理) */
|
|
50
|
+
export type CellEditorFactory = (ctx: CellEditorContext) => HTMLElement | CellEditorReturn;
|
|
36
51
|
/** 编辑器解析器:按格决定用哪个工厂(无 → 该格无自定义编辑器) */
|
|
37
52
|
export type EditorResolver = (cell: CellModel | null, pos: {
|
|
38
53
|
row: number;
|
|
@@ -14,7 +14,12 @@ export declare class CellEditorHost {
|
|
|
14
14
|
* rectOverride 给定时用它定位(合并单元格 → 整片合并区),否则按单格 rectOf。
|
|
15
15
|
*/
|
|
16
16
|
mount(row: number, col: number, factory: CellEditorFactory, ctx: CellEditorContext, rectOverride?: () => Rect | null): boolean;
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* 按当前 rectOf 重定位活动编辑器(滚动/缩放后跟随).
|
|
19
|
+
* Phase 1 长文本撑高 (2026-06-08): 若编辑器实现了 `getDesiredHeight`,
|
|
20
|
+
* 最终高度 = max(单元格原高, 期望高度), 上限 viewport 一半防撑爆.
|
|
21
|
+
* 宽度仍 = 列宽 (跟 WPS 一致, 仅向下溢出).
|
|
22
|
+
*/
|
|
18
23
|
position(): void;
|
|
19
24
|
/** 卸载活动编辑器 */
|
|
20
25
|
unmount(): void;
|
|
@@ -1,3 +1,42 @@
|
|
|
1
|
-
import { SheetModel } from '../model/types';
|
|
2
|
-
import { EditConfig } from './types';
|
|
1
|
+
import { MergeRange, SheetModel } from '../model/types';
|
|
2
|
+
import { DimTarget, EditableTarget, EditConfig } from './types';
|
|
3
|
+
/** 把 DimTarget 3 形态规范化成 index 数组. 重复 / 越界由调用方各自处理. */
|
|
4
|
+
export declare function normalizeDimTarget(target: DimTarget): number[];
|
|
5
|
+
/**
|
|
6
|
+
* 该列/行能否改尺寸 (Phase B, 2026-06-08).
|
|
7
|
+
* - editable=false → 一律 false
|
|
8
|
+
* - strictDimensions=false (默认) → 仅受全局 editable 控制, 一律 true
|
|
9
|
+
* - strictDimensions=true + 没设白名单 → true (没白名单 = 默认全可编辑)
|
|
10
|
+
* - strictDimensions=true + 设了白名单 → 该轴 index 上至少 1 格在白名单内才 true
|
|
11
|
+
*/
|
|
12
|
+
export declare function canEditDimension(sheet: SheetModel, axis: 'col' | 'row', index: number, cfg: EditConfig): boolean;
|
|
13
|
+
/** 单格 / 行 / 列 / 区域 四态 target 命中判定. 形状由有哪些字段自动识别. */
|
|
14
|
+
export declare function matchesEditableTarget(row: number, col: number, t: EditableTarget): boolean;
|
|
15
|
+
/** 把一组格按"是否可编辑"二分. 用于粘贴 / 图片转换 等"批量目标 + 部分跳过"场景. */
|
|
16
|
+
export declare function partitionByEditable(sheet: SheetModel, cells: Array<{
|
|
17
|
+
row: number;
|
|
18
|
+
col: number;
|
|
19
|
+
}>, cfg: EditConfig): {
|
|
20
|
+
allowed: Array<{
|
|
21
|
+
row: number;
|
|
22
|
+
col: number;
|
|
23
|
+
}>;
|
|
24
|
+
denied: Array<{
|
|
25
|
+
row: number;
|
|
26
|
+
col: number;
|
|
27
|
+
}>;
|
|
28
|
+
};
|
|
29
|
+
/** 区域是否**全可编辑**(任一格只读即返 ok=false + firstDenied). 用于 mergeCells / unmergeCells. */
|
|
30
|
+
export declare function rangeAllEditable(sheet: SheetModel, range: MergeRange, cfg: EditConfig): {
|
|
31
|
+
ok: boolean;
|
|
32
|
+
firstDenied?: {
|
|
33
|
+
row: number;
|
|
34
|
+
col: number;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
/** 收集区域里全部不可编辑的格(用于 emit permission-denied 时填 cells 列表). */
|
|
38
|
+
export declare function collectDeniedInRange(sheet: SheetModel, range: MergeRange, cfg: EditConfig): Array<{
|
|
39
|
+
row: number;
|
|
40
|
+
col: number;
|
|
41
|
+
}>;
|
|
3
42
|
export declare function resolveEditable(sheet: SheetModel, row: number, col: number, cfg: EditConfig): boolean;
|
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
import { CellModel, MergeRange } from '../model/types';
|
|
2
2
|
import { FormulaEngineFactory } from '../formula/engine';
|
|
3
|
+
/**
|
|
4
|
+
* 行/列维度目标 (Phase B, 2026-06-08) —— 用于尺寸 API (setColumnWidth / setRowHeight /
|
|
5
|
+
* autoFitColumns / resetColumnWidth ...) 的参数. 3 种形状自动识别:
|
|
6
|
+
*
|
|
7
|
+
* ┌────────────────────┬──────────────────────────┐
|
|
8
|
+
* │ 形状 │ 含义 │
|
|
9
|
+
* ├────────────────────┼──────────────────────────┤
|
|
10
|
+
* │ `number` │ 单个 index │
|
|
11
|
+
* │ `number[]` │ 多 index (允许不相邻) │
|
|
12
|
+
* │ `{ from, to }` │ 闭区间范围 │
|
|
13
|
+
* └────────────────────┴──────────────────────────┘
|
|
14
|
+
*/
|
|
15
|
+
export type DimTarget = number | number[] | {
|
|
16
|
+
from: number;
|
|
17
|
+
to: number;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* 可编辑目标 —— 用于 `EditConfig.editableTargets` 的白名单元素;接受 4 种形状,
|
|
21
|
+
* 自动识别(看带哪些字段):
|
|
22
|
+
*
|
|
23
|
+
* ┌──────────────────────────────────────┬─────────────────────────────┐
|
|
24
|
+
* │ 形状 │ 含义 │
|
|
25
|
+
* ├──────────────────────────────────────┼─────────────────────────────┤
|
|
26
|
+
* │ `{ row, col }` │ 单格(命中精确这一格) │
|
|
27
|
+
* │ `{ row }` │ 整行(该行所有列) │
|
|
28
|
+
* │ `{ col }` │ 整列(该列所有行) │
|
|
29
|
+
* │ `{ top, left, bottom, right }` │ 矩形区域(0-based 闭区间) │
|
|
30
|
+
* └──────────────────────────────────────┴─────────────────────────────┘
|
|
31
|
+
*
|
|
32
|
+
* 多个 target 可以**重叠 / 不相邻**;命中**任一**就算可编辑。
|
|
33
|
+
*/
|
|
34
|
+
export type EditableTarget = {
|
|
35
|
+
row: number;
|
|
36
|
+
col: number;
|
|
37
|
+
} | {
|
|
38
|
+
row: number;
|
|
39
|
+
col?: undefined;
|
|
40
|
+
} | {
|
|
41
|
+
col: number;
|
|
42
|
+
row?: undefined;
|
|
43
|
+
} | MergeRange;
|
|
3
44
|
export interface EditConfig {
|
|
4
45
|
/** 总开关:默认 false = 只读(行为与历史完全一致) */
|
|
5
46
|
editable?: boolean;
|
|
@@ -10,6 +51,27 @@ export interface EditConfig {
|
|
|
10
51
|
}) => boolean | void;
|
|
11
52
|
/** 只读区域(0-based 闭区间);命中即只读 */
|
|
12
53
|
readOnlyRanges?: MergeRange[];
|
|
54
|
+
/**
|
|
55
|
+
* **可编辑白名单**(2026-06-08 新增) —— 设了就是"白名单模式":默认只读,
|
|
56
|
+
* 只有命中**任一** target 的格才可编辑。**未设(undefined)= 默认全可编辑**
|
|
57
|
+
* (老行为)。**显式传空数组 `[]`** = 全只读(没格在白名单)。
|
|
58
|
+
*
|
|
59
|
+
* 用例: 协同编辑、点检表单只填几格、模板里只让用户改"金额"列等.
|
|
60
|
+
*
|
|
61
|
+
* 与黑名单组合(优先级): `editable=false` → 全只读 ► 不在白名单 → 只读 ►
|
|
62
|
+
* 命中 `readOnlyRanges` → 只读 ► `cellReadOnly` 返 true → 只读 ► 否则可编辑.
|
|
63
|
+
*/
|
|
64
|
+
editableTargets?: EditableTarget | EditableTarget[];
|
|
65
|
+
/**
|
|
66
|
+
* **严格尺寸闸门**(Phase B, 2026-06-08) —— 默认 `false`:setColumnWidth / setRowHeight /
|
|
67
|
+
* autoFit / resetDimensions 等尺寸 API 仅受 `editable` 全局闸门控制 (老行为, 简单).
|
|
68
|
+
*
|
|
69
|
+
* 设 `true` + 启用了 `editableTargets` 白名单 → 升级语义:**该列/行至少有 1 格在白名单内**
|
|
70
|
+
* 才能改它的宽高; 否则拒绝 + emit permission-denied (reason='dimension').
|
|
71
|
+
*
|
|
72
|
+
* 跟"白名单未覆盖 = 完全只读"的严格语义一致, 防"用户改不了数据但能改列宽行高"。
|
|
73
|
+
*/
|
|
74
|
+
strictDimensions?: boolean;
|
|
13
75
|
/**
|
|
14
76
|
* 公式重算(E4):默认 false = 沿用 Excel 缓存值(只读/无公式路径零成本)。
|
|
15
77
|
* 开启后,编辑公式格或被公式引用的格 → 依赖格自动重算并逐个发 cell-change。
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 长任务防假死 + 取消的两件小工具(框架无关)。
|
|
3
|
+
*
|
|
4
|
+
* 长导出(PDF / PNG / XLSX、批量图片转换)必须在循环中:
|
|
5
|
+
* 1. checkAborted(signal) — 用户调 abortController.abort() 立刻中断
|
|
6
|
+
* 2. await yieldToEvent() — 让出主线程跑一次绘制 / 事件,避免 UI 假死
|
|
7
|
+
* 配合 ExportProgress 的 onProgress 回调,使用者可显示进度条 + 取消按钮。
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* 让出主线程跑一帧。优先 requestAnimationFrame(浏览器),其次 setTimeout(node / worker 无 rAF)。
|
|
11
|
+
* 用 await yieldToEvent() 包在循环里防 UI 假死。返回 0 让调用方可选取用时间戳。
|
|
12
|
+
*/
|
|
13
|
+
export declare function yieldToEvent(): Promise<number>;
|
|
14
|
+
/**
|
|
15
|
+
* 抛 AbortError 让上层 try/catch 区分"取消"与"真出错"。
|
|
16
|
+
* AbortSignal 标准:`signal.aborted === true` 时调用方应 throw `DOMException('Aborted', 'AbortError')`。
|
|
17
|
+
* 跨环境兜底:Node 18+ / 现代浏览器 / Worker 均有 DOMException;无 DOMException 时回退普通 Error 但保留 name。
|
|
18
|
+
*/
|
|
19
|
+
export declare function checkAborted(signal?: AbortSignal): void;
|
|
20
|
+
/** 判断是否 AbortError(便于上层在 catch 里区分,避免吞掉真异常) */
|
|
21
|
+
export declare function isAbortError(e: unknown): boolean;
|
|
@@ -41,7 +41,8 @@ export declare class WorkbookExporter {
|
|
|
41
41
|
/** 导出当前/指定表为图片 Blob(图片为单表;多表请用 PDF) */
|
|
42
42
|
exportImage(opts?: ImageExportOptions): Promise<Blob>;
|
|
43
43
|
downloadImage(opts?: ImageExportOptions): Promise<void>;
|
|
44
|
-
/** 导出为 PDF Blob(每个目标表分页;需可选依赖 jspdf)。未显式指定的页面参数取自工作表 pageSetup。
|
|
44
|
+
/** 导出为 PDF Blob(每个目标表分页;需可选依赖 jspdf)。未显式指定的页面参数取自工作表 pageSetup。
|
|
45
|
+
* 支持 `onProgress` 分阶段(render/compose/paginate/write)报进度 + `signal` 取消(标准 AbortSignal)。 */
|
|
45
46
|
exportPdf(opts?: PdfExportOptions): Promise<Blob>;
|
|
46
47
|
downloadPdf(opts?: PdfExportOptions): Promise<void>;
|
|
47
48
|
/** 打开系统打印(可在对话框另存为 PDF)。页面参数同样默认取自 pageSetup。 */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MergeRange } from '../model/types';
|
|
2
|
+
import { ExportProgressFn } from '../progress';
|
|
2
3
|
/** 选哪些工作表导出 */
|
|
3
4
|
export type ExportTarget = 'active' | 'all' | number | number[];
|
|
4
5
|
/** 公共渲染选项(决定底图怎么画) */
|
|
@@ -13,6 +14,13 @@ export interface RenderExportOptions {
|
|
|
13
14
|
gridlines?: boolean;
|
|
14
15
|
/** 背景色(默认白) */
|
|
15
16
|
background?: string;
|
|
17
|
+
/**
|
|
18
|
+
* 长任务进度回调。每个调度阶段(render/compose/paginate/write/zip)各 emit。
|
|
19
|
+
* 大表 / 多表 / 多页时穿插 `await yieldToEvent()` 避免 UI 假死。
|
|
20
|
+
*/
|
|
21
|
+
onProgress?: ExportProgressFn;
|
|
22
|
+
/** 取消信号。`abortController.abort()` 后下一个调度点抛 AbortError(标准语义) */
|
|
23
|
+
signal?: AbortSignal;
|
|
16
24
|
}
|
|
17
25
|
/** 图片导出选项 */
|
|
18
26
|
export interface ImageExportOptions extends RenderExportOptions {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { WorkbookModel } from '../model/types';
|
|
2
|
+
import { ExportProgressFn } from '../progress';
|
|
2
3
|
export interface XlsxExportOptions {
|
|
3
4
|
/**
|
|
4
5
|
* 保真模式:
|
|
@@ -6,10 +7,18 @@ export interface XlsxExportOptions {
|
|
|
6
7
|
* - `'overlay'`:重载原始 .xlsx,只把编辑后的 值/样式/合并/行高列宽/冻结 叠加上去,**保留** ExcelJS
|
|
7
8
|
* 能往返的其余部分(条件格式/数据验证/打印设置/定义名/图表等)。需 `sourceBuffer`(壳自动注入);
|
|
8
9
|
* 缺原件时自动回退 rebuild。注:overlay 不反映 结构增删行列 / 图片 编辑(那类用 rebuild)。
|
|
10
|
+
*
|
|
11
|
+
* WPS 单元格内嵌图(DISPIMG):两种模式都会在 ExcelJS 写出后**于 zip 层回注** `xl/cellimages.xml`
|
|
12
|
+
* + rels + media + Content_Types/workbook-rels(见 wps-cellimages.ts),从模型重建 → 原有的 + App 内
|
|
13
|
+
* 新转的内嵌图导出后都在(blob-only 无字节的图除外)。导出 → 用 WPS 打开,内嵌图正常显示。
|
|
9
14
|
*/
|
|
10
15
|
fidelity?: 'rebuild' | 'overlay';
|
|
11
16
|
/** 原始 .xlsx 字节(overlay 模式用;由 exporter 从 host 注入,用方一般不直接传) */
|
|
12
17
|
sourceBuffer?: ArrayBuffer;
|
|
18
|
+
/** 长任务进度回调(zip 写出前/后 emit `{stage:'zip'}`;exceljs writeBuffer 黑盒) */
|
|
19
|
+
onProgress?: ExportProgressFn;
|
|
20
|
+
/** 取消信号(zip 阶段前后检查) */
|
|
21
|
+
signal?: AbortSignal;
|
|
13
22
|
}
|
|
14
23
|
/** WorkbookModel → .xlsx Blob(懒加载 exceljs)。overlay 模式重载原件叠加编辑,否则从模型重建。 */
|
|
15
24
|
export declare function workbookToXlsxBlob(workbook: WorkbookModel, opts?: XlsxExportOptions): Promise<Blob>;
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { CssColor } from '../model/types';
|
|
2
2
|
export declare function argbToCss(argb: string | undefined): CssColor | undefined;
|
|
3
|
+
/**
|
|
4
|
+
* 任意 css 颜色 → `#RRGGBB`(大写);供 <input type=color> 回显 / 粘贴样式解析。
|
|
5
|
+
* 支持 #RGB / #RRGGBB / #RRGGBBAA / rgb()/rgba();识别不了返 ''。
|
|
6
|
+
*/
|
|
7
|
+
export declare function toHex6(css: string | undefined): string;
|
|
3
8
|
export declare function indexedToCss(idx: number): CssColor | undefined;
|
|
4
9
|
/** 主题色 + tint → css。tint > 0 变亮,< 0 变暗(按 OOXML 规范的 HSL Luminance 调整)。 */
|
|
5
10
|
export declare function themeToCss(themeColors: CssColor[], themeIdx: number, tint?: number): CssColor | undefined;
|
|
@@ -3,3 +3,6 @@ export interface FormatResult {
|
|
|
3
3
|
color?: string;
|
|
4
4
|
}
|
|
5
5
|
export declare function formatValue(value: number | string | boolean | Date | null, code: string | undefined, date1904?: boolean): FormatResult;
|
|
6
|
+
/** Date → Excel 序列号(导出/往返用). date1904=true 时 epoch=1904-01-01;
|
|
7
|
+
* 1900 系统时跳过 phantom 1900-02-29(序号 ≥ 60 加 1 补回 bug 偏移). */
|
|
8
|
+
export declare function dateToSerial(date: Date, date1904: boolean): number;
|
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
import { SheetModel, WorkbookModel } from '../model/types';
|
|
2
|
+
/** 失效某 sheet 的"已 fit"标记;下次 autoFitRowHeights 会重新测量。
|
|
3
|
+
* 用法:模型有结构性变化(wrapText 切换 / 富文本编辑 / 列宽改) → 行高需按新内容重撑 → 调一次。 */
|
|
4
|
+
export declare function invalidateAutofit(sheet: SheetModel): void;
|
|
2
5
|
export declare function autoFitRowHeights(sheet: SheetModel, workbook: WorkbookModel, ctx?: CanvasRenderingContext2D): void;
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import { SheetModel } from '../model/types';
|
|
2
|
+
/** Excel/WPS 网格上限:行 1,048,576 / 列 16,384(虚拟外推封顶,防失控) */
|
|
3
|
+
export declare const MAX_GRID_ROWS = 1048576;
|
|
4
|
+
export declare const MAX_GRID_COLS = 16384;
|
|
2
5
|
export declare class GridMetrics {
|
|
3
6
|
private sheet;
|
|
4
7
|
readonly cols: number;
|
|
5
8
|
readonly rows: number;
|
|
9
|
+
/**
|
|
10
|
+
* 虚拟行/列上限(≥ dimension,≤ Excel 上限)。**仅**用于"滚动出空行"的 spacer 尺寸 /
|
|
11
|
+
* 可视区范围 / 命中夹取 / 表头;**不**改 totalWidth/Height(导出与 data-access 仍按 dimension)。
|
|
12
|
+
*/
|
|
13
|
+
readonly vRows: number;
|
|
14
|
+
readonly vCols: number;
|
|
6
15
|
/** 行表头(显示行号)宽度 px */
|
|
7
16
|
readonly rowHeaderWidth: number;
|
|
8
17
|
/** 列表头(显示列字母)高度 px */
|
|
@@ -13,7 +22,7 @@ export declare class GridMetrics {
|
|
|
13
22
|
private rowHeights;
|
|
14
23
|
/** 当前缩放比例(几何与字体同步按它缩放,保证缩放后排版一致) */
|
|
15
24
|
readonly zoom: number;
|
|
16
|
-
constructor(sheet: SheetModel, zoom?: number);
|
|
25
|
+
constructor(sheet: SheetModel, zoom?: number, virtualRows?: number, virtualCols?: number);
|
|
17
26
|
colWidth(c: number): number;
|
|
18
27
|
rowHeight(r: number): number;
|
|
19
28
|
private get dcw();
|
|
@@ -23,10 +32,13 @@ export declare class GridMetrics {
|
|
|
23
32
|
rowTop(r: number): number;
|
|
24
33
|
get totalWidth(): number;
|
|
25
34
|
get totalHeight(): number;
|
|
35
|
+
/** 含虚拟外推的总宽/高(spacer 尺寸用;= totalWidth + 虚拟列外推) */
|
|
36
|
+
get virtualWidth(): number;
|
|
37
|
+
get virtualHeight(): number;
|
|
26
38
|
/** 给定网格 x 坐标,返回所在列。超出数据范围按默认列宽外推。 */
|
|
27
39
|
colAt(x: number): number;
|
|
28
40
|
rowAt(y: number): number;
|
|
29
|
-
/** 数据单元格的可视区列区间(end
|
|
41
|
+
/** 数据单元格的可视区列区间(end 夹到虚拟范围 vCols-1,允许滚动出空列;空格 paint 为 no-op) */
|
|
30
42
|
visibleColRange(scrollX: number, viewW: number): [number, number];
|
|
31
43
|
visibleRowRange(scrollY: number, viewH: number): [number, number];
|
|
32
44
|
/** 网格线/表头的可视区列区间(可超出数据范围,铺满视口,模拟 Excel) */
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { WorkbookModel } from './model/types';
|
|
2
|
+
export type JsonRow = unknown[] | Record<string, unknown>;
|
|
3
|
+
export type JsonSheetInput = {
|
|
4
|
+
name?: string;
|
|
5
|
+
rows: JsonRow[];
|
|
6
|
+
};
|
|
7
|
+
export type JsonInput = unknown[][] | Record<string, unknown>[] | {
|
|
8
|
+
sheets: JsonSheetInput[];
|
|
9
|
+
};
|
|
10
|
+
export interface JsonLoadOptions {
|
|
11
|
+
/** 对象数组:首行写表头(键名);默认 true。`false` 直接从首行起当数据(用 columns 控制顺序) */
|
|
12
|
+
headerRow?: boolean;
|
|
13
|
+
/** 单表 / 默认表名,缺省 'Sheet1' */
|
|
14
|
+
sheetName?: string;
|
|
15
|
+
/** 主题色 17 色调色板;不给用全黑兜底 */
|
|
16
|
+
themeColors?: string[];
|
|
17
|
+
/** 数字串 → 数字、'TRUE'/'FALSE' → boolean、ISO 日期串 → Date(默认 true) */
|
|
18
|
+
autoInfer?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** JSON → WorkbookModel。input shape 自动识别。 */
|
|
21
|
+
export declare function jsonToWorkbook(input: JsonInput, opts?: JsonLoadOptions): WorkbookModel;
|
|
22
|
+
/** 用方传 WorkbookModel-shape 时的浅校验(壳分支用) */
|
|
23
|
+
export declare function isWorkbookModel(v: unknown): v is WorkbookModel;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { WorkbookModel } from './types';
|
|
2
|
-
/**
|
|
2
|
+
/** 轻量深克隆整个工作簿(供 editable 懒捕获 baseline + 结构编辑 undo 快照)。 */
|
|
3
3
|
export declare function cloneWorkbook(wb: WorkbookModel): WorkbookModel;
|
|
4
4
|
/**
|
|
5
|
-
* 把 baseline(snap)的内容就地还原进 live(不换 live / live.sheets / 各 sheet 的对象身份)。
|
|
6
|
-
*
|
|
7
|
-
* 约定:editing 期间不增删 sheet,故按 index 对齐;多出的 live sheet 不动。
|
|
5
|
+
* 把 baseline/快照(snap)的内容就地还原进 live(不换 live / live.sheets / 各 sheet 的对象身份)。
|
|
6
|
+
* 每次对 snap 取一份新轻量克隆,故 snap 自身保持可重复还原(redo / 多次 reset)。
|
|
8
7
|
*/
|
|
9
8
|
export declare function restoreWorkbookInto(live: WorkbookModel, snap: WorkbookModel): void;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { CellStyleOverride, ImageAnchor, MergeRange, SheetModel, WorkbookModel } from './types';
|
|
2
|
+
import { CellSnapshot } from './snapshot';
|
|
3
|
+
export interface CellInspection extends CellSnapshot {
|
|
4
|
+
/** 该格所属合并区(锚点格 = 自身;被覆盖格 = 覆盖它的;否则 null) */
|
|
5
|
+
merge: MergeRange | null;
|
|
6
|
+
/** 是否合并区的左上锚点 */
|
|
7
|
+
isMergeAnchor: boolean;
|
|
8
|
+
/** 覆盖到该格的浮动图(按 sheet.images 索引 + 锚点克隆) */
|
|
9
|
+
floatingImages: Array<{
|
|
10
|
+
index: number;
|
|
11
|
+
anchor: ImageAnchor;
|
|
12
|
+
}>;
|
|
13
|
+
/** WPS 单元格内嵌图(DISPIMG) */
|
|
14
|
+
cellImage: {
|
|
15
|
+
id: string;
|
|
16
|
+
src: string;
|
|
17
|
+
mime?: string;
|
|
18
|
+
} | null;
|
|
19
|
+
/** 命中的数据验证范围(无则 null;详细规则字段当前模型未建模) */
|
|
20
|
+
dataValidation: MergeRange | null;
|
|
21
|
+
/** 命中的条件格式规则索引 + 该规则计算后的等效样式 */
|
|
22
|
+
conditional: Array<{
|
|
23
|
+
ruleIndex: number;
|
|
24
|
+
style: CellStyleOverride;
|
|
25
|
+
}>;
|
|
26
|
+
/** 直读 cell.hyperlink(便于不深入 cell 字段) */
|
|
27
|
+
hyperlink: string | null;
|
|
28
|
+
/** 直读 cell.comment */
|
|
29
|
+
comment: string | null;
|
|
30
|
+
}
|
|
31
|
+
/** 该格落在哪个合并区(锚点 / 被覆盖均算);否则 null */
|
|
32
|
+
export declare function findMergeAt(sheet: SheetModel, row: number, col: number): MergeRange | null;
|
|
33
|
+
/** 一张浮动图的锚点是否覆盖到 (row,col)。twoCellAnchor 用 from..to 矩形;oneCellAnchor 仅 from 格。 */
|
|
34
|
+
export declare function imageAnchorContains(anchor: ImageAnchor, row: number, col: number): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* 聚合查询。
|
|
37
|
+
* @param sheet 工作表
|
|
38
|
+
* @param workbook 工作簿(用于 WPS 内嵌图登记表 cellImages)
|
|
39
|
+
* @param row 0-based
|
|
40
|
+
* @param col 0-based
|
|
41
|
+
* @param date1904 仅作 buildCellSnapshot 文本格式化用
|
|
42
|
+
*/
|
|
43
|
+
export declare function inspectCell(sheet: SheetModel, workbook: WorkbookModel, row: number, col: number, date1904: boolean): CellInspection;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CellModel, CellStyle, CellStyleOverride, ColumnInfo, ImageAnchor, MergeRange, RowInfo, SheetModel } from './types';
|
|
1
|
+
import { CellModel, CellStyle, CellStyleOverride, ColumnInfo, ImageAnchor, MergeRange, RowInfo, SheetModel, WorkbookModel } from './types';
|
|
2
2
|
import { CellValue } from './data-access';
|
|
3
3
|
/** 设单元格值。返回旧 CellModel(克隆,供 undo);新值为空则删除该格。 */
|
|
4
4
|
export declare function setCellValue(sheet: SheetModel, row: number, col: number, value: CellValue): void;
|
|
@@ -23,6 +23,21 @@ export declare function cloneImageAnchor(a: ImageAnchor): ImageAnchor;
|
|
|
23
23
|
export declare function addImage(sheet: SheetModel, anchor: ImageAnchor, index?: number): number;
|
|
24
24
|
/** 删一张图(调用方负责为 undo 捕获前态)。 */
|
|
25
25
|
export declare function removeImage(sheet: SheetModel, index: number): void;
|
|
26
|
+
/**
|
|
27
|
+
* 浮动图 → WPS 单元格内嵌图(DISPIMG)。
|
|
28
|
+
* 取 sheet.images[imageIndex] 的字节登记到 wb.cellImages(新 id),目标格设 =DISPIMG 公式 + dispImgId,
|
|
29
|
+
* 移除该浮动图。返回新 id;图缺 bytes/mime 不可转 → 返 null(不动模型)。
|
|
30
|
+
*/
|
|
31
|
+
export declare function convertFloatToCellImage(wb: WorkbookModel, sheet: SheetModel, imageIndex: number, row: number, col: number): string | null;
|
|
32
|
+
/**
|
|
33
|
+
* WPS 单元格内嵌图 → 浮动图。
|
|
34
|
+
* 取 (row,col) 的 dispImgId 对应登记图,造一张 oneCellAnchor 浮动图锚在该格(默认尺寸 sizePx),
|
|
35
|
+
* 清空该格。登记表里若无其它格再引用该 id,一并回收。返回浮动图索引;非内嵌图格返 -1。
|
|
36
|
+
*/
|
|
37
|
+
export declare function convertCellImageToFloat(wb: WorkbookModel, sheet: SheetModel, row: number, col: number, size?: {
|
|
38
|
+
width: number;
|
|
39
|
+
height: number;
|
|
40
|
+
}): number;
|
|
26
41
|
/**
|
|
27
42
|
* 设图片的内容矩形(zoom 后像素,content 坐标)→ 规整为原点相对 oneCellAnchor。
|
|
28
43
|
* 像素↔EMU:left_px = emuToPx(colOffEmu)*zoom ⇒ colOffEmu = pxToEmu(left/zoom)。不依赖列/行几何。
|
|
@@ -85,6 +85,12 @@ export interface CellModel {
|
|
|
85
85
|
comment?: string;
|
|
86
86
|
/** 样式索引,指向 SheetModel.styles */
|
|
87
87
|
styleId: number;
|
|
88
|
+
/**
|
|
89
|
+
* WPS DISPIMG 单元格内嵌图的 id(指向 WorkbookModel.cellImages)。
|
|
90
|
+
* 有值时渲染器把图画进格内(随行高列宽缩放、随网格滚动裁剪),而非画 formula 文本。
|
|
91
|
+
* 由 cell-image-parser 从 `=DISPIMG("id",n)` 公式解析填充。
|
|
92
|
+
*/
|
|
93
|
+
dispImgId?: string;
|
|
88
94
|
}
|
|
89
95
|
/** 合并区域(0-based,闭区间) */
|
|
90
96
|
export interface MergeRange {
|
|
@@ -102,6 +108,12 @@ export interface RowInfo {
|
|
|
102
108
|
/** 行高,单位 = px(已从 pt 换算) */
|
|
103
109
|
height: number;
|
|
104
110
|
hidden: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* 是否"手动设定行高"(OOXML `<row customHeight="1">`)。
|
|
113
|
+
* true 时渲染层**不做自动行高**(与 Excel/WPS 一致:手动高度的行只裁切/溢出,不撑大)。
|
|
114
|
+
* 由 row-meta-parser 从原始 XML 读出(ExcelJS 不暴露此标记)。
|
|
115
|
+
*/
|
|
116
|
+
customHeight?: boolean;
|
|
105
117
|
}
|
|
106
118
|
/** 冻结窗格: 冻结前 frozenRows 行 / frozenCols 列 */
|
|
107
119
|
export interface FreezeInfo {
|
|
@@ -155,6 +167,19 @@ export interface AnchorCell {
|
|
|
155
167
|
row: number;
|
|
156
168
|
rowOffEmu: number;
|
|
157
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* WPS DISPIMG 单元格内嵌图(workbook 级登记表 xl/cellimages.xml 的一条)。
|
|
172
|
+
* 单元格通过 `=DISPIMG("id",n)` 公式按 id 引用;不同于浮动图(ImageAnchor),它"属于"单元格。
|
|
173
|
+
*/
|
|
174
|
+
export interface CellImage {
|
|
175
|
+
/** DISPIMG id(= cellimages.xml 里 cNvPr@name,如 "ID_5db4b3...") */
|
|
176
|
+
id: string;
|
|
177
|
+
/** 原始图片字节 + mime(解析层产出,可跨 Worker 传输) */
|
|
178
|
+
bytes?: Uint8Array;
|
|
179
|
+
mime?: string;
|
|
180
|
+
/** blob url(主线程 finalize 从 bytes 生成;解析阶段为空) */
|
|
181
|
+
src: string;
|
|
182
|
+
}
|
|
158
183
|
/** 图表规格(从 chartN.xml 抽出,交给 ECharts 映射) */
|
|
159
184
|
export interface ChartSpec {
|
|
160
185
|
type: 'bar' | 'line' | 'pie' | 'area' | 'scatter' | 'doughnut' | 'radar' | 'unsupported';
|
|
@@ -265,6 +290,11 @@ export interface WorkbookModel {
|
|
|
265
290
|
/** 主题色调色板(theme1.xml 解析所得,索引同 ECMA dk1/lt1/dk2/lt2/accent1..6/hlink/folHlink) */
|
|
266
291
|
themeColors: CssColor[];
|
|
267
292
|
date1904: boolean;
|
|
293
|
+
/**
|
|
294
|
+
* WPS DISPIMG 单元格内嵌图登记表(id → 图)。对应 xl/cellimages.xml,workbook 级共享。
|
|
295
|
+
* 单元格 CellModel.dispImgId 指向此表;无 WPS 内嵌图时为 undefined。
|
|
296
|
+
*/
|
|
297
|
+
cellImages?: Map<string, CellImage>;
|
|
268
298
|
}
|
|
269
299
|
export declare const cellKey: (row: number, col: number) => string;
|
|
270
300
|
/** 数据钩子: 解析后、渲染前改模型(返回新模型或就地改) */
|
|
@@ -282,8 +312,20 @@ export interface CellStyleOverride {
|
|
|
282
312
|
indent?: number;
|
|
283
313
|
numFmt?: string;
|
|
284
314
|
}
|
|
285
|
-
/**
|
|
315
|
+
/**
|
|
316
|
+
* 渲染钩子上下文 (Phase C, 2026-06-08).
|
|
317
|
+
* 给 `cellStyle` 钩子的第 3 入参, 让插件能感知该格当前是否可编辑 →
|
|
318
|
+
* 给只读格定制样式不再需要在 setup 里间接调 viewer.isCellEditable.
|
|
319
|
+
*/
|
|
320
|
+
export interface CellStyleCtx {
|
|
321
|
+
/** 该格此刻是否可编辑(综合 editable + editableTargets + readOnlyRanges + cellReadOnly) */
|
|
322
|
+
editable: boolean;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* 渲染钩子: 按单元格覆盖样式(返回部分样式,与解析样式合并).
|
|
326
|
+
* Phase C 2026-06-08: 加可选第 3 入参 `ctx: CellStyleCtx`, 含 `editable`. 旧 `(cell, pos) => ...` 签名兼容.
|
|
327
|
+
*/
|
|
286
328
|
export type CellStyleFn = (cell: CellModel, pos: {
|
|
287
329
|
row: number;
|
|
288
330
|
col: number;
|
|
289
|
-
}) => CellStyleOverride | void;
|
|
331
|
+
}, ctx?: CellStyleCtx) => CellStyleOverride | void;
|