@file-viewer/core 2.0.11 → 2.1.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.en.md +2 -2
- package/README.md +2 -2
- package/dist/config/options.d.ts +1 -1
- package/dist/config/options.js +1 -1
- package/dist/contracts/types.d.ts +71 -1
- package/dist/headless.d.ts +2 -2
- package/dist/headless.js +1 -1
- package/dist/index.d.ts +9 -6
- package/dist/index.js +105 -48
- package/dist/platform/assets.d.ts +3 -1
- package/dist/platform/assets.js +18 -2
- package/dist/registry/capabilities.d.ts +2 -2
- package/dist/registry/capabilities.js +2 -1
- package/dist/registry/formats.d.ts +20 -7
- package/dist/registry/formats.js +14 -5
- package/dist/registry/registry.d.ts +8 -1
- package/dist/registry/registry.js +29 -0
- package/dist/renderers/image.js +1 -10
- package/dist/renderers/index.d.ts +320 -2
- package/dist/renderers/index.js +27 -157
- package/dist/viewer/createViewer.js +86 -3
- package/package.json +17 -44
- package/dist/renderers/archive.d.ts +0 -2
- package/dist/renderers/archive.js +0 -547
- package/dist/renderers/archiveCache.d.ts +0 -10
- package/dist/renderers/archiveCache.js +0 -96
- package/dist/renderers/archiveFallback.d.ts +0 -7
- package/dist/renderers/archiveFallback.js +0 -166
- package/dist/renderers/archiveShared.d.ts +0 -23
- package/dist/renderers/archiveShared.js +0 -71
- package/dist/renderers/audio.d.ts +0 -8
- package/dist/renderers/audio.js +0 -219
- package/dist/renderers/cad.d.ts +0 -2
- package/dist/renderers/cad.js +0 -446
- package/dist/renderers/code.d.ts +0 -11
- package/dist/renderers/code.js +0 -233
- package/dist/renderers/data.d.ts +0 -7
- package/dist/renderers/data.js +0 -370
- package/dist/renderers/drawing.d.ts +0 -10
- package/dist/renderers/drawing.js +0 -882
- package/dist/renderers/eda.d.ts +0 -2
- package/dist/renderers/eda.js +0 -434
- package/dist/renderers/edaParser.d.ts +0 -77
- package/dist/renderers/edaParser.js +0 -569
- package/dist/renderers/email.d.ts +0 -2
- package/dist/renderers/email.js +0 -463
- package/dist/renderers/epub.d.ts +0 -2
- package/dist/renderers/epub.js +0 -331
- package/dist/renderers/geo.d.ts +0 -2
- package/dist/renderers/geo.js +0 -284
- package/dist/renderers/markdown.d.ts +0 -2
- package/dist/renderers/markdown.js +0 -83
- package/dist/renderers/model.d.ts +0 -2
- package/dist/renderers/model.js +0 -567
- package/dist/renderers/ofd.d.ts +0 -2
- package/dist/renderers/ofd.js +0 -256
- package/dist/renderers/openDocument.d.ts +0 -2
- package/dist/renderers/openDocument.js +0 -122
- package/dist/renderers/pdf.d.ts +0 -3
- package/dist/renderers/pdf.js +0 -1001
- package/dist/renderers/pdfStyles.d.ts +0 -1
- package/dist/renderers/pdfStyles.js +0 -1
- package/dist/renderers/pptx.d.ts +0 -2
- package/dist/renderers/pptx.js +0 -217
- package/dist/renderers/spreadsheet/state.d.ts +0 -80
- package/dist/renderers/spreadsheet/state.js +0 -96
- package/dist/renderers/spreadsheet/view.d.ts +0 -25
- package/dist/renderers/spreadsheet/view.js +0 -833
- package/dist/renderers/spreadsheet/worker/index.d.ts +0 -2
- package/dist/renderers/spreadsheet/worker/index.js +0 -1
- package/dist/renderers/spreadsheet/worker/sheetjs/SheetJsModel.d.ts +0 -73
- package/dist/renderers/spreadsheet/worker/sheetjs/SheetJsModel.js +0 -623
- package/dist/renderers/spreadsheet/worker/sheetjs/color.d.ts +0 -2
- package/dist/renderers/spreadsheet/worker/sheetjs/color.js +0 -73
- package/dist/renderers/spreadsheet/worker/sheetjs/index.d.ts +0 -1
- package/dist/renderers/spreadsheet/worker/sheetjs/index.js +0 -1
- package/dist/renderers/spreadsheet/worker/sheetjs/parser.d.ts +0 -18
- package/dist/renderers/spreadsheet/worker/sheetjs/parser.js +0 -106
- package/dist/renderers/spreadsheet/worker/sheetjs/sheet.worker.d.ts +0 -1
- package/dist/renderers/spreadsheet/worker/sheetjs/sheet.worker.js +0 -11
- package/dist/renderers/spreadsheet/worker/type.d.ts +0 -57
- package/dist/renderers/spreadsheet/worker/type.js +0 -1
- package/dist/renderers/spreadsheet.d.ts +0 -3
- package/dist/renderers/spreadsheet.js +0 -929
- package/dist/renderers/typst.d.ts +0 -8
- package/dist/renderers/typst.js +0 -547
- package/dist/renderers/umd/parser.d.ts +0 -30
- package/dist/renderers/umd/parser.js +0 -408
- package/dist/renderers/umd.d.ts +0 -2
- package/dist/renderers/umd.js +0 -297
- package/dist/renderers/video.d.ts +0 -8
- package/dist/renderers/video.js +0 -108
- package/dist/renderers/wordDoc.d.ts +0 -5
- package/dist/renderers/wordDoc.js +0 -284
- package/dist/renderers/wordDocx.d.ts +0 -5
- package/dist/renderers/wordDocx.js +0 -985
- package/dist/renderers/wordDocx.worker.d.ts +0 -1
- package/dist/renderers/wordDocx.worker.js +0 -96
- package/vendor/ofd/dltech/jbig2/arithmetic_decoder.js +0 -183
- package/vendor/ofd/dltech/jbig2/ccitt.js +0 -1070
- package/vendor/ofd/dltech/jbig2/compatibility.js +0 -12
- package/vendor/ofd/dltech/jbig2/core_utils.js +0 -180
- package/vendor/ofd/dltech/jbig2/is_node.js +0 -27
- package/vendor/ofd/dltech/jbig2/jbig2.js +0 -2589
- package/vendor/ofd/dltech/jbig2/jbig2_stream.js +0 -81
- package/vendor/ofd/dltech/jbig2/primitives.js +0 -387
- package/vendor/ofd/dltech/jbig2/stream.js +0 -1348
- package/vendor/ofd/dltech/jbig2/util.js +0 -972
- package/vendor/ofd/dltech/ofd/ofd.d.ts +0 -11
- package/vendor/ofd/dltech/ofd/ofd.js +0 -100
- package/vendor/ofd/dltech/ofd/ofd_parser.js +0 -395
- package/vendor/ofd/dltech/ofd/ofd_render.js +0 -473
- package/vendor/ofd/dltech/ofd/ofd_util.js +0 -350
- package/vendor/ofd/dltech/ofd/pipeline.js +0 -26
|
@@ -1,929 +0,0 @@
|
|
|
1
|
-
import { resolveFileViewerSpreadsheetWorkerUrl } from '../platform/assets.js';
|
|
2
|
-
import { registerFileViewerZoomProvider, unregisterFileViewerZoomProvider, } from '../features/document/dom/index.js';
|
|
3
|
-
import { createFileViewerZoomChangeEmitter as createZoomChangeEmitter } from '../features/document/zoom.js';
|
|
4
|
-
import { createFileViewerWorkerController, } from '../platform/worker.js';
|
|
5
|
-
import { buildRows, clampWindowStart, collectWindowStarts, createEmptyVirtualState, DEFAULT_SHEET_DEFAULTS, displayCellKey, getDataKey, markWindowState, ROW_STATE_FIELD, RowState, WINDOW_SIZE, } from './spreadsheet/state.js';
|
|
6
|
-
import { buildColumns, createTableConfig, detectIndexOffset, getDisplayColumns, getRowHeight, HEADER_HEIGHT, INDEX_COLUMN_WIDTH, normalizeCellStyle, normalizeRowHeight, } from './spreadsheet/view.js';
|
|
7
|
-
const spreadsheetStyle = `
|
|
8
|
-
.excel-wrapper{position:relative;width:100%;height:100%;display:flex;flex-direction:column;background:#fff;color:#172033;font-family:Aptos,'Segoe UI','PingFang SC','Microsoft YaHei',sans-serif}
|
|
9
|
-
.excel-wrapper *{box-sizing:border-box}
|
|
10
|
-
.excel-wrapper .table-wrapper{position:relative;width:100%;flex:1;min-height:0;background:#fff;overflow:hidden}
|
|
11
|
-
.excel-wrapper .table-host{position:absolute;inset:0}
|
|
12
|
-
.excel-wrapper .table-target{width:100%;height:100%}
|
|
13
|
-
.excel-wrapper .table-host .e-virt-table-container,.excel-wrapper .table-host .e-virt-table-stage{width:100%!important}
|
|
14
|
-
.excel-wrapper .table-host .e-virt-table-container{height:100%!important}
|
|
15
|
-
.excel-wrapper .table-host .e-virt-table-stage{overflow:hidden}
|
|
16
|
-
.excel-wrapper .sheet-loading{position:absolute;right:18px;bottom:18px;z-index:20;display:inline-flex;align-items:center;gap:8px;padding:10px 14px;border-radius:14px;background:rgba(33,163,102,.1);border:1px solid rgba(33,163,102,.2);box-shadow:0 8px 20px rgba(33,163,102,.12);color:#1a7f50;font-size:12px;font-weight:700;pointer-events:none}
|
|
17
|
-
.excel-wrapper .sheet-loading-dot{width:8px;height:8px;flex-shrink:0;border-radius:999px;background:#21a366;box-shadow:0 0 0 6px rgba(33,163,102,.12);animation:sheet-loading-pulse 1.2s ease-in-out infinite}
|
|
18
|
-
.excel-wrapper .sheet-loading-summary{color:#5f6368}
|
|
19
|
-
.excel-wrapper .excel-image-viewport{position:absolute;right:0;bottom:0;z-index:35;overflow:hidden;pointer-events:none}
|
|
20
|
-
.excel-wrapper .excel-image-layer{position:absolute;inset:0 auto auto 0;width:0;height:0;transform-origin:0 0;will-change:transform}
|
|
21
|
-
.excel-wrapper .excel-image{position:absolute;display:block;max-width:none;height:auto;object-fit:contain;user-select:none}
|
|
22
|
-
.excel-wrapper .loading{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(255,255,255,.96);z-index:999;backdrop-filter:blur(6px)}
|
|
23
|
-
.excel-wrapper .loading-card{width:min(100%,460px);display:flex;align-items:center;gap:18px;padding:22px;border-radius:24px;background:rgba(255,255,255,.92);border:1px solid rgba(33,163,102,.1);box-shadow:0 22px 48px rgba(18,36,27,.12)}
|
|
24
|
-
.excel-wrapper .loading-brand{flex-shrink:0;width:78px;height:78px;display:flex;align-items:center;justify-content:center;border-radius:22px;background:linear-gradient(135deg,rgba(33,163,102,.14),rgba(33,163,102,.04));color:#1a7f50;font-size:18px;font-weight:900;letter-spacing:0}
|
|
25
|
-
.excel-wrapper .loading-copy{min-width:0;flex:1}
|
|
26
|
-
.excel-wrapper .loading-kicker{display:block;color:#21a366;font-size:12px;font-weight:800;letter-spacing:.08em;text-transform:uppercase}
|
|
27
|
-
.excel-wrapper .loading-copy strong{display:block;margin-top:6px;color:#183828;font-size:20px;line-height:1.3}
|
|
28
|
-
.excel-wrapper .loading-copy p{margin:8px 0 0;color:#64748b;font-size:13px;line-height:1.5}
|
|
29
|
-
.excel-wrapper .loading-spinner{width:28px;height:28px;border-radius:999px;border:3px solid rgba(33,163,102,.16);border-top-color:#21a366;animation:sheet-loading-spin .8s linear infinite}
|
|
30
|
-
.excel-wrapper .error{position:absolute;left:50%;top:50%;z-index:1000;transform:translate(-50%,-50%);max-width:min(520px,calc(100% - 48px));padding:16px 18px;border-radius:16px;background:#fff7ed;color:#9a3412;border:1px solid rgba(234,88,12,.18);box-shadow:0 18px 42px rgba(154,52,18,.12);font-size:14px;line-height:1.6}
|
|
31
|
-
.excel-wrapper .toolbar{min-height:44px;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 12px;border-top:1px solid #e5e7eb;background:#f8fafc}
|
|
32
|
-
.excel-wrapper .btn-group{min-width:0;max-width:100%;flex:1 1 auto;display:flex;align-items:center;gap:6px;overflow-x:auto;overflow-y:hidden;scrollbar-gutter:stable;scrollbar-width:thin;overscroll-behavior-x:contain}
|
|
33
|
-
.excel-wrapper .sheet-tab{flex:0 0 auto;width:max-content;min-width:72px;max-width:min(260px,70vw);height:30px;border:1px solid transparent;border-radius:8px;padding:0 12px;background:transparent;color:#526173;font:inherit;font-size:12px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer}
|
|
34
|
-
.excel-wrapper .sheet-tab:hover{background:#edf2f7}
|
|
35
|
-
.excel-wrapper .sheet-tab.active{border-color:rgba(33,163,102,.28);background:rgba(33,163,102,.12);color:#137347}
|
|
36
|
-
.excel-wrapper .summary{flex:0 0 auto;max-width:42%;overflow:hidden;color:#64748b;font-size:12px;font-weight:700;white-space:nowrap;text-overflow:ellipsis}
|
|
37
|
-
.excel-wrapper .hidden{display:none!important}
|
|
38
|
-
.file-viewer[data-viewer-theme='dark'] .excel-wrapper{background:#0f172a;color:#e5e7eb}
|
|
39
|
-
.file-viewer[data-viewer-theme='dark'] .excel-wrapper .table-wrapper{background:#111827}
|
|
40
|
-
.file-viewer[data-viewer-theme='dark'] .excel-wrapper .toolbar{background:#111827;border-color:rgba(148,163,184,.22)}
|
|
41
|
-
.file-viewer[data-viewer-theme='dark'] .excel-wrapper .sheet-tab{color:#cbd5e1}
|
|
42
|
-
.file-viewer[data-viewer-theme='dark'] .excel-wrapper .sheet-tab:hover{background:#1f2937}
|
|
43
|
-
@media (prefers-color-scheme:dark){.file-viewer[data-viewer-theme='system'] .excel-wrapper{background:#0f172a;color:#e5e7eb}.file-viewer[data-viewer-theme='system'] .excel-wrapper .table-wrapper{background:#111827}.file-viewer[data-viewer-theme='system'] .excel-wrapper .toolbar{background:#111827;border-color:rgba(148,163,184,.22)}.file-viewer[data-viewer-theme='system'] .excel-wrapper .sheet-tab{color:#cbd5e1}.file-viewer[data-viewer-theme='system'] .excel-wrapper .sheet-tab:hover{background:#1f2937}}
|
|
44
|
-
@keyframes sheet-loading-spin{to{transform:rotate(360deg)}}
|
|
45
|
-
@keyframes sheet-loading-pulse{0%,100%{opacity:.55;transform:scale(.9)}50%{opacity:1;transform:scale(1)}}
|
|
46
|
-
@media (max-width:720px){.excel-wrapper .toolbar{align-items:stretch;flex-direction:column}.excel-wrapper .btn-group{flex:0 0 auto}.excel-wrapper .summary{max-width:none;white-space:normal}.excel-wrapper .sheet-loading{left:12px;right:12px;bottom:58px;justify-content:center}.excel-wrapper .loading-card{margin:18px;flex-direction:column;text-align:center}}
|
|
47
|
-
`;
|
|
48
|
-
const loadEVirtTable = async () => {
|
|
49
|
-
const module = await import('e-virt-table');
|
|
50
|
-
return module.default || module;
|
|
51
|
-
};
|
|
52
|
-
const getTargetWindow = (target) => {
|
|
53
|
-
return target.ownerDocument.defaultView;
|
|
54
|
-
};
|
|
55
|
-
const getDocumentBaseUrl = (target) => {
|
|
56
|
-
return target.ownerDocument.baseURI ||
|
|
57
|
-
target.ownerDocument.URL ||
|
|
58
|
-
'http://localhost/';
|
|
59
|
-
};
|
|
60
|
-
const callListener = (listener, event) => {
|
|
61
|
-
if (!listener) {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
if (typeof listener === 'function') {
|
|
65
|
-
listener(event);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
listener.handleEvent(event);
|
|
69
|
-
};
|
|
70
|
-
class MainThreadSpreadsheetWorker {
|
|
71
|
-
constructor(targetWindow) {
|
|
72
|
-
this.onmessage = null;
|
|
73
|
-
this.onerror = null;
|
|
74
|
-
this.destroyed = false;
|
|
75
|
-
this.listeners = new Map();
|
|
76
|
-
this.parserPromise = null;
|
|
77
|
-
this.context = null;
|
|
78
|
-
this.targetWindow = targetWindow;
|
|
79
|
-
}
|
|
80
|
-
addEventListener(type, listener) {
|
|
81
|
-
var _a;
|
|
82
|
-
if (!this.listeners.has(type)) {
|
|
83
|
-
this.listeners.set(type, new Set());
|
|
84
|
-
}
|
|
85
|
-
(_a = this.listeners.get(type)) === null || _a === void 0 ? void 0 : _a.add(listener);
|
|
86
|
-
}
|
|
87
|
-
removeEventListener(type, listener) {
|
|
88
|
-
var _a;
|
|
89
|
-
(_a = this.listeners.get(type)) === null || _a === void 0 ? void 0 : _a.delete(listener);
|
|
90
|
-
}
|
|
91
|
-
terminate() {
|
|
92
|
-
this.destroyed = true;
|
|
93
|
-
this.listeners.clear();
|
|
94
|
-
}
|
|
95
|
-
postMessage(message) {
|
|
96
|
-
void this.handleMessage(message);
|
|
97
|
-
}
|
|
98
|
-
async loadParser() {
|
|
99
|
-
if (!this.parserPromise) {
|
|
100
|
-
this.parserPromise = import('./spreadsheet/worker/sheetjs/parser.js');
|
|
101
|
-
}
|
|
102
|
-
const parser = await this.parserPromise;
|
|
103
|
-
if (!this.context) {
|
|
104
|
-
this.context = parser.createSpreadsheetParserContext();
|
|
105
|
-
}
|
|
106
|
-
return parser;
|
|
107
|
-
}
|
|
108
|
-
dispatch(type, event) {
|
|
109
|
-
var _a;
|
|
110
|
-
(_a = this.listeners.get(type)) === null || _a === void 0 ? void 0 : _a.forEach(listener => callListener(listener, event));
|
|
111
|
-
}
|
|
112
|
-
dispatchMessage(data) {
|
|
113
|
-
var _a;
|
|
114
|
-
const targetGlobal = this.targetWindow;
|
|
115
|
-
const MessageEventCtor = (targetGlobal === null || targetGlobal === void 0 ? void 0 : targetGlobal.MessageEvent) ||
|
|
116
|
-
(typeof MessageEvent !== 'undefined' ? MessageEvent : undefined);
|
|
117
|
-
const event = MessageEventCtor
|
|
118
|
-
? new MessageEventCtor('message', { data })
|
|
119
|
-
: { type: 'message', data };
|
|
120
|
-
(_a = this.onmessage) === null || _a === void 0 ? void 0 : _a.call(this, event);
|
|
121
|
-
this.dispatch('message', event);
|
|
122
|
-
}
|
|
123
|
-
dispatchError(error) {
|
|
124
|
-
var _a;
|
|
125
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
126
|
-
const targetGlobal = this.targetWindow;
|
|
127
|
-
const ErrorEventCtor = (targetGlobal === null || targetGlobal === void 0 ? void 0 : targetGlobal.ErrorEvent) ||
|
|
128
|
-
(typeof ErrorEvent !== 'undefined' ? ErrorEvent : undefined);
|
|
129
|
-
const event = ErrorEventCtor
|
|
130
|
-
? new ErrorEventCtor('error', { message, error })
|
|
131
|
-
: { type: 'error', message, error };
|
|
132
|
-
(_a = this.onerror) === null || _a === void 0 ? void 0 : _a.call(this, event);
|
|
133
|
-
this.dispatch('error', event);
|
|
134
|
-
}
|
|
135
|
-
async handleMessage(message) {
|
|
136
|
-
if (this.destroyed) {
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
try {
|
|
140
|
-
const parser = await this.loadParser();
|
|
141
|
-
parser.handleSpreadsheetWorkerRequest(this.context || parser.createSpreadsheetParserContext(), message).forEach(response => {
|
|
142
|
-
if (!this.destroyed) {
|
|
143
|
-
this.dispatchMessage(response);
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
catch (error) {
|
|
148
|
-
if (!this.destroyed) {
|
|
149
|
-
this.dispatchError(error);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
const createMainThreadSpreadsheetWorker = (target) => {
|
|
155
|
-
return new MainThreadSpreadsheetWorker(getTargetWindow(target));
|
|
156
|
-
};
|
|
157
|
-
const createSpreadsheetWorkerFactory = (target, context) => {
|
|
158
|
-
return () => {
|
|
159
|
-
var _a, _b, _c;
|
|
160
|
-
if (((_b = (_a = context === null || context === void 0 ? void 0 : context.options) === null || _a === void 0 ? void 0 : _a.spreadsheet) === null || _b === void 0 ? void 0 : _b.worker) !== true) {
|
|
161
|
-
return createMainThreadSpreadsheetWorker(target);
|
|
162
|
-
}
|
|
163
|
-
const view = getTargetWindow(target);
|
|
164
|
-
const WorkerCtor = (view === null || view === void 0 ? void 0 : view.Worker) ||
|
|
165
|
-
(typeof Worker !== 'undefined' ? Worker : undefined);
|
|
166
|
-
if (!WorkerCtor) {
|
|
167
|
-
return createMainThreadSpreadsheetWorker(target);
|
|
168
|
-
}
|
|
169
|
-
const workerUrl = resolveFileViewerSpreadsheetWorkerUrl((_c = context === null || context === void 0 ? void 0 : context.options) === null || _c === void 0 ? void 0 : _c.spreadsheet, getDocumentBaseUrl(target));
|
|
170
|
-
try {
|
|
171
|
-
return new WorkerCtor(workerUrl, { type: 'module' });
|
|
172
|
-
}
|
|
173
|
-
catch (moduleWorkerError) {
|
|
174
|
-
try {
|
|
175
|
-
return new WorkerCtor(workerUrl);
|
|
176
|
-
}
|
|
177
|
-
catch (classicWorkerError) {
|
|
178
|
-
console.warn('[file-viewer] Spreadsheet Worker 无法创建,已回退到主线程解析。', classicWorkerError || moduleWorkerError);
|
|
179
|
-
return createMainThreadSpreadsheetWorker(target);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
};
|
|
183
|
-
};
|
|
184
|
-
const createStyle = (documentRef) => {
|
|
185
|
-
const style = documentRef.createElement('style');
|
|
186
|
-
style.textContent = spreadsheetStyle;
|
|
187
|
-
return style;
|
|
188
|
-
};
|
|
189
|
-
const setHidden = (element, hidden) => {
|
|
190
|
-
element.classList.toggle('hidden', hidden);
|
|
191
|
-
};
|
|
192
|
-
const clampZoom = (value) => {
|
|
193
|
-
return Math.min(2.5, Math.max(0.5, Number(value.toFixed(2))));
|
|
194
|
-
};
|
|
195
|
-
const renderFileViewerSpreadsheet = async (buffer, target, _type, context) => {
|
|
196
|
-
var _a, _b;
|
|
197
|
-
const documentRef = target.ownerDocument;
|
|
198
|
-
const EVirtTable = await loadEVirtTable();
|
|
199
|
-
const zoomEmitter = createZoomChangeEmitter();
|
|
200
|
-
const root = documentRef.createElement('div');
|
|
201
|
-
root.className = 'excel-wrapper';
|
|
202
|
-
root.dataset.viewerZoomProvider = 'xlsx';
|
|
203
|
-
const loading = documentRef.createElement('div');
|
|
204
|
-
loading.className = 'loading';
|
|
205
|
-
loading.innerHTML = `
|
|
206
|
-
<div class="loading-card">
|
|
207
|
-
<div class="loading-brand">XLSX</div>
|
|
208
|
-
<div class="loading-copy">
|
|
209
|
-
<span class="loading-kicker">Excel 表格</span>
|
|
210
|
-
<strong data-loading-title>正在解析 Excel 工作簿</strong>
|
|
211
|
-
<p>正在准备工作表、样式和大数据视口,请稍候。</p>
|
|
212
|
-
</div>
|
|
213
|
-
<span class="loading-spinner"></span>
|
|
214
|
-
</div>
|
|
215
|
-
`;
|
|
216
|
-
const error = documentRef.createElement('div');
|
|
217
|
-
error.className = 'error hidden';
|
|
218
|
-
const tableWrapper = documentRef.createElement('div');
|
|
219
|
-
tableWrapper.className = 'table-wrapper';
|
|
220
|
-
const sheetLoading = documentRef.createElement('div');
|
|
221
|
-
sheetLoading.className = 'sheet-loading hidden';
|
|
222
|
-
sheetLoading.innerHTML = `
|
|
223
|
-
<span class="sheet-loading-dot"></span>
|
|
224
|
-
<span>正在平滑补充可视区数据</span>
|
|
225
|
-
<span class="sheet-loading-summary"></span>
|
|
226
|
-
`;
|
|
227
|
-
const tableHostShell = documentRef.createElement('div');
|
|
228
|
-
tableHostShell.className = 'table-host';
|
|
229
|
-
const tableHost = documentRef.createElement('div');
|
|
230
|
-
tableHost.className = 'table-target';
|
|
231
|
-
const imageViewport = documentRef.createElement('div');
|
|
232
|
-
imageViewport.className = 'excel-image-viewport hidden';
|
|
233
|
-
const imageLayer = documentRef.createElement('div');
|
|
234
|
-
imageLayer.className = 'excel-image-layer';
|
|
235
|
-
imageViewport.appendChild(imageLayer);
|
|
236
|
-
tableHostShell.append(tableHost, imageViewport);
|
|
237
|
-
tableWrapper.append(sheetLoading, tableHostShell);
|
|
238
|
-
const toolbar = documentRef.createElement('div');
|
|
239
|
-
toolbar.className = 'toolbar';
|
|
240
|
-
const sheetTabsBar = documentRef.createElement('div');
|
|
241
|
-
sheetTabsBar.className = 'btn-group';
|
|
242
|
-
sheetTabsBar.setAttribute('aria-label', '工作表列表');
|
|
243
|
-
const summary = documentRef.createElement('div');
|
|
244
|
-
summary.className = 'summary';
|
|
245
|
-
toolbar.append(sheetTabsBar, summary);
|
|
246
|
-
root.append(loading, error, tableWrapper, toolbar);
|
|
247
|
-
target.replaceChildren(createStyle(documentRef), root);
|
|
248
|
-
let sheets = [];
|
|
249
|
-
let sheetIndex = 0;
|
|
250
|
-
let errorMessage = '';
|
|
251
|
-
let totalRows = 0;
|
|
252
|
-
let totalCols = 0;
|
|
253
|
-
let sheetDefaults = { ...DEFAULT_SHEET_DEFAULTS };
|
|
254
|
-
let sheetInitializing = true;
|
|
255
|
-
let hasInitialWindow = false;
|
|
256
|
-
let loadedWindowCount = 0;
|
|
257
|
-
let loadingWindowCount = 0;
|
|
258
|
-
let sheetImages = [];
|
|
259
|
-
let zoom = 1;
|
|
260
|
-
let imageViewportState = {
|
|
261
|
-
scrollX: 0,
|
|
262
|
-
scrollY: 0,
|
|
263
|
-
width: 0,
|
|
264
|
-
height: 0,
|
|
265
|
-
};
|
|
266
|
-
let loadingState = true;
|
|
267
|
-
let virtualState = createEmptyVirtualState();
|
|
268
|
-
const sheetStateCache = new Map();
|
|
269
|
-
const sheetImageCache = new Map();
|
|
270
|
-
let table = null;
|
|
271
|
-
let resizeObserver = null;
|
|
272
|
-
let resizeFrame = 0;
|
|
273
|
-
let scrollFrame = 0;
|
|
274
|
-
let viewportRange = { start: 0, end: 0 };
|
|
275
|
-
let scrollDirection = 1;
|
|
276
|
-
let lastScrollY = 0;
|
|
277
|
-
let sheetSessionId = 0;
|
|
278
|
-
let disposed = false;
|
|
279
|
-
let hasNotifiedFirstPaint = false;
|
|
280
|
-
const controller = createFileViewerWorkerController(createSpreadsheetWorkerFactory(target, context), { logErrors: false });
|
|
281
|
-
const getActiveSheet = () => sheets.find(sheet => sheet.id === sheetIndex);
|
|
282
|
-
const getSheetTabs = () => {
|
|
283
|
-
const visible = sheets.filter(sheet => !sheet.hidden);
|
|
284
|
-
return visible.length ? visible : sheets;
|
|
285
|
-
};
|
|
286
|
-
const getActiveSheetId = () => { var _a; return sheetIndex !== null && sheetIndex !== void 0 ? sheetIndex : (_a = sheets[0]) === null || _a === void 0 ? void 0 : _a.id; };
|
|
287
|
-
const getHostHeight = () => tableHost.clientHeight || 0;
|
|
288
|
-
const showBlockingLoading = () => !errorMessage && !hasInitialWindow && (loadingState || sheetInitializing);
|
|
289
|
-
const showStreamingLoading = () => !showBlockingLoading() &&
|
|
290
|
-
!errorMessage &&
|
|
291
|
-
hasInitialWindow &&
|
|
292
|
-
loadingWindowCount > 0;
|
|
293
|
-
const scalePx = (value) => Math.max(1, Math.round(value * zoom));
|
|
294
|
-
const scaleRowHeight = (value) => Math.max(0.1, Math.round(value * zoom));
|
|
295
|
-
const getSheetLoadingText = () => {
|
|
296
|
-
var _a;
|
|
297
|
-
if (!sheets.length) {
|
|
298
|
-
return '正在解析 Excel 工作簿,请耐心等待...';
|
|
299
|
-
}
|
|
300
|
-
const activeName = (_a = getActiveSheet()) === null || _a === void 0 ? void 0 : _a.name;
|
|
301
|
-
return activeName ? `正在准备「${activeName}」...` : '正在准备工作表内容...';
|
|
302
|
-
};
|
|
303
|
-
const getCachedSummary = () => {
|
|
304
|
-
if (!totalRows) {
|
|
305
|
-
return '';
|
|
306
|
-
}
|
|
307
|
-
const cachedRows = Math.min(loadedWindowCount * WINDOW_SIZE, totalRows);
|
|
308
|
-
return `已缓存 ${cachedRows.toLocaleString()} / ${totalRows.toLocaleString()} 行`;
|
|
309
|
-
};
|
|
310
|
-
const getStatusSummary = () => {
|
|
311
|
-
var _a, _b;
|
|
312
|
-
const rows = totalRows || ((_a = getActiveSheet()) === null || _a === void 0 ? void 0 : _a.rowCount) || 0;
|
|
313
|
-
const cols = totalCols || ((_b = getActiveSheet()) === null || _b === void 0 ? void 0 : _b.colCount) || 0;
|
|
314
|
-
if (!rows) {
|
|
315
|
-
return '';
|
|
316
|
-
}
|
|
317
|
-
if (!cols) {
|
|
318
|
-
return `共 ${rows} 行,按视口预取平滑加载`;
|
|
319
|
-
}
|
|
320
|
-
return `共 ${rows} 行,${cols} 列,按视口预取平滑加载`;
|
|
321
|
-
};
|
|
322
|
-
const getZoomState = () => ({
|
|
323
|
-
scale: zoom,
|
|
324
|
-
label: `${Math.round(zoom * 100)}%`,
|
|
325
|
-
canZoomIn: zoom < 2.5,
|
|
326
|
-
canZoomOut: zoom > 0.5,
|
|
327
|
-
canReset: zoom !== 1,
|
|
328
|
-
minScale: 0.5,
|
|
329
|
-
maxScale: 2.5,
|
|
330
|
-
});
|
|
331
|
-
const renderImages = () => {
|
|
332
|
-
const margin = 240;
|
|
333
|
-
const width = Math.max(imageViewportState.width - scalePx(INDEX_COLUMN_WIDTH), 0);
|
|
334
|
-
const height = Math.max(imageViewportState.height - scalePx(HEADER_HEIGHT), 0);
|
|
335
|
-
const visibleImages = sheetImages.filter((image) => {
|
|
336
|
-
const x = scalePx(image.left) - imageViewportState.scrollX;
|
|
337
|
-
const y = scalePx(image.top) - imageViewportState.scrollY;
|
|
338
|
-
return x + scalePx(image.width) >= -margin &&
|
|
339
|
-
x <= width + margin &&
|
|
340
|
-
y + scalePx(image.height) >= -margin &&
|
|
341
|
-
y <= height + margin;
|
|
342
|
-
});
|
|
343
|
-
setHidden(imageViewport, visibleImages.length === 0);
|
|
344
|
-
Object.assign(imageViewport.style, {
|
|
345
|
-
left: `${scalePx(INDEX_COLUMN_WIDTH)}px`,
|
|
346
|
-
top: `${scalePx(HEADER_HEIGHT)}px`,
|
|
347
|
-
});
|
|
348
|
-
imageLayer.style.transform =
|
|
349
|
-
`translate(${-imageViewportState.scrollX}px, ${-imageViewportState.scrollY}px)`;
|
|
350
|
-
imageLayer.replaceChildren(...visibleImages.map((image, index) => {
|
|
351
|
-
const element = documentRef.createElement('img');
|
|
352
|
-
element.className = 'excel-image';
|
|
353
|
-
element.src = image.src;
|
|
354
|
-
element.alt = image.id;
|
|
355
|
-
element.draggable = false;
|
|
356
|
-
Object.assign(element.style, {
|
|
357
|
-
left: `${scalePx(image.left)}px`,
|
|
358
|
-
top: `${scalePx(image.top)}px`,
|
|
359
|
-
width: `${scalePx(image.width)}px`,
|
|
360
|
-
height: `${scalePx(image.height)}px`,
|
|
361
|
-
});
|
|
362
|
-
element.dataset.imageIndex = `${index}`;
|
|
363
|
-
return element;
|
|
364
|
-
}));
|
|
365
|
-
};
|
|
366
|
-
const scrollActiveSheetIntoView = () => {
|
|
367
|
-
requestAnimationFrame(() => {
|
|
368
|
-
var _a;
|
|
369
|
-
(_a = sheetTabsBar.querySelector('.sheet-tab.active')) === null || _a === void 0 ? void 0 : _a.scrollIntoView({
|
|
370
|
-
block: 'nearest',
|
|
371
|
-
inline: 'center',
|
|
372
|
-
behavior: 'smooth',
|
|
373
|
-
});
|
|
374
|
-
});
|
|
375
|
-
};
|
|
376
|
-
const renderChrome = () => {
|
|
377
|
-
setHidden(loading, !showBlockingLoading());
|
|
378
|
-
const loadingTitle = loading.querySelector('[data-loading-title]');
|
|
379
|
-
if (loadingTitle) {
|
|
380
|
-
loadingTitle.textContent = getSheetLoadingText();
|
|
381
|
-
}
|
|
382
|
-
error.textContent = errorMessage;
|
|
383
|
-
setHidden(error, !errorMessage);
|
|
384
|
-
setHidden(sheetLoading, !showStreamingLoading());
|
|
385
|
-
const cacheText = sheetLoading.querySelector('.sheet-loading-summary');
|
|
386
|
-
if (cacheText) {
|
|
387
|
-
cacheText.textContent = getCachedSummary();
|
|
388
|
-
}
|
|
389
|
-
summary.textContent = getStatusSummary();
|
|
390
|
-
sheetTabsBar.replaceChildren(...getSheetTabs().map(sheet => {
|
|
391
|
-
const button = documentRef.createElement('button');
|
|
392
|
-
button.type = 'button';
|
|
393
|
-
button.className = `sheet-tab${sheetIndex === sheet.id ? ' active' : ''}`;
|
|
394
|
-
button.title = sheet.name;
|
|
395
|
-
button.textContent = sheet.name;
|
|
396
|
-
button.setAttribute('aria-pressed', sheetIndex === sheet.id ? 'true' : 'false');
|
|
397
|
-
button.addEventListener('click', () => handleSheet(sheet.id));
|
|
398
|
-
return button;
|
|
399
|
-
}));
|
|
400
|
-
renderImages();
|
|
401
|
-
};
|
|
402
|
-
const setLoading = (value) => {
|
|
403
|
-
loadingState = value;
|
|
404
|
-
renderChrome();
|
|
405
|
-
};
|
|
406
|
-
const emitWorker = (type, payload) => {
|
|
407
|
-
setLoading(true);
|
|
408
|
-
controller.emit(type, payload);
|
|
409
|
-
};
|
|
410
|
-
const applyRowHeight = (row, baseHeight) => {
|
|
411
|
-
row.__baseHeight = baseHeight;
|
|
412
|
-
row._height = scaleRowHeight(baseHeight);
|
|
413
|
-
};
|
|
414
|
-
const syncScaledRowHeights = () => {
|
|
415
|
-
virtualState.rowHeightCache.forEach((height, rowIndex) => {
|
|
416
|
-
const row = virtualState.rows[rowIndex];
|
|
417
|
-
if (row) {
|
|
418
|
-
applyRowHeight(row, height);
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
};
|
|
422
|
-
const setZoom = (scale) => {
|
|
423
|
-
zoom = clampZoom(scale);
|
|
424
|
-
syncScaledRowHeights();
|
|
425
|
-
syncTableLayout();
|
|
426
|
-
zoomEmitter.emit();
|
|
427
|
-
renderChrome();
|
|
428
|
-
return getZoomState();
|
|
429
|
-
};
|
|
430
|
-
registerFileViewerZoomProvider(root, {
|
|
431
|
-
zoomIn: () => setZoom(zoom + 0.1),
|
|
432
|
-
zoomOut: () => setZoom(zoom - 0.1),
|
|
433
|
-
resetZoom: () => setZoom(1),
|
|
434
|
-
setZoom,
|
|
435
|
-
getState: getZoomState,
|
|
436
|
-
subscribe: zoomEmitter.subscribe,
|
|
437
|
-
});
|
|
438
|
-
const syncWindowStats = () => {
|
|
439
|
-
loadedWindowCount = virtualState.loadedWindows.size;
|
|
440
|
-
loadingWindowCount = virtualState.loadingWindows.size;
|
|
441
|
-
renderChrome();
|
|
442
|
-
};
|
|
443
|
-
const syncImageViewport = () => {
|
|
444
|
-
imageViewportState = {
|
|
445
|
-
scrollX: (table === null || table === void 0 ? void 0 : table.ctx.scrollX) || 0,
|
|
446
|
-
scrollY: (table === null || table === void 0 ? void 0 : table.ctx.scrollY) || 0,
|
|
447
|
-
width: tableHost.clientWidth || 0,
|
|
448
|
-
height: tableHost.clientHeight || 0,
|
|
449
|
-
};
|
|
450
|
-
renderImages();
|
|
451
|
-
};
|
|
452
|
-
const buildTableView = () => ({
|
|
453
|
-
config: createTableConfig({
|
|
454
|
-
hostHeight: getHostHeight(),
|
|
455
|
-
sheetDefaults,
|
|
456
|
-
virtualState,
|
|
457
|
-
zoomScale: zoom,
|
|
458
|
-
}),
|
|
459
|
-
columns: getDisplayColumns(virtualState.columns, zoom),
|
|
460
|
-
});
|
|
461
|
-
const resetViewportTracking = () => {
|
|
462
|
-
viewportRange = { start: 0, end: 0 };
|
|
463
|
-
scrollDirection = 1;
|
|
464
|
-
lastScrollY = 0;
|
|
465
|
-
};
|
|
466
|
-
const ensureViewportWindows = (startRow, endRow) => {
|
|
467
|
-
if (!virtualState.active || !virtualState.totalRows) {
|
|
468
|
-
return;
|
|
469
|
-
}
|
|
470
|
-
collectWindowStarts({
|
|
471
|
-
startRow,
|
|
472
|
-
endRow,
|
|
473
|
-
direction: scrollDirection,
|
|
474
|
-
totalRows: virtualState.totalRows,
|
|
475
|
-
}).forEach(windowStart => requestWindow(windowStart, true));
|
|
476
|
-
};
|
|
477
|
-
const scheduleViewportLoad = () => {
|
|
478
|
-
if (!table || disposed) {
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
if (scrollFrame) {
|
|
482
|
-
cancelAnimationFrame(scrollFrame);
|
|
483
|
-
}
|
|
484
|
-
scrollFrame = requestAnimationFrame(() => {
|
|
485
|
-
scrollFrame = 0;
|
|
486
|
-
if (!table || !virtualState.active || !virtualState.totalRows || disposed) {
|
|
487
|
-
return;
|
|
488
|
-
}
|
|
489
|
-
const head = Math.max(table.ctx.body.headIndex || 0, 0);
|
|
490
|
-
const tail = Math.max(table.ctx.body.tailIndex || head, head);
|
|
491
|
-
const scrollY = table.ctx.scrollY || 0;
|
|
492
|
-
scrollDirection = scrollY >= lastScrollY ? 1 : -1;
|
|
493
|
-
lastScrollY = scrollY;
|
|
494
|
-
viewportRange = { start: head, end: tail };
|
|
495
|
-
syncImageViewport();
|
|
496
|
-
ensureViewportWindows(head, tail);
|
|
497
|
-
});
|
|
498
|
-
};
|
|
499
|
-
const ensureTable = () => {
|
|
500
|
-
if (table) {
|
|
501
|
-
return table;
|
|
502
|
-
}
|
|
503
|
-
table = new EVirtTable(tableHost, {
|
|
504
|
-
data: [],
|
|
505
|
-
columns: [],
|
|
506
|
-
config: createTableConfig({
|
|
507
|
-
hostHeight: getHostHeight(),
|
|
508
|
-
sheetDefaults,
|
|
509
|
-
virtualState,
|
|
510
|
-
zoomScale: zoom,
|
|
511
|
-
}),
|
|
512
|
-
});
|
|
513
|
-
table.on('onScrollX', scheduleViewportLoad);
|
|
514
|
-
table.on('onScrollY', scheduleViewportLoad);
|
|
515
|
-
table.on('resize', scheduleViewportLoad);
|
|
516
|
-
return table;
|
|
517
|
-
};
|
|
518
|
-
const renderTable = (instance, columns = virtualState.columns, rows = virtualState.rows, resetScroll = false) => {
|
|
519
|
-
const view = {
|
|
520
|
-
config: createTableConfig({
|
|
521
|
-
hostHeight: getHostHeight(),
|
|
522
|
-
sheetDefaults,
|
|
523
|
-
virtualState,
|
|
524
|
-
zoomScale: zoom,
|
|
525
|
-
}),
|
|
526
|
-
columns: getDisplayColumns(columns, zoom),
|
|
527
|
-
};
|
|
528
|
-
instance.loadConfig(view.config);
|
|
529
|
-
instance.loadColumns(view.columns);
|
|
530
|
-
instance.loadData(rows);
|
|
531
|
-
instance.draw();
|
|
532
|
-
syncImageViewport();
|
|
533
|
-
if (resetScroll) {
|
|
534
|
-
requestAnimationFrame(() => {
|
|
535
|
-
instance.scrollTo(0, 0);
|
|
536
|
-
instance.draw();
|
|
537
|
-
syncImageViewport();
|
|
538
|
-
scheduleViewportLoad();
|
|
539
|
-
});
|
|
540
|
-
return;
|
|
541
|
-
}
|
|
542
|
-
scheduleViewportLoad();
|
|
543
|
-
};
|
|
544
|
-
function syncTableLayout() {
|
|
545
|
-
const instance = ensureTable();
|
|
546
|
-
const { config, columns } = buildTableView();
|
|
547
|
-
instance.loadConfig(config);
|
|
548
|
-
if (virtualState.active && columns.length) {
|
|
549
|
-
instance.loadColumns(columns);
|
|
550
|
-
}
|
|
551
|
-
instance.doLayout();
|
|
552
|
-
instance.draw();
|
|
553
|
-
syncImageViewport();
|
|
554
|
-
scheduleViewportLoad();
|
|
555
|
-
}
|
|
556
|
-
function requestWindow(startRow = 0, silent = true) {
|
|
557
|
-
const sheetId = getActiveSheetId();
|
|
558
|
-
if (sheetId === undefined) {
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
const windowStart = clampWindowStart(startRow, virtualState.totalRows);
|
|
562
|
-
if (virtualState.loadedWindows.has(windowStart) || virtualState.loadingWindows.has(windowStart)) {
|
|
563
|
-
return;
|
|
564
|
-
}
|
|
565
|
-
virtualState.loadingWindows.add(windowStart);
|
|
566
|
-
syncWindowStats();
|
|
567
|
-
if (virtualState.active) {
|
|
568
|
-
markWindowState(virtualState.rows, virtualState.totalRows, windowStart, RowState.Loading);
|
|
569
|
-
table === null || table === void 0 ? void 0 : table.draw();
|
|
570
|
-
}
|
|
571
|
-
errorMessage = '';
|
|
572
|
-
emitWorker('parseSheet', {
|
|
573
|
-
sheet: sheetId,
|
|
574
|
-
startRow: windowStart,
|
|
575
|
-
pageSize: WINDOW_SIZE,
|
|
576
|
-
sessionId: sheetSessionId,
|
|
577
|
-
});
|
|
578
|
-
if (silent) {
|
|
579
|
-
loadingState = false;
|
|
580
|
-
renderChrome();
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
const initializeVirtualSheet = (ws) => {
|
|
584
|
-
const meta = ws.meta;
|
|
585
|
-
if (!meta) {
|
|
586
|
-
return;
|
|
587
|
-
}
|
|
588
|
-
const { columns, dataKeys } = buildColumns(ws);
|
|
589
|
-
virtualState = {
|
|
590
|
-
...createEmptyVirtualState(),
|
|
591
|
-
active: true,
|
|
592
|
-
totalRows: meta.totalRows,
|
|
593
|
-
totalCols: meta.totalCols,
|
|
594
|
-
indexOffset: detectIndexOffset(ws),
|
|
595
|
-
defaults: ws.defaults,
|
|
596
|
-
dataKeys,
|
|
597
|
-
rows: buildRows(meta.totalRows),
|
|
598
|
-
columns,
|
|
599
|
-
};
|
|
600
|
-
sheetDefaults = ws.defaults;
|
|
601
|
-
totalRows = meta.totalRows;
|
|
602
|
-
totalCols = meta.totalCols;
|
|
603
|
-
syncWindowStats();
|
|
604
|
-
queueMicrotask(() => {
|
|
605
|
-
if (disposed) {
|
|
606
|
-
return;
|
|
607
|
-
}
|
|
608
|
-
renderTable(ensureTable(), columns, virtualState.rows, true);
|
|
609
|
-
});
|
|
610
|
-
};
|
|
611
|
-
const clearVirtualRow = (row) => {
|
|
612
|
-
virtualState.dataKeys.forEach((key) => {
|
|
613
|
-
delete row[key];
|
|
614
|
-
});
|
|
615
|
-
};
|
|
616
|
-
const applyStructureRowHeights = (rowHeights) => {
|
|
617
|
-
if (!Array.isArray(rowHeights)) {
|
|
618
|
-
return;
|
|
619
|
-
}
|
|
620
|
-
rowHeights.forEach((rawHeight, absoluteRow) => {
|
|
621
|
-
if (rawHeight === undefined) {
|
|
622
|
-
return;
|
|
623
|
-
}
|
|
624
|
-
const row = virtualState.rows[absoluteRow];
|
|
625
|
-
if (!row) {
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
|
-
const height = normalizeRowHeight(rawHeight, virtualState.defaults.rowHeight);
|
|
629
|
-
applyRowHeight(row, height);
|
|
630
|
-
virtualState.rowHeightCache.set(absoluteRow, height);
|
|
631
|
-
});
|
|
632
|
-
};
|
|
633
|
-
const applyWindowRows = (ws) => {
|
|
634
|
-
var _a, _b;
|
|
635
|
-
const meta = ws.meta;
|
|
636
|
-
if (!meta) {
|
|
637
|
-
return;
|
|
638
|
-
}
|
|
639
|
-
const rowIndexes = [];
|
|
640
|
-
const endRow = Math.min(meta.endRow, virtualState.totalRows);
|
|
641
|
-
for (let absoluteRow = meta.startRow; absoluteRow < endRow; absoluteRow += 1) {
|
|
642
|
-
const row = virtualState.rows[absoluteRow];
|
|
643
|
-
const relativeRow = absoluteRow - meta.startRow;
|
|
644
|
-
if (!row) {
|
|
645
|
-
continue;
|
|
646
|
-
}
|
|
647
|
-
clearVirtualRow(row);
|
|
648
|
-
const data = ((_a = ws.data) === null || _a === void 0 ? void 0 : _a[relativeRow]) || [];
|
|
649
|
-
data.forEach((value, colIndex) => {
|
|
650
|
-
if (value === '' || value === null || value === undefined) {
|
|
651
|
-
return;
|
|
652
|
-
}
|
|
653
|
-
row[getDataKey(colIndex)] = value;
|
|
654
|
-
});
|
|
655
|
-
const windowHeight = getRowHeight(ws.rowHeights, relativeRow, virtualState.defaults.rowHeight);
|
|
656
|
-
const height = normalizeRowHeight(getRowHeight((_b = ws.structure) === null || _b === void 0 ? void 0 : _b.rowHeights, absoluteRow, windowHeight), virtualState.defaults.rowHeight);
|
|
657
|
-
applyRowHeight(row, height);
|
|
658
|
-
row[ROW_STATE_FIELD] = RowState.Loaded;
|
|
659
|
-
virtualState.rowHeightCache.set(absoluteRow, height);
|
|
660
|
-
rowIndexes.push(absoluteRow);
|
|
661
|
-
}
|
|
662
|
-
virtualState.windowRows.set(meta.startRow, rowIndexes);
|
|
663
|
-
};
|
|
664
|
-
const applyWindowCells = (ws) => {
|
|
665
|
-
const meta = ws.meta;
|
|
666
|
-
if (!meta) {
|
|
667
|
-
return;
|
|
668
|
-
}
|
|
669
|
-
const keys = [];
|
|
670
|
-
Object.entries(ws.cell || {}).forEach(([key, value]) => {
|
|
671
|
-
const [row, col] = key.split('-').map(Number);
|
|
672
|
-
const absoluteKey = displayCellKey(meta.startRow + row, col + 1);
|
|
673
|
-
const style = normalizeCellStyle(value);
|
|
674
|
-
if (!style) {
|
|
675
|
-
return;
|
|
676
|
-
}
|
|
677
|
-
virtualState.cellCache.set(absoluteKey, style);
|
|
678
|
-
keys.push(absoluteKey);
|
|
679
|
-
});
|
|
680
|
-
virtualState.windowCells.set(meta.startRow, keys);
|
|
681
|
-
};
|
|
682
|
-
const setSheetMerges = (merges) => {
|
|
683
|
-
virtualState.mergeStartMap.clear();
|
|
684
|
-
virtualState.mergeCoveredMap.clear();
|
|
685
|
-
merges.forEach((merge) => {
|
|
686
|
-
const startKey = displayCellKey(merge.row, merge.col + 1);
|
|
687
|
-
virtualState.mergeStartMap.set(startKey, {
|
|
688
|
-
...merge,
|
|
689
|
-
col: merge.col + 1,
|
|
690
|
-
});
|
|
691
|
-
for (let rowOffset = 0; rowOffset < merge.rowspan; rowOffset += 1) {
|
|
692
|
-
for (let colOffset = 0; colOffset < merge.colspan; colOffset += 1) {
|
|
693
|
-
if (rowOffset === 0 && colOffset === 0) {
|
|
694
|
-
continue;
|
|
695
|
-
}
|
|
696
|
-
const coveredKey = displayCellKey(merge.row + rowOffset, merge.col + colOffset + 1);
|
|
697
|
-
virtualState.mergeCoveredMap.set(coveredKey, true);
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
});
|
|
701
|
-
};
|
|
702
|
-
const applySheetStructure = (ws) => {
|
|
703
|
-
const structure = ws.structure;
|
|
704
|
-
const mergeList = structure === null || structure === void 0 ? void 0 : structure.merge;
|
|
705
|
-
if (mergeList) {
|
|
706
|
-
setSheetMerges(mergeList);
|
|
707
|
-
}
|
|
708
|
-
else {
|
|
709
|
-
const meta = ws.meta;
|
|
710
|
-
if (meta && !virtualState.mergeStartMap.size) {
|
|
711
|
-
setSheetMerges((ws.merge || []).map((merge) => ({
|
|
712
|
-
...merge,
|
|
713
|
-
row: merge.row + meta.startRow,
|
|
714
|
-
})));
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
applyStructureRowHeights(structure === null || structure === void 0 ? void 0 : structure.rowHeights);
|
|
718
|
-
if (structure === null || structure === void 0 ? void 0 : structure.images) {
|
|
719
|
-
sheetImages = structure.images;
|
|
720
|
-
const sheetId = getActiveSheetId();
|
|
721
|
-
if (sheetId !== undefined) {
|
|
722
|
-
sheetImageCache.set(sheetId, structure.images);
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
};
|
|
726
|
-
const applyVirtualWindow = (ws) => {
|
|
727
|
-
var _a;
|
|
728
|
-
const meta = ws.meta;
|
|
729
|
-
if (!meta) {
|
|
730
|
-
return;
|
|
731
|
-
}
|
|
732
|
-
if (!virtualState.active) {
|
|
733
|
-
initializeVirtualSheet(ws);
|
|
734
|
-
}
|
|
735
|
-
applySheetStructure(ws);
|
|
736
|
-
applyWindowRows(ws);
|
|
737
|
-
applyWindowCells(ws);
|
|
738
|
-
virtualState.loadedWindows.add(meta.startRow);
|
|
739
|
-
virtualState.loadingWindows.delete(meta.startRow);
|
|
740
|
-
syncWindowStats();
|
|
741
|
-
hasInitialWindow = true;
|
|
742
|
-
const activeSheetId = getActiveSheetId();
|
|
743
|
-
if (activeSheetId !== undefined) {
|
|
744
|
-
sheetStateCache.set(activeSheetId, virtualState);
|
|
745
|
-
}
|
|
746
|
-
table === null || table === void 0 ? void 0 : table.draw();
|
|
747
|
-
loadingState = false;
|
|
748
|
-
sheetInitializing = false;
|
|
749
|
-
renderChrome();
|
|
750
|
-
if (!hasNotifiedFirstPaint) {
|
|
751
|
-
hasNotifiedFirstPaint = true;
|
|
752
|
-
(_a = context === null || context === void 0 ? void 0 : context.onProgressiveRender) === null || _a === void 0 ? void 0 : _a.call(context);
|
|
753
|
-
}
|
|
754
|
-
const start = viewportRange.start || meta.startRow;
|
|
755
|
-
const end = Math.max(viewportRange.end, meta.endRow - 1, meta.startRow);
|
|
756
|
-
ensureViewportWindows(start, end);
|
|
757
|
-
};
|
|
758
|
-
const resetViewState = () => {
|
|
759
|
-
errorMessage = '';
|
|
760
|
-
totalRows = 0;
|
|
761
|
-
totalCols = 0;
|
|
762
|
-
sheetDefaults = { ...DEFAULT_SHEET_DEFAULTS };
|
|
763
|
-
sheetImages = [];
|
|
764
|
-
virtualState = createEmptyVirtualState();
|
|
765
|
-
hasInitialWindow = false;
|
|
766
|
-
resetViewportTracking();
|
|
767
|
-
syncWindowStats();
|
|
768
|
-
syncImageViewport();
|
|
769
|
-
if (!table) {
|
|
770
|
-
return;
|
|
771
|
-
}
|
|
772
|
-
table.loadColumns([]);
|
|
773
|
-
table.loadData([]);
|
|
774
|
-
table.scrollTo(0, 0);
|
|
775
|
-
table.draw();
|
|
776
|
-
};
|
|
777
|
-
const cacheCurrentSheetState = () => {
|
|
778
|
-
const sheetId = getActiveSheetId();
|
|
779
|
-
if (sheetId === undefined || !virtualState.active) {
|
|
780
|
-
return;
|
|
781
|
-
}
|
|
782
|
-
sheetStateCache.set(sheetId, virtualState);
|
|
783
|
-
};
|
|
784
|
-
const restoreCachedSheetState = (sheetId) => {
|
|
785
|
-
const cached = sheetStateCache.get(sheetId);
|
|
786
|
-
if (!cached) {
|
|
787
|
-
return false;
|
|
788
|
-
}
|
|
789
|
-
cached.loadingWindows.clear();
|
|
790
|
-
virtualState = cached;
|
|
791
|
-
errorMessage = '';
|
|
792
|
-
totalRows = cached.totalRows;
|
|
793
|
-
totalCols = cached.totalCols;
|
|
794
|
-
sheetDefaults = cached.defaults;
|
|
795
|
-
sheetImages = sheetImageCache.get(sheetId) || [];
|
|
796
|
-
hasInitialWindow = cached.loadedWindows.size > 0;
|
|
797
|
-
sheetInitializing = !hasInitialWindow;
|
|
798
|
-
syncWindowStats();
|
|
799
|
-
queueMicrotask(() => {
|
|
800
|
-
if (disposed) {
|
|
801
|
-
return;
|
|
802
|
-
}
|
|
803
|
-
renderTable(ensureTable(), cached.columns, cached.rows);
|
|
804
|
-
syncImageViewport();
|
|
805
|
-
});
|
|
806
|
-
return true;
|
|
807
|
-
};
|
|
808
|
-
const startSheetSession = () => {
|
|
809
|
-
const sheetId = getActiveSheetId();
|
|
810
|
-
if (sheetId === undefined) {
|
|
811
|
-
loadingState = false;
|
|
812
|
-
sheetInitializing = false;
|
|
813
|
-
renderChrome();
|
|
814
|
-
return;
|
|
815
|
-
}
|
|
816
|
-
sheetSessionId += 1;
|
|
817
|
-
if (restoreCachedSheetState(sheetId)) {
|
|
818
|
-
loadingState = false;
|
|
819
|
-
renderChrome();
|
|
820
|
-
return;
|
|
821
|
-
}
|
|
822
|
-
sheetInitializing = true;
|
|
823
|
-
resetViewState();
|
|
824
|
-
requestWindow(0, false);
|
|
825
|
-
};
|
|
826
|
-
function handleSheet(index) {
|
|
827
|
-
if (sheetIndex === index) {
|
|
828
|
-
scrollActiveSheetIntoView();
|
|
829
|
-
return;
|
|
830
|
-
}
|
|
831
|
-
cacheCurrentSheetState();
|
|
832
|
-
sheetIndex = index;
|
|
833
|
-
renderChrome();
|
|
834
|
-
startSheetSession();
|
|
835
|
-
scrollActiveSheetIntoView();
|
|
836
|
-
}
|
|
837
|
-
const emitParseWorkbook = () => {
|
|
838
|
-
emitWorker('parseWorkbook', { workbook: buffer });
|
|
839
|
-
};
|
|
840
|
-
controller.onWorkerEvent('sheets', ({ sheets: list }) => {
|
|
841
|
-
sheets = list;
|
|
842
|
-
const firstSheet = list.find((sheet) => !sheet.hidden) || list[0];
|
|
843
|
-
if (firstSheet) {
|
|
844
|
-
sheetIndex = firstSheet.id;
|
|
845
|
-
renderChrome();
|
|
846
|
-
startSheetSession();
|
|
847
|
-
scrollActiveSheetIntoView();
|
|
848
|
-
return;
|
|
849
|
-
}
|
|
850
|
-
sheetInitializing = false;
|
|
851
|
-
loadingState = false;
|
|
852
|
-
renderChrome();
|
|
853
|
-
});
|
|
854
|
-
controller.onWorkerEvent('parseSheet', ({ sessionId, sheet, sheetData: ws }) => {
|
|
855
|
-
if (sessionId !== sheetSessionId || sheet !== getActiveSheetId()) {
|
|
856
|
-
return;
|
|
857
|
-
}
|
|
858
|
-
applyVirtualWindow(ws);
|
|
859
|
-
});
|
|
860
|
-
controller.onWorkerEvent('parseError', ({ sessionId, startRow, message }) => {
|
|
861
|
-
if (sessionId && sessionId !== sheetSessionId) {
|
|
862
|
-
return;
|
|
863
|
-
}
|
|
864
|
-
sheetInitializing = false;
|
|
865
|
-
loadingState = false;
|
|
866
|
-
if (typeof startRow === 'number') {
|
|
867
|
-
virtualState.loadingWindows.delete(startRow);
|
|
868
|
-
syncWindowStats();
|
|
869
|
-
if (virtualState.active) {
|
|
870
|
-
markWindowState(virtualState.rows, virtualState.totalRows, startRow, RowState.Placeholder);
|
|
871
|
-
table === null || table === void 0 ? void 0 : table.draw();
|
|
872
|
-
}
|
|
873
|
-
}
|
|
874
|
-
else {
|
|
875
|
-
virtualState.loadingWindows.clear();
|
|
876
|
-
syncWindowStats();
|
|
877
|
-
}
|
|
878
|
-
errorMessage = message || 'Excel 解析失败';
|
|
879
|
-
renderChrome();
|
|
880
|
-
});
|
|
881
|
-
controller.onWorkerError((event) => {
|
|
882
|
-
sheetInitializing = false;
|
|
883
|
-
loadingState = false;
|
|
884
|
-
errorMessage = event.message || 'Excel Worker 运行失败';
|
|
885
|
-
renderChrome();
|
|
886
|
-
});
|
|
887
|
-
(_a = context === null || context === void 0 ? void 0 : context.registerExportAdapter) === null || _a === void 0 ? void 0 : _a.call(context, {
|
|
888
|
-
print: false,
|
|
889
|
-
exportHtml: false,
|
|
890
|
-
});
|
|
891
|
-
ensureTable();
|
|
892
|
-
const ResizeObserverCtor = ((_b = getTargetWindow(target)) === null || _b === void 0 ? void 0 : _b.ResizeObserver) ||
|
|
893
|
-
(typeof ResizeObserver !== 'undefined' ? ResizeObserver : undefined);
|
|
894
|
-
if (ResizeObserverCtor) {
|
|
895
|
-
resizeObserver = new ResizeObserverCtor(() => {
|
|
896
|
-
if (resizeFrame) {
|
|
897
|
-
cancelAnimationFrame(resizeFrame);
|
|
898
|
-
}
|
|
899
|
-
resizeFrame = requestAnimationFrame(() => {
|
|
900
|
-
resizeFrame = 0;
|
|
901
|
-
syncTableLayout();
|
|
902
|
-
});
|
|
903
|
-
});
|
|
904
|
-
resizeObserver.observe(tableHost);
|
|
905
|
-
}
|
|
906
|
-
renderChrome();
|
|
907
|
-
emitParseWorkbook();
|
|
908
|
-
return {
|
|
909
|
-
$el: root,
|
|
910
|
-
unmount() {
|
|
911
|
-
var _a;
|
|
912
|
-
disposed = true;
|
|
913
|
-
if (resizeFrame) {
|
|
914
|
-
cancelAnimationFrame(resizeFrame);
|
|
915
|
-
}
|
|
916
|
-
if (scrollFrame) {
|
|
917
|
-
cancelAnimationFrame(scrollFrame);
|
|
918
|
-
}
|
|
919
|
-
resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.disconnect();
|
|
920
|
-
resizeObserver = null;
|
|
921
|
-
unregisterFileViewerZoomProvider(root);
|
|
922
|
-
controller.destroy();
|
|
923
|
-
table === null || table === void 0 ? void 0 : table.destroy();
|
|
924
|
-
table = null;
|
|
925
|
-
(_a = context === null || context === void 0 ? void 0 : context.registerExportAdapter) === null || _a === void 0 ? void 0 : _a.call(context, null);
|
|
926
|
-
},
|
|
927
|
-
};
|
|
928
|
-
};
|
|
929
|
-
export default renderFileViewerSpreadsheet;
|