@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,833 +0,0 @@
|
|
|
1
|
-
import tinycolor from 'tinycolor2';
|
|
2
|
-
import { displayCellKey, getDataKey, getRowState, INDEX_COLUMN_KEY, ROW_KEY_FIELD, RowState } from './state.js';
|
|
3
|
-
export const INDEX_COLUMN_WIDTH = 68;
|
|
4
|
-
const TABLE_FONT_FAMILY = 'Aptos, Calibri, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif';
|
|
5
|
-
const TABLE_FONT_SIZE = 11;
|
|
6
|
-
const MIN_RENDERABLE_ROW_HEIGHT = 8;
|
|
7
|
-
const HIDDEN_ROW_HEIGHT = 0.1;
|
|
8
|
-
const CELL_PADDING = 2;
|
|
9
|
-
const CELL_LINE_HEIGHT = 1.2;
|
|
10
|
-
export const HEADER_HEIGHT = 34;
|
|
11
|
-
const EXCEL_HEADER_BG = '#f3f3f3';
|
|
12
|
-
const EXCEL_HEADER_TEXT = '#5f6368';
|
|
13
|
-
const EXCEL_GRID = '#d7dbe0';
|
|
14
|
-
const EXCEL_GREEN = '#21a366';
|
|
15
|
-
const EXCEL_GREEN_SOFT = 'rgba(33, 163, 102, 0.1)';
|
|
16
|
-
const DATA_AREA_MIN_COL_INDEX = 1;
|
|
17
|
-
const BORDER_SIDE_KEYS = ['Top', 'Right', 'Bottom', 'Left'];
|
|
18
|
-
const DEFAULT_BORDER_COLOR = '#000000';
|
|
19
|
-
const BORDER_STYLE_PRIORITY = {
|
|
20
|
-
double: 8,
|
|
21
|
-
solid: 7,
|
|
22
|
-
dashed: 5,
|
|
23
|
-
dotted: 4
|
|
24
|
-
};
|
|
25
|
-
const HEADER_FONT = `bold 12px ${TABLE_FONT_FAMILY}`;
|
|
26
|
-
const BODY_FONT = `${TABLE_FONT_SIZE}px ${TABLE_FONT_FAMILY}`;
|
|
27
|
-
const MAX_OVERFLOW_SCAN_COLS = 32;
|
|
28
|
-
const INDEX_CELL_STYLE = {
|
|
29
|
-
backgroundColor: EXCEL_HEADER_BG,
|
|
30
|
-
color: EXCEL_HEADER_TEXT,
|
|
31
|
-
font: HEADER_FONT
|
|
32
|
-
};
|
|
33
|
-
const LOADING_CELL_STYLE = {
|
|
34
|
-
backgroundColor: '#f4f7f9',
|
|
35
|
-
color: '#73808d',
|
|
36
|
-
font: `italic ${TABLE_FONT_SIZE}px ${TABLE_FONT_FAMILY}`
|
|
37
|
-
};
|
|
38
|
-
let measureCanvas;
|
|
39
|
-
const textWidthCache = new Map();
|
|
40
|
-
const normalizeZoomScale = (scale = 1) => {
|
|
41
|
-
return Number.isFinite(scale) ? Math.min(2.5, Math.max(0.5, scale)) : 1;
|
|
42
|
-
};
|
|
43
|
-
const scaleNumber = (value, zoomScale) => {
|
|
44
|
-
return Math.max(1, Math.round(value * normalizeZoomScale(zoomScale)));
|
|
45
|
-
};
|
|
46
|
-
const scaleFont = (font, zoomScale) => {
|
|
47
|
-
if (!font) {
|
|
48
|
-
return font;
|
|
49
|
-
}
|
|
50
|
-
const normalizedScale = normalizeZoomScale(zoomScale);
|
|
51
|
-
return font.replace(/(\d+(?:\.\d+)?)px/g, (_, size) => {
|
|
52
|
-
return `${Number(size) * normalizedScale}px`;
|
|
53
|
-
});
|
|
54
|
-
};
|
|
55
|
-
const scaleBorder = (border, zoomScale) => {
|
|
56
|
-
if (!border) {
|
|
57
|
-
return undefined;
|
|
58
|
-
}
|
|
59
|
-
return {
|
|
60
|
-
...border,
|
|
61
|
-
width: Math.max(0.5, border.width * normalizeZoomScale(zoomScale))
|
|
62
|
-
};
|
|
63
|
-
};
|
|
64
|
-
const scaleCellStyle = (style, zoomScale) => {
|
|
65
|
-
if (!style) {
|
|
66
|
-
return undefined;
|
|
67
|
-
}
|
|
68
|
-
return {
|
|
69
|
-
...style,
|
|
70
|
-
font: scaleFont(style.font, zoomScale),
|
|
71
|
-
borderTop: scaleBorder(style.borderTop, zoomScale),
|
|
72
|
-
borderRight: scaleBorder(style.borderRight, zoomScale),
|
|
73
|
-
borderBottom: scaleBorder(style.borderBottom, zoomScale),
|
|
74
|
-
borderLeft: scaleBorder(style.borderLeft, zoomScale)
|
|
75
|
-
};
|
|
76
|
-
};
|
|
77
|
-
const getHeaderFont = (zoomScale) => scaleFont(HEADER_FONT, zoomScale) || HEADER_FONT;
|
|
78
|
-
const getBodyFont = (zoomScale) => scaleFont(BODY_FONT, zoomScale) || BODY_FONT;
|
|
79
|
-
const getIndexCellStyle = (zoomScale) => ({
|
|
80
|
-
...INDEX_CELL_STYLE,
|
|
81
|
-
font: getHeaderFont(zoomScale)
|
|
82
|
-
});
|
|
83
|
-
const getLoadingCellStyle = (zoomScale) => ({
|
|
84
|
-
...LOADING_CELL_STYLE,
|
|
85
|
-
font: scaleFont(LOADING_CELL_STYLE.font, zoomScale)
|
|
86
|
-
});
|
|
87
|
-
const cloneColumns = (columns) => {
|
|
88
|
-
return columns.map(column => {
|
|
89
|
-
var _a;
|
|
90
|
-
return ({
|
|
91
|
-
...column,
|
|
92
|
-
...(((_a = column.children) === null || _a === void 0 ? void 0 : _a.length) ? { children: cloneColumns(column.children) } : {})
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
};
|
|
96
|
-
const buildFont = (style) => {
|
|
97
|
-
if (typeof style.font === 'string' && style.font.trim()) {
|
|
98
|
-
return style.font;
|
|
99
|
-
}
|
|
100
|
-
const hasFont = style.fontFamily !== undefined ||
|
|
101
|
-
style.fontSize !== undefined ||
|
|
102
|
-
style.fontWeight !== undefined ||
|
|
103
|
-
style.fontStyle !== undefined;
|
|
104
|
-
if (!hasFont) {
|
|
105
|
-
return undefined;
|
|
106
|
-
}
|
|
107
|
-
const normalizedWeight = (() => {
|
|
108
|
-
const { fontWeight } = style;
|
|
109
|
-
if (typeof fontWeight === 'number') {
|
|
110
|
-
return fontWeight >= 600 ? 'bold' : 'normal';
|
|
111
|
-
}
|
|
112
|
-
if (typeof fontWeight === 'string') {
|
|
113
|
-
const trimmed = fontWeight.trim();
|
|
114
|
-
if (/^\d+$/.test(trimmed)) {
|
|
115
|
-
return Number(trimmed) >= 600 ? 'bold' : 'normal';
|
|
116
|
-
}
|
|
117
|
-
return trimmed;
|
|
118
|
-
}
|
|
119
|
-
return 'normal';
|
|
120
|
-
})();
|
|
121
|
-
return [
|
|
122
|
-
style.fontStyle || 'normal',
|
|
123
|
-
normalizedWeight,
|
|
124
|
-
`${Number.parseInt(style.fontSize, 10) || TABLE_FONT_SIZE}px`,
|
|
125
|
-
style.fontFamily || TABLE_FONT_FAMILY
|
|
126
|
-
].join(' ');
|
|
127
|
-
};
|
|
128
|
-
const alignFromClassName = (className) => {
|
|
129
|
-
if (!className) {
|
|
130
|
-
return undefined;
|
|
131
|
-
}
|
|
132
|
-
if (className.includes('htLeft')) {
|
|
133
|
-
return 'left';
|
|
134
|
-
}
|
|
135
|
-
if (className.includes('htRight')) {
|
|
136
|
-
return 'right';
|
|
137
|
-
}
|
|
138
|
-
if (className.includes('htCenter')) {
|
|
139
|
-
return 'center';
|
|
140
|
-
}
|
|
141
|
-
return undefined;
|
|
142
|
-
};
|
|
143
|
-
const verticalAlignFromClassName = (className) => {
|
|
144
|
-
if (!className) {
|
|
145
|
-
return undefined;
|
|
146
|
-
}
|
|
147
|
-
if (className.includes('htTop')) {
|
|
148
|
-
return 'top';
|
|
149
|
-
}
|
|
150
|
-
if (className.includes('htBottom')) {
|
|
151
|
-
return 'bottom';
|
|
152
|
-
}
|
|
153
|
-
if (className.includes('htMiddle')) {
|
|
154
|
-
return 'middle';
|
|
155
|
-
}
|
|
156
|
-
return undefined;
|
|
157
|
-
};
|
|
158
|
-
const hasClassName = (className, value) => {
|
|
159
|
-
return !!(className === null || className === void 0 ? void 0 : className.split(/\s+/).includes(value));
|
|
160
|
-
};
|
|
161
|
-
const getColumnWidth = (widths, index, fallback) => {
|
|
162
|
-
var _a;
|
|
163
|
-
if (typeof widths === 'number') {
|
|
164
|
-
return widths;
|
|
165
|
-
}
|
|
166
|
-
return (_a = widths === null || widths === void 0 ? void 0 : widths[index]) !== null && _a !== void 0 ? _a : fallback;
|
|
167
|
-
};
|
|
168
|
-
const getRenderColumnWidth = (column) => {
|
|
169
|
-
const width = Number(column === null || column === void 0 ? void 0 : column.width);
|
|
170
|
-
return Number.isFinite(width) && width > 0 ? width : 0;
|
|
171
|
-
};
|
|
172
|
-
const isVisibleDataColumn = (column) => {
|
|
173
|
-
return !!column && !column.hide && getRenderColumnWidth(column) > 0;
|
|
174
|
-
};
|
|
175
|
-
const getSheetColumnsMeta = (ws) => {
|
|
176
|
-
var _a, _b;
|
|
177
|
-
return ((_b = (_a = ws.structure) === null || _a === void 0 ? void 0 : _a.columns) === null || _b === void 0 ? void 0 : _b.length) ? ws.structure.columns : ws.columns;
|
|
178
|
-
};
|
|
179
|
-
const getSheetColWidths = (ws) => {
|
|
180
|
-
var _a, _b;
|
|
181
|
-
return (_b = (_a = ws.structure) === null || _a === void 0 ? void 0 : _a.colWidths) !== null && _b !== void 0 ? _b : ws.colWidths;
|
|
182
|
-
};
|
|
183
|
-
export const getRowHeight = (heights, index, fallback) => {
|
|
184
|
-
var _a;
|
|
185
|
-
if (typeof heights === 'number') {
|
|
186
|
-
return heights;
|
|
187
|
-
}
|
|
188
|
-
return (_a = heights === null || heights === void 0 ? void 0 : heights[index]) !== null && _a !== void 0 ? _a : fallback;
|
|
189
|
-
};
|
|
190
|
-
// Excel 已经给出了行高时,预览层不再二次猜测。
|
|
191
|
-
// 只有完全缺失时才回退到默认行高,同时给极小值留一个最小可渲染下限。
|
|
192
|
-
export const normalizeRowHeight = (height, fallback) => {
|
|
193
|
-
if (typeof height === 'number' && Number.isFinite(height)) {
|
|
194
|
-
if (height <= 0) {
|
|
195
|
-
// e-virt-table 内部用 item._height || CELL_HEIGHT,0 会被误判为未设置。
|
|
196
|
-
return HIDDEN_ROW_HEIGHT;
|
|
197
|
-
}
|
|
198
|
-
return Math.max(Math.ceil(height), MIN_RENDERABLE_ROW_HEIGHT);
|
|
199
|
-
}
|
|
200
|
-
return Math.max(Math.ceil(fallback), MIN_RENDERABLE_ROW_HEIGHT);
|
|
201
|
-
};
|
|
202
|
-
const isPlainTextCell = (value) => {
|
|
203
|
-
if (value === null || value === undefined) {
|
|
204
|
-
return false;
|
|
205
|
-
}
|
|
206
|
-
const text = `${value}`.trim();
|
|
207
|
-
if (!text) {
|
|
208
|
-
return false;
|
|
209
|
-
}
|
|
210
|
-
return !/^\d+([./:-]\d+)*$/.test(text);
|
|
211
|
-
};
|
|
212
|
-
// 普通明细表通常会把第一行当成字段表头,而报表类工作表往往需要保留原始 Excel 行号。
|
|
213
|
-
// 这里只在“首行像简单字段头且没有合并单元格”时,才给左侧序号做 1 行偏移。
|
|
214
|
-
export const detectIndexOffset = (ws) => {
|
|
215
|
-
const meta = ws.meta;
|
|
216
|
-
const rows = ws.data || [];
|
|
217
|
-
if (!meta || rows.length < 2 || (ws.merge || []).length) {
|
|
218
|
-
return 0;
|
|
219
|
-
}
|
|
220
|
-
const firstRow = rows[0] || [];
|
|
221
|
-
const secondRow = rows[1] || [];
|
|
222
|
-
const firstRowValues = firstRow.filter(value => `${value !== null && value !== void 0 ? value : ''}`.trim() !== '');
|
|
223
|
-
const secondRowValues = secondRow.filter(value => `${value !== null && value !== void 0 ? value : ''}`.trim() !== '');
|
|
224
|
-
if (firstRowValues.length < Math.min(Math.max(Math.floor(meta.totalCols / 2), 3), 6)) {
|
|
225
|
-
return 0;
|
|
226
|
-
}
|
|
227
|
-
if (!firstRowValues.every(isPlainTextCell) || secondRowValues.length < 2) {
|
|
228
|
-
return 0;
|
|
229
|
-
}
|
|
230
|
-
return 1;
|
|
231
|
-
};
|
|
232
|
-
export const buildColumns = (ws) => {
|
|
233
|
-
var _a;
|
|
234
|
-
const columnsMeta = getSheetColumnsMeta(ws);
|
|
235
|
-
const colWidths = getSheetColWidths(ws);
|
|
236
|
-
const columns = [{
|
|
237
|
-
key: INDEX_COLUMN_KEY,
|
|
238
|
-
title: '',
|
|
239
|
-
type: 'index',
|
|
240
|
-
fixed: 'left',
|
|
241
|
-
width: INDEX_COLUMN_WIDTH,
|
|
242
|
-
minWidth: INDEX_COLUMN_WIDTH,
|
|
243
|
-
maxWidth: INDEX_COLUMN_WIDTH,
|
|
244
|
-
widthFillDisable: true,
|
|
245
|
-
headerAlign: 'center',
|
|
246
|
-
align: 'center',
|
|
247
|
-
headerVerticalAlign: 'middle',
|
|
248
|
-
verticalAlign: 'middle',
|
|
249
|
-
overflowTooltipShow: false,
|
|
250
|
-
overflowTooltipHeaderShow: false
|
|
251
|
-
}];
|
|
252
|
-
const dataKeys = [];
|
|
253
|
-
for (let index = 0; index < (((_a = ws.meta) === null || _a === void 0 ? void 0 : _a.totalCols) || 0); index += 1) {
|
|
254
|
-
const key = getDataKey(index);
|
|
255
|
-
const column = columnsMeta === null || columnsMeta === void 0 ? void 0 : columnsMeta[index];
|
|
256
|
-
const width = getColumnWidth(colWidths, index, ws.defaults.colWidth);
|
|
257
|
-
const hidden = !!(column === null || column === void 0 ? void 0 : column.hidden) || width <= 0;
|
|
258
|
-
const columnVerticalAlign = verticalAlignFromClassName(column === null || column === void 0 ? void 0 : column.className) || 'middle';
|
|
259
|
-
dataKeys.push(key);
|
|
260
|
-
columns.push({
|
|
261
|
-
key,
|
|
262
|
-
title: (column === null || column === void 0 ? void 0 : column.title) || `${index + 1}`,
|
|
263
|
-
width: hidden ? 0 : Math.max(Math.ceil(width), 1),
|
|
264
|
-
hide: hidden,
|
|
265
|
-
widthFillDisable: true,
|
|
266
|
-
renderType: 'both',
|
|
267
|
-
headerAlign: 'center',
|
|
268
|
-
headerVerticalAlign: 'middle',
|
|
269
|
-
align: alignFromClassName(column === null || column === void 0 ? void 0 : column.className) || 'left',
|
|
270
|
-
verticalAlign: columnVerticalAlign,
|
|
271
|
-
overflowTooltipShow: true,
|
|
272
|
-
overflowTooltipHeaderShow: true
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
return { columns, dataKeys };
|
|
276
|
-
};
|
|
277
|
-
const scaleColumn = (column, zoomScale) => {
|
|
278
|
-
var _a;
|
|
279
|
-
const nextColumn = {
|
|
280
|
-
...column,
|
|
281
|
-
...(((_a = column.children) === null || _a === void 0 ? void 0 : _a.length) ? { children: column.children.map(child => scaleColumn(child, zoomScale)) } : {})
|
|
282
|
-
};
|
|
283
|
-
const width = Number(column.width);
|
|
284
|
-
if (Number.isFinite(width) && width > 0) {
|
|
285
|
-
;
|
|
286
|
-
nextColumn.width = scaleNumber(width, zoomScale);
|
|
287
|
-
}
|
|
288
|
-
const minWidth = Number(column.minWidth);
|
|
289
|
-
if (Number.isFinite(minWidth) && minWidth > 0) {
|
|
290
|
-
;
|
|
291
|
-
nextColumn.minWidth = scaleNumber(minWidth, zoomScale);
|
|
292
|
-
}
|
|
293
|
-
const maxWidth = Number(column.maxWidth);
|
|
294
|
-
if (Number.isFinite(maxWidth) && maxWidth > 0) {
|
|
295
|
-
;
|
|
296
|
-
nextColumn.maxWidth = scaleNumber(maxWidth, zoomScale);
|
|
297
|
-
}
|
|
298
|
-
return nextColumn;
|
|
299
|
-
};
|
|
300
|
-
// Excel 预览优先忠实还原原始列宽,不再为了“铺满容器”二次拉伸列宽。
|
|
301
|
-
export const getDisplayColumns = (columns, zoomScale = 1) => {
|
|
302
|
-
const normalizedScale = normalizeZoomScale(zoomScale);
|
|
303
|
-
if (normalizedScale === 1) {
|
|
304
|
-
return cloneColumns(columns);
|
|
305
|
-
}
|
|
306
|
-
return columns.map(column => scaleColumn(column, normalizedScale));
|
|
307
|
-
};
|
|
308
|
-
const toBorderWidth = (value) => {
|
|
309
|
-
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
310
|
-
return Math.max(value, 0);
|
|
311
|
-
}
|
|
312
|
-
if (typeof value === 'string') {
|
|
313
|
-
const parsed = Number.parseFloat(value);
|
|
314
|
-
return Number.isFinite(parsed) ? Math.max(parsed, 0) : 0;
|
|
315
|
-
}
|
|
316
|
-
return 0;
|
|
317
|
-
};
|
|
318
|
-
const toBorderStyle = (value) => {
|
|
319
|
-
if (typeof value !== 'string') {
|
|
320
|
-
return 'solid';
|
|
321
|
-
}
|
|
322
|
-
const style = value.trim();
|
|
323
|
-
switch (style) {
|
|
324
|
-
case 'double':
|
|
325
|
-
case 'dashed':
|
|
326
|
-
case 'dotted':
|
|
327
|
-
case 'solid':
|
|
328
|
-
return style;
|
|
329
|
-
default:
|
|
330
|
-
return 'solid';
|
|
331
|
-
}
|
|
332
|
-
};
|
|
333
|
-
const getBorderSide = (style, side) => {
|
|
334
|
-
const width = toBorderWidth(style[`border${side}Width`]);
|
|
335
|
-
if (!width) {
|
|
336
|
-
return undefined;
|
|
337
|
-
}
|
|
338
|
-
return {
|
|
339
|
-
width,
|
|
340
|
-
style: toBorderStyle(style[`border${side}Style`]),
|
|
341
|
-
color: style[`border${side}Color`] || DEFAULT_BORDER_COLOR
|
|
342
|
-
};
|
|
343
|
-
};
|
|
344
|
-
const hasBorder = (style) => {
|
|
345
|
-
if (!style) {
|
|
346
|
-
return false;
|
|
347
|
-
}
|
|
348
|
-
return !!(style.borderTop || style.borderRight || style.borderBottom || style.borderLeft);
|
|
349
|
-
};
|
|
350
|
-
const hasTextLayout = (style) => {
|
|
351
|
-
if (!style) {
|
|
352
|
-
return false;
|
|
353
|
-
}
|
|
354
|
-
return !!(style.horizontalAlign || style.verticalAlign || style.wrapText || style.shrinkToFit);
|
|
355
|
-
};
|
|
356
|
-
const shouldRenderTextInOverlay = (style, column) => {
|
|
357
|
-
if (!hasTextLayout(style)) {
|
|
358
|
-
return false;
|
|
359
|
-
}
|
|
360
|
-
// e-virt-table 的列级 align 可以交给 canvas;只有单元格级布局差异才用 DOM 覆盖层补齐。
|
|
361
|
-
return !!((style === null || style === void 0 ? void 0 : style.wrapText) ||
|
|
362
|
-
(style === null || style === void 0 ? void 0 : style.shrinkToFit) ||
|
|
363
|
-
((style === null || style === void 0 ? void 0 : style.horizontalAlign) && style.horizontalAlign !== ((column === null || column === void 0 ? void 0 : column.align) || 'left')) ||
|
|
364
|
-
((style === null || style === void 0 ? void 0 : style.verticalAlign) && style.verticalAlign !== ((column === null || column === void 0 ? void 0 : column.verticalAlign) || 'middle')));
|
|
365
|
-
};
|
|
366
|
-
const toFlexJustify = (align) => {
|
|
367
|
-
switch (align) {
|
|
368
|
-
case 'center':
|
|
369
|
-
return 'center';
|
|
370
|
-
case 'right':
|
|
371
|
-
return 'flex-end';
|
|
372
|
-
default:
|
|
373
|
-
return 'flex-start';
|
|
374
|
-
}
|
|
375
|
-
};
|
|
376
|
-
const toFlexAlign = (verticalAlign) => {
|
|
377
|
-
switch (verticalAlign) {
|
|
378
|
-
case 'top':
|
|
379
|
-
return 'flex-start';
|
|
380
|
-
case 'bottom':
|
|
381
|
-
return 'flex-end';
|
|
382
|
-
default:
|
|
383
|
-
return 'center';
|
|
384
|
-
}
|
|
385
|
-
};
|
|
386
|
-
const toTextLayerLeft = (align, ownWidth, overflowWidth, leftRoom) => {
|
|
387
|
-
switch (align) {
|
|
388
|
-
case 'right':
|
|
389
|
-
return ownWidth - overflowWidth;
|
|
390
|
-
case 'center':
|
|
391
|
-
return -Math.min(leftRoom, Math.max((overflowWidth - ownWidth) / 2, 0));
|
|
392
|
-
default:
|
|
393
|
-
return 0;
|
|
394
|
-
}
|
|
395
|
-
};
|
|
396
|
-
const isHiddenVirtualRow = (row) => {
|
|
397
|
-
return typeof row._height === 'number' && row._height <= HIDDEN_ROW_HEIGHT;
|
|
398
|
-
};
|
|
399
|
-
const getDataColumnIndex = (column, fallbackColIndex) => {
|
|
400
|
-
const key = column === null || column === void 0 ? void 0 : column.key;
|
|
401
|
-
if (typeof key === 'string' && key.startsWith('c')) {
|
|
402
|
-
const index = Number(key.slice(1));
|
|
403
|
-
if (Number.isInteger(index) && index >= 0) {
|
|
404
|
-
return index;
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
return Math.max(fallbackColIndex - 1, 0);
|
|
408
|
-
};
|
|
409
|
-
const getCellCacheKey = (rowIndex, colIndex, column) => {
|
|
410
|
-
return displayCellKey(rowIndex, getDataColumnIndex(column, colIndex) + 1);
|
|
411
|
-
};
|
|
412
|
-
const getCellKeyByDataColumn = (rowIndex, dataColIndex) => {
|
|
413
|
-
return displayCellKey(rowIndex, dataColIndex + 1);
|
|
414
|
-
};
|
|
415
|
-
const getTextValue = (value) => {
|
|
416
|
-
if (value === null || value === undefined) {
|
|
417
|
-
return '';
|
|
418
|
-
}
|
|
419
|
-
return `${value}`;
|
|
420
|
-
};
|
|
421
|
-
const hasRenderableValue = (value) => {
|
|
422
|
-
return getTextValue(value).trim() !== '';
|
|
423
|
-
};
|
|
424
|
-
const isNumericLikeValue = (text) => {
|
|
425
|
-
return /^[+-]?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?%?$/.test(text.trim());
|
|
426
|
-
};
|
|
427
|
-
const measureTextWidth = (text, font, padding, documentRef) => {
|
|
428
|
-
const cacheKey = `${font}\n${padding}\n${text}`;
|
|
429
|
-
const cached = textWidthCache.get(cacheKey);
|
|
430
|
-
if (cached !== undefined) {
|
|
431
|
-
return cached;
|
|
432
|
-
}
|
|
433
|
-
if (!measureCanvas && documentRef) {
|
|
434
|
-
measureCanvas = documentRef.createElement('canvas');
|
|
435
|
-
}
|
|
436
|
-
const context = measureCanvas === null || measureCanvas === void 0 ? void 0 : measureCanvas.getContext('2d');
|
|
437
|
-
if (!context) {
|
|
438
|
-
return text.length * TABLE_FONT_SIZE;
|
|
439
|
-
}
|
|
440
|
-
context.font = font;
|
|
441
|
-
const width = context.measureText(text).width + padding * 2;
|
|
442
|
-
textWidthCache.set(cacheKey, width);
|
|
443
|
-
return width;
|
|
444
|
-
};
|
|
445
|
-
const isBlankOverflowTarget = (virtualState, row, rowIndex, dataColIndex) => {
|
|
446
|
-
const column = virtualState.columns[dataColIndex + 1];
|
|
447
|
-
if (!isVisibleDataColumn(column)) {
|
|
448
|
-
return false;
|
|
449
|
-
}
|
|
450
|
-
const cellKey = getCellKeyByDataColumn(rowIndex, dataColIndex);
|
|
451
|
-
if (virtualState.mergeStartMap.has(cellKey) || virtualState.mergeCoveredMap.has(cellKey)) {
|
|
452
|
-
return false;
|
|
453
|
-
}
|
|
454
|
-
return !hasRenderableValue(row[getDataKey(dataColIndex)]);
|
|
455
|
-
};
|
|
456
|
-
const collectOverflowRoom = (virtualState, row, rowIndex, dataColIndex, direction) => {
|
|
457
|
-
let room = 0;
|
|
458
|
-
for (let step = 1; step <= MAX_OVERFLOW_SCAN_COLS; step += 1) {
|
|
459
|
-
const nextColIndex = dataColIndex + step * direction;
|
|
460
|
-
if (nextColIndex < 0 || nextColIndex >= virtualState.totalCols) {
|
|
461
|
-
break;
|
|
462
|
-
}
|
|
463
|
-
if (!isBlankOverflowTarget(virtualState, row, rowIndex, nextColIndex)) {
|
|
464
|
-
break;
|
|
465
|
-
}
|
|
466
|
-
room += getRenderColumnWidth(virtualState.columns[nextColIndex + 1]);
|
|
467
|
-
}
|
|
468
|
-
return room;
|
|
469
|
-
};
|
|
470
|
-
const getExcelOverflowLayout = (virtualState, row, rowIndex, dataColIndex, column, style, value, zoomScale, documentRef) => {
|
|
471
|
-
const text = getTextValue(value);
|
|
472
|
-
if (!text || (style === null || style === void 0 ? void 0 : style.wrapText) || (style === null || style === void 0 ? void 0 : style.shrinkToFit) || isNumericLikeValue(text)) {
|
|
473
|
-
return undefined;
|
|
474
|
-
}
|
|
475
|
-
const cellKey = getCellKeyByDataColumn(rowIndex, dataColIndex);
|
|
476
|
-
if (virtualState.mergeStartMap.has(cellKey) || virtualState.mergeCoveredMap.has(cellKey)) {
|
|
477
|
-
return undefined;
|
|
478
|
-
}
|
|
479
|
-
const ownWidth = getRenderColumnWidth(column);
|
|
480
|
-
if (!ownWidth) {
|
|
481
|
-
return undefined;
|
|
482
|
-
}
|
|
483
|
-
const font = (style === null || style === void 0 ? void 0 : style.font) || BODY_FONT;
|
|
484
|
-
const measuredWidth = Math.ceil(measureTextWidth(text, font, scaleNumber(CELL_PADDING, zoomScale), documentRef));
|
|
485
|
-
if (measuredWidth <= ownWidth) {
|
|
486
|
-
return undefined;
|
|
487
|
-
}
|
|
488
|
-
const align = (style === null || style === void 0 ? void 0 : style.horizontalAlign) || (column === null || column === void 0 ? void 0 : column.align) || 'left';
|
|
489
|
-
const leftRoom = align === 'right' || align === 'center'
|
|
490
|
-
? collectOverflowRoom(virtualState, row, rowIndex, dataColIndex, -1)
|
|
491
|
-
: 0;
|
|
492
|
-
const rightRoom = align !== 'right'
|
|
493
|
-
? collectOverflowRoom(virtualState, row, rowIndex, dataColIndex, 1)
|
|
494
|
-
: 0;
|
|
495
|
-
const maxWidth = ownWidth + leftRoom + rightRoom;
|
|
496
|
-
if (maxWidth <= ownWidth) {
|
|
497
|
-
return undefined;
|
|
498
|
-
}
|
|
499
|
-
const width = Math.min(measuredWidth, maxWidth);
|
|
500
|
-
return {
|
|
501
|
-
left: toTextLayerLeft(align, ownWidth, width, leftRoom),
|
|
502
|
-
width
|
|
503
|
-
};
|
|
504
|
-
};
|
|
505
|
-
const getBorderScore = (border) => {
|
|
506
|
-
if (!border) {
|
|
507
|
-
return 0;
|
|
508
|
-
}
|
|
509
|
-
return border.width * 100 + (BORDER_STYLE_PRIORITY[border.style] || 1);
|
|
510
|
-
};
|
|
511
|
-
const getCollapsedBorderStyle = (virtualState, rowIndex, dataColIndex, style, zoomScale) => {
|
|
512
|
-
const previousRow = scaleCellStyle(virtualState.cellCache.get(displayCellKey(rowIndex - 1, dataColIndex + 1)), zoomScale);
|
|
513
|
-
const nextRow = scaleCellStyle(virtualState.cellCache.get(displayCellKey(rowIndex + 1, dataColIndex + 1)), zoomScale);
|
|
514
|
-
const previousCol = scaleCellStyle(virtualState.cellCache.get(displayCellKey(rowIndex, dataColIndex)), zoomScale);
|
|
515
|
-
const nextCol = scaleCellStyle(virtualState.cellCache.get(displayCellKey(rowIndex, dataColIndex + 2)), zoomScale);
|
|
516
|
-
const borderTop = getBorderScore(style.borderTop) >= getBorderScore(previousRow === null || previousRow === void 0 ? void 0 : previousRow.borderBottom)
|
|
517
|
-
? style.borderTop
|
|
518
|
-
: undefined;
|
|
519
|
-
const borderBottom = getBorderScore(style.borderBottom) > getBorderScore(nextRow === null || nextRow === void 0 ? void 0 : nextRow.borderTop)
|
|
520
|
-
? style.borderBottom
|
|
521
|
-
: undefined;
|
|
522
|
-
const borderLeft = getBorderScore(style.borderLeft) >= getBorderScore(previousCol === null || previousCol === void 0 ? void 0 : previousCol.borderRight)
|
|
523
|
-
? style.borderLeft
|
|
524
|
-
: undefined;
|
|
525
|
-
const borderRight = getBorderScore(style.borderRight) > getBorderScore(nextCol === null || nextCol === void 0 ? void 0 : nextCol.borderLeft)
|
|
526
|
-
? style.borderRight
|
|
527
|
-
: undefined;
|
|
528
|
-
return {
|
|
529
|
-
...style,
|
|
530
|
-
borderTop,
|
|
531
|
-
borderRight,
|
|
532
|
-
borderBottom,
|
|
533
|
-
borderLeft
|
|
534
|
-
};
|
|
535
|
-
};
|
|
536
|
-
const createBorderLine = (documentRef, side, border) => {
|
|
537
|
-
const line = documentRef.createElement('span');
|
|
538
|
-
const half = border.width / 2;
|
|
539
|
-
Object.assign(line.style, {
|
|
540
|
-
position: 'absolute',
|
|
541
|
-
pointerEvents: 'none',
|
|
542
|
-
boxSizing: 'border-box'
|
|
543
|
-
});
|
|
544
|
-
if (side === 'top' || side === 'bottom') {
|
|
545
|
-
Object.assign(line.style, {
|
|
546
|
-
left: `${-half}px`,
|
|
547
|
-
width: `calc(100% + ${border.width}px)`,
|
|
548
|
-
height: '0'
|
|
549
|
-
});
|
|
550
|
-
line.style[side] = `${-half}px`;
|
|
551
|
-
line.style.borderTop = `${border.width}px ${border.style} ${border.color}`;
|
|
552
|
-
}
|
|
553
|
-
else {
|
|
554
|
-
Object.assign(line.style, {
|
|
555
|
-
top: `${-half}px`,
|
|
556
|
-
height: `calc(100% + ${border.width}px)`,
|
|
557
|
-
width: '0'
|
|
558
|
-
});
|
|
559
|
-
line.style[side] = `${-half}px`;
|
|
560
|
-
line.style.borderLeft = `${border.width}px ${border.style} ${border.color}`;
|
|
561
|
-
}
|
|
562
|
-
return line;
|
|
563
|
-
};
|
|
564
|
-
const createTextLayer = (documentRef, value, style, padding) => {
|
|
565
|
-
const text = documentRef.createElement('span');
|
|
566
|
-
text.textContent = getTextValue(value);
|
|
567
|
-
Object.assign(text.style, {
|
|
568
|
-
position: 'relative',
|
|
569
|
-
zIndex: '1',
|
|
570
|
-
width: '100%',
|
|
571
|
-
height: '100%',
|
|
572
|
-
boxSizing: 'border-box',
|
|
573
|
-
display: 'flex',
|
|
574
|
-
alignItems: toFlexAlign(style.verticalAlign),
|
|
575
|
-
justifyContent: toFlexJustify(style.horizontalAlign),
|
|
576
|
-
padding: `0 ${padding}px`,
|
|
577
|
-
overflow: 'hidden',
|
|
578
|
-
textOverflow: style.wrapText ? 'clip' : 'ellipsis',
|
|
579
|
-
whiteSpace: style.wrapText ? 'pre-wrap' : 'nowrap',
|
|
580
|
-
wordBreak: style.wrapText ? 'break-word' : 'normal',
|
|
581
|
-
lineHeight: `${CELL_LINE_HEIGHT}`,
|
|
582
|
-
textAlign: style.horizontalAlign || 'left',
|
|
583
|
-
color: style.color || 'inherit',
|
|
584
|
-
font: style.font || BODY_FONT,
|
|
585
|
-
transform: style.shrinkToFit ? 'scale(0.92)' : 'none',
|
|
586
|
-
transformOrigin: `${style.horizontalAlign || 'left'} center`
|
|
587
|
-
});
|
|
588
|
-
return text;
|
|
589
|
-
};
|
|
590
|
-
const applyOverflowLayout = (text, overflowLayout) => {
|
|
591
|
-
if (!overflowLayout) {
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
594
|
-
Object.assign(text.style, {
|
|
595
|
-
position: 'absolute',
|
|
596
|
-
left: `${overflowLayout.left}px`,
|
|
597
|
-
top: '0',
|
|
598
|
-
width: `${overflowLayout.width}px`,
|
|
599
|
-
overflow: 'hidden',
|
|
600
|
-
textOverflow: 'clip'
|
|
601
|
-
});
|
|
602
|
-
};
|
|
603
|
-
// e-virt-table 的普通样式接口不支持 Excel 式四边边框和单元格级换行/垂直对齐,
|
|
604
|
-
// 这里借助官方的 BODY_CELL_RENDER_METHOD,只在可视区补轻量 DOM 覆盖层。
|
|
605
|
-
const renderCellOverlay = (cellEl, style, value, renderText, overflowLayout, zoomScale) => {
|
|
606
|
-
const documentRef = cellEl.ownerDocument;
|
|
607
|
-
cellEl.replaceChildren();
|
|
608
|
-
Object.assign(cellEl.style, {
|
|
609
|
-
pointerEvents: 'none',
|
|
610
|
-
overflow: 'visible',
|
|
611
|
-
background: 'transparent'
|
|
612
|
-
});
|
|
613
|
-
const fragment = documentRef.createDocumentFragment();
|
|
614
|
-
if (renderText) {
|
|
615
|
-
const text = createTextLayer(documentRef, value, style, scaleNumber(CELL_PADDING, zoomScale));
|
|
616
|
-
applyOverflowLayout(text, overflowLayout);
|
|
617
|
-
fragment.appendChild(text);
|
|
618
|
-
}
|
|
619
|
-
if (style.borderTop) {
|
|
620
|
-
fragment.appendChild(createBorderLine(documentRef, 'top', style.borderTop));
|
|
621
|
-
}
|
|
622
|
-
if (style.borderRight) {
|
|
623
|
-
fragment.appendChild(createBorderLine(documentRef, 'right', style.borderRight));
|
|
624
|
-
}
|
|
625
|
-
if (style.borderBottom) {
|
|
626
|
-
fragment.appendChild(createBorderLine(documentRef, 'bottom', style.borderBottom));
|
|
627
|
-
}
|
|
628
|
-
if (style.borderLeft) {
|
|
629
|
-
fragment.appendChild(createBorderLine(documentRef, 'left', style.borderLeft));
|
|
630
|
-
}
|
|
631
|
-
cellEl.appendChild(fragment);
|
|
632
|
-
};
|
|
633
|
-
export const normalizeCellStyle = (meta) => {
|
|
634
|
-
if (!meta) {
|
|
635
|
-
return undefined;
|
|
636
|
-
}
|
|
637
|
-
const style = meta.style || {};
|
|
638
|
-
const nextStyle = {};
|
|
639
|
-
if (style.backgroundColor) {
|
|
640
|
-
nextStyle.backgroundColor = style.backgroundColor;
|
|
641
|
-
}
|
|
642
|
-
if (style.color) {
|
|
643
|
-
nextStyle.color = style.color;
|
|
644
|
-
}
|
|
645
|
-
else if (style.backgroundColor && tinycolor(style.backgroundColor).isDark()) {
|
|
646
|
-
nextStyle.color = '#ffffff';
|
|
647
|
-
}
|
|
648
|
-
const font = buildFont(style);
|
|
649
|
-
if (font) {
|
|
650
|
-
nextStyle.font = font;
|
|
651
|
-
}
|
|
652
|
-
else if (style.backgroundColor && tinycolor(style.backgroundColor).isDark()) {
|
|
653
|
-
nextStyle.font = `bold ${TABLE_FONT_SIZE}px ${TABLE_FONT_FAMILY}`;
|
|
654
|
-
}
|
|
655
|
-
const borderTop = getBorderSide(style, 'Top');
|
|
656
|
-
if (borderTop) {
|
|
657
|
-
nextStyle.borderTop = borderTop;
|
|
658
|
-
}
|
|
659
|
-
const borderRight = getBorderSide(style, 'Right');
|
|
660
|
-
if (borderRight) {
|
|
661
|
-
nextStyle.borderRight = borderRight;
|
|
662
|
-
}
|
|
663
|
-
const borderBottom = getBorderSide(style, 'Bottom');
|
|
664
|
-
if (borderBottom) {
|
|
665
|
-
nextStyle.borderBottom = borderBottom;
|
|
666
|
-
}
|
|
667
|
-
const borderLeft = getBorderSide(style, 'Left');
|
|
668
|
-
if (borderLeft) {
|
|
669
|
-
nextStyle.borderLeft = borderLeft;
|
|
670
|
-
}
|
|
671
|
-
const horizontalAlign = alignFromClassName(meta.className);
|
|
672
|
-
if (horizontalAlign) {
|
|
673
|
-
nextStyle.horizontalAlign = horizontalAlign;
|
|
674
|
-
}
|
|
675
|
-
const verticalAlign = verticalAlignFromClassName(meta.className);
|
|
676
|
-
if (verticalAlign) {
|
|
677
|
-
nextStyle.verticalAlign = verticalAlign;
|
|
678
|
-
}
|
|
679
|
-
if (hasClassName(meta.className, 'htWrap')) {
|
|
680
|
-
nextStyle.wrapText = true;
|
|
681
|
-
}
|
|
682
|
-
if (hasClassName(meta.className, 'htShrink')) {
|
|
683
|
-
nextStyle.shrinkToFit = true;
|
|
684
|
-
}
|
|
685
|
-
if (!nextStyle.backgroundColor && !nextStyle.color && !nextStyle.font && !hasBorder(nextStyle) && !hasTextLayout(nextStyle)) {
|
|
686
|
-
return undefined;
|
|
687
|
-
}
|
|
688
|
-
return nextStyle;
|
|
689
|
-
};
|
|
690
|
-
export const createTableConfig = ({ hostHeight, sheetDefaults, virtualState, zoomScale = 1 }) => {
|
|
691
|
-
const normalizedScale = normalizeZoomScale(zoomScale);
|
|
692
|
-
const scaledPadding = scaleNumber(CELL_PADDING, normalizedScale);
|
|
693
|
-
const scaledHeaderHeight = scaleNumber(HEADER_HEIGHT, normalizedScale);
|
|
694
|
-
const scaledCellHeight = scaleNumber(normalizeRowHeight(sheetDefaults.rowHeight, sheetDefaults.rowHeight), normalizedScale);
|
|
695
|
-
const scaledCellWidth = scaleNumber(sheetDefaults.colWidth, normalizedScale);
|
|
696
|
-
const headerStyle = getIndexCellStyle(normalizedScale);
|
|
697
|
-
const loadingStyle = getLoadingCellStyle(normalizedScale);
|
|
698
|
-
const spanMethod = ({ rowIndex, colIndex, column }) => {
|
|
699
|
-
if (colIndex === 0) {
|
|
700
|
-
return;
|
|
701
|
-
}
|
|
702
|
-
const key = getCellCacheKey(rowIndex, colIndex, column);
|
|
703
|
-
if (virtualState.mergeCoveredMap.has(key)) {
|
|
704
|
-
return { rowspan: 0, colspan: 0 };
|
|
705
|
-
}
|
|
706
|
-
const merge = virtualState.mergeStartMap.get(key);
|
|
707
|
-
if (!merge) {
|
|
708
|
-
return;
|
|
709
|
-
}
|
|
710
|
-
return {
|
|
711
|
-
rowspan: merge.rowspan,
|
|
712
|
-
colspan: merge.colspan
|
|
713
|
-
};
|
|
714
|
-
};
|
|
715
|
-
const headerStyleMethod = () => headerStyle;
|
|
716
|
-
const styleMethod = ({ row, rowIndex, colIndex, column }) => {
|
|
717
|
-
if (colIndex === 0) {
|
|
718
|
-
return headerStyle;
|
|
719
|
-
}
|
|
720
|
-
const currentRow = row;
|
|
721
|
-
if (isHiddenVirtualRow(currentRow)) {
|
|
722
|
-
return undefined;
|
|
723
|
-
}
|
|
724
|
-
if (getRowState(currentRow) !== RowState.Loaded) {
|
|
725
|
-
return loadingStyle;
|
|
726
|
-
}
|
|
727
|
-
return scaleCellStyle(virtualState.cellCache.get(getCellCacheKey(rowIndex, colIndex, column)), normalizedScale);
|
|
728
|
-
};
|
|
729
|
-
const renderMethod = ({ row, rowIndex, colIndex, column, value }) => {
|
|
730
|
-
const currentRow = row;
|
|
731
|
-
if (colIndex === 0 || isHiddenVirtualRow(currentRow) || getRowState(currentRow) !== RowState.Loaded) {
|
|
732
|
-
return undefined;
|
|
733
|
-
}
|
|
734
|
-
const cellKey = getCellCacheKey(rowIndex, colIndex, column);
|
|
735
|
-
if (virtualState.mergeCoveredMap.has(cellKey)) {
|
|
736
|
-
return undefined;
|
|
737
|
-
}
|
|
738
|
-
const style = scaleCellStyle(virtualState.cellCache.get(cellKey), normalizedScale);
|
|
739
|
-
const dataColIndex = getDataColumnIndex(column, colIndex);
|
|
740
|
-
const overflowLayout = getExcelOverflowLayout(virtualState, currentRow, rowIndex, dataColIndex, column, style, value, normalizedScale);
|
|
741
|
-
const renderText = shouldRenderTextInOverlay(style, column) || !!overflowLayout;
|
|
742
|
-
if (!hasBorder(style) && !renderText) {
|
|
743
|
-
return undefined;
|
|
744
|
-
}
|
|
745
|
-
return ((cellEl) => {
|
|
746
|
-
const baseStyle = {
|
|
747
|
-
...(style || {}),
|
|
748
|
-
horizontalAlign: (style === null || style === void 0 ? void 0 : style.horizontalAlign) || (column === null || column === void 0 ? void 0 : column.align),
|
|
749
|
-
verticalAlign: (style === null || style === void 0 ? void 0 : style.verticalAlign) || (column === null || column === void 0 ? void 0 : column.verticalAlign)
|
|
750
|
-
};
|
|
751
|
-
const collapsedStyle = hasBorder(style)
|
|
752
|
-
? getCollapsedBorderStyle(virtualState, rowIndex, dataColIndex, baseStyle, normalizedScale)
|
|
753
|
-
: baseStyle;
|
|
754
|
-
renderCellOverlay(cellEl, collapsedStyle, value, renderText, overflowLayout, normalizedScale);
|
|
755
|
-
});
|
|
756
|
-
};
|
|
757
|
-
return {
|
|
758
|
-
ROW_KEY: ROW_KEY_FIELD,
|
|
759
|
-
DISABLED: true,
|
|
760
|
-
HEIGHT: Math.max(hostHeight, 240),
|
|
761
|
-
MAX_HEIGHT: Math.max(hostHeight, 240),
|
|
762
|
-
HEADER_HEIGHT: scaledHeaderHeight,
|
|
763
|
-
CELL_HEIGHT: scaledCellHeight,
|
|
764
|
-
CELL_WIDTH: scaledCellWidth,
|
|
765
|
-
CELL_PADDING: scaledPadding,
|
|
766
|
-
CELL_LINE_HEIGHT,
|
|
767
|
-
COLUMNS_VERTICAL_ALIGN: 'middle',
|
|
768
|
-
HEADER_FONT: getHeaderFont(normalizedScale),
|
|
769
|
-
BODY_FONT: getBodyFont(normalizedScale),
|
|
770
|
-
BORDER_RADIUS: 0,
|
|
771
|
-
BORDER_COLOR: EXCEL_GRID,
|
|
772
|
-
HEADER_BG_COLOR: EXCEL_HEADER_BG,
|
|
773
|
-
BODY_BG_COLOR: '#ffffff',
|
|
774
|
-
HEADER_TEXT_COLOR: EXCEL_HEADER_TEXT,
|
|
775
|
-
BODY_TEXT_COLOR: '#202124',
|
|
776
|
-
READONLY_COLOR: '#ffffff',
|
|
777
|
-
READONLY_TEXT_COLOR: '#202124',
|
|
778
|
-
EDIT_BG_COLOR: '#ffffff',
|
|
779
|
-
PLACEHOLDER_COLOR: '#8a94a3',
|
|
780
|
-
SCROLLER_COLOR: '#c1c7d0',
|
|
781
|
-
SCROLLER_FOCUS_COLOR: '#9aa0a6',
|
|
782
|
-
SELECT_ROW_COL_BG_COLOR: EXCEL_GREEN_SOFT,
|
|
783
|
-
SELECT_AREA_COLOR: 'rgba(33, 163, 102, 0.14)',
|
|
784
|
-
SELECT_BORDER_COLOR: EXCEL_GREEN,
|
|
785
|
-
AUTOFILL_POINT_BORDER_COLOR: EXCEL_GREEN,
|
|
786
|
-
ENABLE_SELECTOR: true,
|
|
787
|
-
ENABLE_SELECTOR_SINGLE: false,
|
|
788
|
-
ENABLE_SELECTOR_SPAN_COL: true,
|
|
789
|
-
ENABLE_SELECTOR_SPAN_ROW: true,
|
|
790
|
-
ENABLE_SELECTOR_ALL_ROWS: true,
|
|
791
|
-
ENABLE_SELECTOR_ALL_COLS: true,
|
|
792
|
-
SELECTOR_AREA_MIN_X: DATA_AREA_MIN_COL_INDEX,
|
|
793
|
-
ENABLE_CONTEXT_MENU: false,
|
|
794
|
-
ENABLE_HEADER_CONTEXT_MENU: false,
|
|
795
|
-
ENABLE_AUTOFILL: true,
|
|
796
|
-
ENABLE_AUTOFILL_SPAN_COL: true,
|
|
797
|
-
ENABLE_AUTOFILL_SPAN_ROW: true,
|
|
798
|
-
ENABLE_PASTER: false,
|
|
799
|
-
ENABLE_HISTORY: false,
|
|
800
|
-
ENABLE_RESIZE_COLUMN: false,
|
|
801
|
-
ENABLE_RESIZE_ROW: false,
|
|
802
|
-
ENABLE_KEYBOARD: true,
|
|
803
|
-
ENABLE_COPY: true,
|
|
804
|
-
// 预览态只开放“拖动扩选”的交互,不允许真正写回单元格内容。
|
|
805
|
-
BEFORE_AUTOFILL_DATA_METHOD: () => [],
|
|
806
|
-
SPAN_METHOD: spanMethod,
|
|
807
|
-
HEADER_CELL_STYLE_METHOD: headerStyleMethod,
|
|
808
|
-
BODY_CELL_STYLE_METHOD: styleMethod,
|
|
809
|
-
BODY_CELL_RENDER_METHOD: renderMethod,
|
|
810
|
-
BODY_CELL_FORMATTER_METHOD: ({ row, rowIndex, colIndex, column, value }) => {
|
|
811
|
-
if (isHiddenVirtualRow(row)) {
|
|
812
|
-
return '';
|
|
813
|
-
}
|
|
814
|
-
if (colIndex === 0) {
|
|
815
|
-
const displayIndex = rowIndex + 1 - virtualState.indexOffset;
|
|
816
|
-
return displayIndex > 0 ? `${displayIndex}` : '';
|
|
817
|
-
}
|
|
818
|
-
if (getRowState(row) !== RowState.Loaded) {
|
|
819
|
-
return '';
|
|
820
|
-
}
|
|
821
|
-
const currentRow = row;
|
|
822
|
-
const style = scaleCellStyle(virtualState.cellCache.get(getCellCacheKey(rowIndex, colIndex, column)), normalizedScale);
|
|
823
|
-
const overflowLayout = getExcelOverflowLayout(virtualState, currentRow, rowIndex, getDataColumnIndex(column, colIndex), column, style, value, normalizedScale);
|
|
824
|
-
if (shouldRenderTextInOverlay(style, column) || overflowLayout) {
|
|
825
|
-
return '';
|
|
826
|
-
}
|
|
827
|
-
if (value === null || value === undefined) {
|
|
828
|
-
return '';
|
|
829
|
-
}
|
|
830
|
-
return `${value}`;
|
|
831
|
-
}
|
|
832
|
-
};
|
|
833
|
-
};
|