ooxml-excel-editor 1.1.0 → 1.2.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 +75 -0
- package/README.md +148 -4
- package/dist/chunks/plugin-overlay-BBrNby8v.js +8965 -0
- package/dist/chunks/worker-client.stub-CJlmpAgJ.js +190 -0
- package/dist/components/ExcelViewer.vue.d.ts +170 -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/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 -821
- package/dist/react/ExcelViewer.d.ts +134 -3
- package/dist/react/ExportProgressOverlay.d.ts +6 -0
- package/dist/react/use-excel-document.d.ts +2 -0
- package/dist/react.js +718 -281
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/dist/chunks/plugin-overlay-Cfnn9EOi.js +0 -7144
- package/dist/chunks/worker-client.stub-BQVZfaLd.js +0 -7
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { CSSProperties } from 'react';
|
|
2
2
|
import { CellModel, CellStyleFn, CellStyleOverride, ImageAnchor, MergeRange, TransformModelFn, WorkbookModel } from '../core/model/types';
|
|
3
|
+
import { EditableTarget } from '../core/edit/types';
|
|
3
4
|
import { FormulaEngineFactory } from '../core/formula/engine';
|
|
4
5
|
import { CellChangePayload, DimChangePayload, DirtyChangePayload, ImageChangePayload, StructChangePayload } from '../core/edit/edit-controller';
|
|
5
6
|
import { CellSnapshot } from '../core/model/snapshot';
|
|
7
|
+
import { CellInspection } from '../core/model/inspect';
|
|
8
|
+
import { JsonInput, JsonLoadOptions } from '../core/loader-json';
|
|
9
|
+
import { ExportProgress } from '../core/progress';
|
|
6
10
|
import { CellValue, getCellValue, getSheetData, getRangeData, sheetToJSON, ReadOptions, SheetToJSONOptions } from '../core/model/data-access';
|
|
7
11
|
import { EditorResolver } from '../core/edit/editor-context';
|
|
8
12
|
import { ViewerTheme } from '../core/render/theme';
|
|
@@ -10,15 +14,60 @@ import { ExcelSource } from '../core/loader';
|
|
|
10
14
|
import { ImageExportOptions, PdfExportOptions, PrintOptions } from '../core/export';
|
|
11
15
|
import { XlsxExportOptions } from '../core/export/xlsx-writer';
|
|
12
16
|
import { Cell } from '../core/viewer/controller';
|
|
13
|
-
import { ExcelPlugin } from '../core/plugin';
|
|
17
|
+
import { ContextMenuBeforePayload, ContextMenuShowPayload, ContextMenuTransform, ExcelPlugin, MenuItem, PermissionDeniedPayload } from '../core/plugin';
|
|
14
18
|
export interface ExcelViewerProps {
|
|
15
19
|
src?: ExcelSource;
|
|
20
|
+
/**
|
|
21
|
+
* 直接喂 WorkbookModel 或 JsonInput(P3):绕过 parser。优先级 workbook > src。
|
|
22
|
+
* WorkbookModel 直用;JsonInput(二维数组 / 对象数组 / `{sheets:[...]}`)走 jsonToWorkbook。
|
|
23
|
+
*/
|
|
24
|
+
workbook?: WorkbookModel | JsonInput;
|
|
25
|
+
/** JSON 直渲选项(workbook = JsonInput 时生效) */
|
|
26
|
+
jsonOptions?: JsonLoadOptions;
|
|
27
|
+
/**
|
|
28
|
+
* 渲染模板(P3 重设计 2026-06-08):一份 .xlsx 当**样式捐赠者** —— 模板的 styling
|
|
29
|
+
* (styles / merges / 列宽 / 行高 / freeze / theme)套到无格式数据源上,模板的 raw 文字 / 占位符 /
|
|
30
|
+
* 图 / 图表 / 条件格式 全部丢弃。
|
|
31
|
+
*
|
|
32
|
+
* ⚠️ **只在数据源是 `workbook`(JSON / 模型)时生效**;`src`(.xlsx)数据源自带格式,
|
|
33
|
+
* 给 `templateFile` 会被忽略并 console.warn.
|
|
34
|
+
*/
|
|
35
|
+
templateFile?: ExcelSource;
|
|
36
|
+
/** 模板显示名(标题栏 `· 模板: xxx` 后缀);不给则取运行时 File.name */
|
|
37
|
+
templateName?: string;
|
|
38
|
+
/**
|
|
39
|
+
* 内置导出进度遮罩(P1.5):默认 `true` —— 调 `viewer.downloadPdf/exportImage/...` /
|
|
40
|
+
* 选区图片批量转换 时,壳自动建 AbortController + 接 onProgress → 显示居中模态 + 取消。
|
|
41
|
+
* `false` 关闭(走纯回调);`renderExportProgress` 自渲染(覆盖内置 UI)。
|
|
42
|
+
*/
|
|
43
|
+
exportProgress?: boolean;
|
|
44
|
+
/** 完全自渲染遮罩:返回任意 ReactNode 替代内置 UI。`exportProgress=false` 时此项也不渲染。 */
|
|
45
|
+
renderExportProgress?: (ctx: {
|
|
46
|
+
state: ExportProgress | null;
|
|
47
|
+
busy: boolean;
|
|
48
|
+
cancel: () => void;
|
|
49
|
+
}) => React.ReactNode;
|
|
50
|
+
/**
|
|
51
|
+
* 右键菜单(Plan C):
|
|
52
|
+
* - `false` → 不弹内置菜单(`onBeforeContextMenu` / `onContextMenuShow` 仍触发,壳可自渲染)
|
|
53
|
+
* - 函数 `(ctx, items) => MenuItem[] | undefined` → 在内置 items 上加 / 减 / 重排;返 undefined 不动
|
|
54
|
+
* - 不传(默认)→ editable 时显示内置菜单,非 editable 走浏览器默认
|
|
55
|
+
*/
|
|
56
|
+
contextMenu?: boolean | ContextMenuTransform;
|
|
57
|
+
/** 右键菜单触发前:`payload.preventDefault()` 阻止内置菜单(自渲染替代) */
|
|
58
|
+
onBeforeContextMenu?: (payload: ContextMenuBeforePayload) => void;
|
|
59
|
+
/** 右键菜单展示通知:无论内置是否弹都触发,供自渲染或事件流串到业务 */
|
|
60
|
+
onContextMenuShow?: (payload: ContextMenuShowPayload) => void;
|
|
16
61
|
fileName?: string;
|
|
17
62
|
theme?: Partial<ViewerTheme>;
|
|
18
63
|
/** 单击超链接是否自动打开(默认 true) */
|
|
19
64
|
openLinks?: boolean;
|
|
20
65
|
transformModel?: TransformModelFn;
|
|
21
66
|
cellStyle?: CellStyleFn;
|
|
67
|
+
/** WPS 单元格内嵌图(DISPIMG)贴合方式:contain 等比(默认,与 WPS 渲染一致)/ fill 拉伸铺满 / cover 等比裁剪 */
|
|
68
|
+
cellImageFit?: 'fill' | 'contain' | 'cover';
|
|
69
|
+
/** 图片点击放大灯箱(默认 true):只读模式单击图放大、编辑模式右键「查看大图」;false 关闭 */
|
|
70
|
+
imageLightbox?: boolean;
|
|
22
71
|
/** 插件(与 Vue 通用):theme/transformModel/cellStyle/events/overlay/setup 全跨框架可用 */
|
|
23
72
|
plugins?: ExcelPlugin[];
|
|
24
73
|
/** 编辑总开关:默认 false = 只读(行为不变)。开启后才能进入编辑(E0:闸门) */
|
|
@@ -30,6 +79,23 @@ export interface ExcelViewerProps {
|
|
|
30
79
|
}) => boolean | void;
|
|
31
80
|
/** 只读区域(0-based 闭区间);命中即只读 */
|
|
32
81
|
readOnlyRanges?: MergeRange[];
|
|
82
|
+
/**
|
|
83
|
+
* **可编辑白名单**(2026-06-08 新增):设了就是白名单语义,只命中**任一** target 的格才可编辑.
|
|
84
|
+
* 4 种 target 形状自动识别:`{row,col}` 单格 / `{row}` 整行 / `{col}` 整列 / `MergeRange` 矩形.
|
|
85
|
+
* 单值或数组都支持;允许**不相邻**多 target. `undefined`=默认全可编辑(老行为),`[]`=全只读.
|
|
86
|
+
*/
|
|
87
|
+
editableTargets?: EditableTarget | EditableTarget[];
|
|
88
|
+
/**
|
|
89
|
+
* **严格尺寸闸门**(Phase B, 2026-06-08) —— 默认 `false`: 尺寸 API 仅受全局 editable 控制. 设 `true` +
|
|
90
|
+
* editableTargets 启用了 → 该列/行至少有 1 格在白名单内才能改尺寸.
|
|
91
|
+
*/
|
|
92
|
+
strictDimensions?: boolean;
|
|
93
|
+
/**
|
|
94
|
+
* **只读单元格视觉钩子** (Phase C, 2026-06-08):
|
|
95
|
+
* `false`(默认) 无视觉差异;`true` 内置浅灰底 `#f5f7fa`;`CellStyleOverride` 固定样式;`CellStyleFn` 按格自定义.
|
|
96
|
+
* 跟 editableTargets 配合 → 白名单外的格自动套此视觉.
|
|
97
|
+
*/
|
|
98
|
+
readOnlyCellStyle?: boolean | CellStyleOverride | CellStyleFn;
|
|
33
99
|
/** 自定义单元格编辑器(按格返回工厂;覆盖插件 editor)。需 editable 开启 */
|
|
34
100
|
editor?: EditorResolver;
|
|
35
101
|
/** 公式重算(E4):默认 false 沿用缓存值。开启后编辑公式/被引用格 → 依赖格自动重算。需 editable */
|
|
@@ -74,6 +140,8 @@ export interface ExcelViewerProps {
|
|
|
74
140
|
onImageChange?: (p: ImageChangePayload) => void;
|
|
75
141
|
/** 行列结构变更(增删行列) */
|
|
76
142
|
onStructChange?: (p: StructChangePayload) => void;
|
|
143
|
+
/** 权限拒绝(Phase A, 2026-06-08):粘贴/合并/图片落点等命中只读 → 默认 skip + 此事件通知 */
|
|
144
|
+
onPermissionDenied?: (p: PermissionDeniedPayload) => void;
|
|
77
145
|
}
|
|
78
146
|
/** 命令式句柄(与 Vue ref / ViewerApi 对齐) */
|
|
79
147
|
export interface ExcelViewerHandle {
|
|
@@ -97,15 +165,69 @@ export interface ExcelViewerHandle {
|
|
|
97
165
|
} | null;
|
|
98
166
|
redraw: () => void;
|
|
99
167
|
isCellEditable: (row: number, col: number) => boolean;
|
|
168
|
+
setEditableTargets: (targets: EditableTarget | EditableTarget[] | undefined) => void;
|
|
169
|
+
getEditableTargets: () => EditableTarget | EditableTarget[] | undefined;
|
|
100
170
|
editCell: (row: number, col: number, value: CellValue) => boolean;
|
|
101
171
|
editRange: (range: MergeRange, values: CellValue[][]) => boolean;
|
|
102
172
|
clearRange: (range: MergeRange) => boolean;
|
|
103
173
|
setStyle: (range: MergeRange, patch: CellStyleOverride) => boolean;
|
|
174
|
+
getActiveFillColor: () => string;
|
|
175
|
+
getActiveFontColor: () => string;
|
|
176
|
+
setSelectionFill: (color: string | null) => boolean;
|
|
177
|
+
setSelectionFontColor: (color: string) => boolean;
|
|
178
|
+
getSelectionWrapState: () => 'all' | 'none' | 'mixed';
|
|
179
|
+
toggleWrapTextOnSelection: () => boolean;
|
|
180
|
+
mergeCells: (range: MergeRange) => boolean;
|
|
181
|
+
unmergeCells: (range: MergeRange) => boolean;
|
|
182
|
+
pasteText: (text: string, at?: {
|
|
183
|
+
row: number;
|
|
184
|
+
col: number;
|
|
185
|
+
}) => boolean;
|
|
186
|
+
pasteRichHtml: (html: string, at?: {
|
|
187
|
+
row: number;
|
|
188
|
+
col: number;
|
|
189
|
+
}) => boolean;
|
|
190
|
+
pasteImageBlob: (blob: Blob, at?: {
|
|
191
|
+
row: number;
|
|
192
|
+
col: number;
|
|
193
|
+
}) => Promise<boolean>;
|
|
104
194
|
getImages: () => ImageAnchor[];
|
|
105
195
|
addImage: (anchor: ImageAnchor) => number;
|
|
106
196
|
removeImage: (index: number) => boolean;
|
|
107
197
|
moveImage: (index: number, dxPx: number, dyPx: number) => boolean;
|
|
108
198
|
resizeImage: (index: number, widthPx: number, heightPx: number) => boolean;
|
|
199
|
+
getCellImages: () => {
|
|
200
|
+
id: string;
|
|
201
|
+
src: string;
|
|
202
|
+
mime?: string;
|
|
203
|
+
}[];
|
|
204
|
+
getCellImageAt: (row: number, col: number) => {
|
|
205
|
+
id: string;
|
|
206
|
+
src: string;
|
|
207
|
+
mime?: string;
|
|
208
|
+
} | null;
|
|
209
|
+
openImageLightbox: (src: string, fileName?: string, mime?: string) => void;
|
|
210
|
+
/** 活动格在公式栏里的可编辑字符串(公式→=…,数值→原始数字串) */
|
|
211
|
+
getCellEditString: () => string;
|
|
212
|
+
/** 活动格此刻是否可经公式栏编辑(editable + 非只读) */
|
|
213
|
+
canEditActiveCell: () => boolean;
|
|
214
|
+
/** 经公式栏提交活动格的值(move='down' 提交后下移) */
|
|
215
|
+
commitActiveCellValue: (value: string, move?: 'down') => boolean;
|
|
216
|
+
setCellImageFit: (fit: 'fill' | 'contain' | 'cover') => void;
|
|
217
|
+
convertImageToCell: (imageIndex: number, row: number, col: number) => boolean;
|
|
218
|
+
convertImageToCellAuto: (imageIndex: number) => boolean;
|
|
219
|
+
convertAllImagesToCells: (col?: number) => number;
|
|
220
|
+
convertImagesInRangeToCell: (range: MergeRange) => Promise<number>;
|
|
221
|
+
convertCellImagesInRangeToFloat: (range: MergeRange, size?: {
|
|
222
|
+
width: number;
|
|
223
|
+
height: number;
|
|
224
|
+
}) => Promise<number>;
|
|
225
|
+
openContextMenu: (x: number, y: number, items?: MenuItem[]) => void;
|
|
226
|
+
closeContextMenu: () => void;
|
|
227
|
+
convertCellImageToFloat: (row: number, col: number, size?: {
|
|
228
|
+
width: number;
|
|
229
|
+
height: number;
|
|
230
|
+
}) => boolean;
|
|
109
231
|
insertRows: (at: number, count?: number) => boolean;
|
|
110
232
|
deleteRows: (at: number, count?: number) => boolean;
|
|
111
233
|
insertCols: (at: number, count?: number) => boolean;
|
|
@@ -119,12 +241,21 @@ export interface ExcelViewerHandle {
|
|
|
119
241
|
col: number;
|
|
120
242
|
} | null;
|
|
121
243
|
getCellSnapshot: (row: number, col: number) => CellSnapshot | null;
|
|
244
|
+
inspectCell: (row: number, col: number) => CellInspection | null;
|
|
122
245
|
beginEdit: (row: number, col: number) => boolean;
|
|
123
246
|
cancelEdit: () => void;
|
|
124
247
|
isEditing: () => boolean;
|
|
125
|
-
setColumnWidth: (
|
|
126
|
-
setRowHeight: (
|
|
248
|
+
setColumnWidth: (target: import('../core/edit/types').DimTarget, width: number) => number;
|
|
249
|
+
setRowHeight: (target: import('../core/edit/types').DimTarget, height: number) => number;
|
|
250
|
+
autoFitColumns: (target?: import('../core/edit/types').DimTarget) => number;
|
|
251
|
+
autoFitRows: (target?: import('../core/edit/types').DimTarget) => number;
|
|
252
|
+
resetColumnWidth: (target: import('../core/edit/types').DimTarget) => number;
|
|
253
|
+
resetRowHeight: (target: import('../core/edit/types').DimTarget) => number;
|
|
127
254
|
isRecalcReady: () => boolean;
|
|
255
|
+
getVirtualExtent: () => {
|
|
256
|
+
rows: number;
|
|
257
|
+
cols: number;
|
|
258
|
+
};
|
|
128
259
|
isDirty: () => boolean;
|
|
129
260
|
resetToOriginal: () => boolean;
|
|
130
261
|
exportImage: (opts?: ImageExportOptions) => Promise<Blob>;
|
|
@@ -7,6 +7,8 @@ export interface ExcelDocument {
|
|
|
7
7
|
workbook: WorkbookModel | null;
|
|
8
8
|
progress: ParseProgress | null;
|
|
9
9
|
load: (src: ExcelSource, transform?: TransformModelFn) => Promise<void>;
|
|
10
|
+
/** 直接喂模型(JSON 直渲 / 模板已应用),跳过 parser */
|
|
11
|
+
loadModel: (model: WorkbookModel, transform?: TransformModelFn) => void;
|
|
10
12
|
/** 原始字节(高保真 overlay 导出用) */
|
|
11
13
|
sourceBuffer: ArrayBuffer | null;
|
|
12
14
|
}
|