@4399ywkf/editor 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -27
- package/dist/SheetView-YFK7BUS5.js +3 -0
- package/dist/{SheetView-SDBRSTVS.js.map → SheetView-YFK7BUS5.js.map} +1 -1
- package/dist/{chunk-KRP5V7VF.js → chunk-2DI4FJPC.js} +10 -3
- package/dist/chunk-2DI4FJPC.js.map +1 -0
- package/dist/{chunk-DGUNVCOM.js → chunk-3QTRZBIK.js} +111 -26
- package/dist/chunk-3QTRZBIK.js.map +1 -0
- package/dist/chunk-JWHQF2CZ.js +257 -0
- package/dist/chunk-JWHQF2CZ.js.map +1 -0
- package/dist/{chunk-WF7PIIFR.js → chunk-JZ67Q3QI.js} +4 -4
- package/dist/chunk-JZ67Q3QI.js.map +1 -0
- package/dist/{chunk-SBTKDJAL.js → chunk-SDVGDHC4.js} +45 -3
- package/dist/chunk-SDVGDHC4.js.map +1 -0
- package/dist/{chunk-HPSPOM2O.js → chunk-XB6FEC4I.js} +3 -3
- package/dist/chunk-XB6FEC4I.js.map +1 -0
- package/dist/{csv-parse-D0zTBvDB.d.ts → csv-parse-DXlwzoZ6.d.ts} +28 -1
- package/dist/csv.d.ts +2 -2
- package/dist/csv.js +4 -4
- package/dist/import-O7RUERND.js +6 -0
- package/dist/{import-GVZDLWA2.js.map → import-O7RUERND.js.map} +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/pdf.d.ts +1 -1
- package/dist/pptx.d.ts +1 -1
- package/dist/{registry-CYKivRDh.d.ts → registry-BQ5T1Yko.d.ts} +9 -16
- package/dist/sheet-runtime.d.ts +10 -8
- package/dist/sheet-runtime.js +6 -14
- package/dist/sheet-runtime.js.map +1 -1
- package/dist/sheet.d.ts +4 -3
- package/dist/sheet.js +1 -1
- package/dist/xlsx.d.ts +12 -11
- package/dist/xlsx.js +121 -32
- package/dist/xlsx.js.map +1 -1
- package/package.json +46 -2
- package/dist/SheetView-SDBRSTVS.js +0 -3
- package/dist/chunk-DGUNVCOM.js.map +0 -1
- package/dist/chunk-HPSPOM2O.js.map +0 -1
- package/dist/chunk-KRP5V7VF.js.map +0 -1
- package/dist/chunk-SBTKDJAL.js.map +0 -1
- package/dist/chunk-SYCK6Y5F.js +0 -89
- package/dist/chunk-SYCK6Y5F.js.map +0 -1
- package/dist/chunk-WF7PIIFR.js.map +0 -1
- package/dist/import-GVZDLWA2.js +0 -6
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { useRef, useEffect } from 'react';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
// src/views/SheetView.tsx
|
|
5
|
+
|
|
6
|
+
// src/sheet-features.ts
|
|
7
|
+
var SHEET_ENGINE_PACKAGES = [
|
|
8
|
+
"@univerjs/presets",
|
|
9
|
+
"@univerjs/preset-sheets-core",
|
|
10
|
+
"@univerjs/preset-sheets-filter",
|
|
11
|
+
"@univerjs/preset-sheets-sort",
|
|
12
|
+
"@univerjs/preset-sheets-data-validation",
|
|
13
|
+
"@univerjs/preset-sheets-conditional-formatting",
|
|
14
|
+
"@univerjs/preset-sheets-hyper-link",
|
|
15
|
+
"@univerjs/preset-sheets-note",
|
|
16
|
+
"@univerjs/preset-sheets-thread-comment",
|
|
17
|
+
"@univerjs/preset-sheets-table",
|
|
18
|
+
"@univerjs/preset-sheets-drawing",
|
|
19
|
+
"@univerjs/preset-sheets-find-replace"
|
|
20
|
+
];
|
|
21
|
+
function usePreset(mod, exportName) {
|
|
22
|
+
const factory = mod[exportName];
|
|
23
|
+
if (typeof factory !== "function") {
|
|
24
|
+
throw new Error(`Univer preset 缺少 ${exportName}`);
|
|
25
|
+
}
|
|
26
|
+
return factory();
|
|
27
|
+
}
|
|
28
|
+
function useLocale(mod) {
|
|
29
|
+
const locale = mod.default;
|
|
30
|
+
if (!locale || typeof locale !== "object") {
|
|
31
|
+
throw new Error("Univer locale 包没有 default 导出");
|
|
32
|
+
}
|
|
33
|
+
return locale;
|
|
34
|
+
}
|
|
35
|
+
async function loadBuiltinSheetPresets() {
|
|
36
|
+
const [
|
|
37
|
+
filter,
|
|
38
|
+
filterLocale,
|
|
39
|
+
sort,
|
|
40
|
+
sortLocale,
|
|
41
|
+
dataValidation,
|
|
42
|
+
dataValidationLocale,
|
|
43
|
+
conditionalFormatting,
|
|
44
|
+
conditionalFormattingLocale,
|
|
45
|
+
hyperLink,
|
|
46
|
+
hyperLinkLocale,
|
|
47
|
+
note,
|
|
48
|
+
noteLocale,
|
|
49
|
+
threadComment,
|
|
50
|
+
threadCommentLocale,
|
|
51
|
+
table,
|
|
52
|
+
tableLocale,
|
|
53
|
+
drawing,
|
|
54
|
+
drawingLocale
|
|
55
|
+
] = await Promise.all([
|
|
56
|
+
import('@univerjs/preset-sheets-filter'),
|
|
57
|
+
import('@univerjs/preset-sheets-filter/locales/zh-CN'),
|
|
58
|
+
import('@univerjs/preset-sheets-sort'),
|
|
59
|
+
import('@univerjs/preset-sheets-sort/locales/zh-CN'),
|
|
60
|
+
import('@univerjs/preset-sheets-data-validation'),
|
|
61
|
+
import('@univerjs/preset-sheets-data-validation/locales/zh-CN'),
|
|
62
|
+
import('@univerjs/preset-sheets-conditional-formatting'),
|
|
63
|
+
import('@univerjs/preset-sheets-conditional-formatting/locales/zh-CN'),
|
|
64
|
+
import('@univerjs/preset-sheets-hyper-link'),
|
|
65
|
+
import('@univerjs/preset-sheets-hyper-link/locales/zh-CN'),
|
|
66
|
+
import('@univerjs/preset-sheets-note'),
|
|
67
|
+
import('@univerjs/preset-sheets-note/locales/zh-CN'),
|
|
68
|
+
import('@univerjs/preset-sheets-thread-comment'),
|
|
69
|
+
import('@univerjs/preset-sheets-thread-comment/locales/zh-CN'),
|
|
70
|
+
import('@univerjs/preset-sheets-table'),
|
|
71
|
+
import('@univerjs/preset-sheets-table/locales/zh-CN'),
|
|
72
|
+
import('@univerjs/preset-sheets-drawing'),
|
|
73
|
+
import('@univerjs/preset-sheets-drawing/locales/zh-CN'),
|
|
74
|
+
import('@univerjs/preset-sheets-filter/lib/index.css'),
|
|
75
|
+
import('@univerjs/preset-sheets-sort/lib/index.css'),
|
|
76
|
+
import('@univerjs/preset-sheets-data-validation/lib/index.css'),
|
|
77
|
+
import('@univerjs/preset-sheets-conditional-formatting/lib/index.css'),
|
|
78
|
+
import('@univerjs/preset-sheets-hyper-link/lib/index.css'),
|
|
79
|
+
import('@univerjs/preset-sheets-note/lib/index.css'),
|
|
80
|
+
import('@univerjs/preset-sheets-thread-comment/lib/index.css'),
|
|
81
|
+
import('@univerjs/preset-sheets-table/lib/index.css'),
|
|
82
|
+
import('@univerjs/preset-sheets-drawing/lib/index.css')
|
|
83
|
+
]);
|
|
84
|
+
return {
|
|
85
|
+
presets: [
|
|
86
|
+
usePreset(filter, "UniverSheetsFilterPreset"),
|
|
87
|
+
usePreset(sort, "UniverSheetsSortPreset"),
|
|
88
|
+
usePreset(dataValidation, "UniverSheetsDataValidationPreset"),
|
|
89
|
+
usePreset(conditionalFormatting, "UniverSheetsConditionalFormattingPreset"),
|
|
90
|
+
usePreset(hyperLink, "UniverSheetsHyperLinkPreset"),
|
|
91
|
+
usePreset(note, "UniverSheetsNotePreset"),
|
|
92
|
+
usePreset(threadComment, "UniverSheetsThreadCommentPreset"),
|
|
93
|
+
usePreset(table, "UniverSheetsTablePreset"),
|
|
94
|
+
usePreset(drawing, "UniverSheetsDrawingPreset")
|
|
95
|
+
],
|
|
96
|
+
locales: [
|
|
97
|
+
useLocale(filterLocale),
|
|
98
|
+
useLocale(sortLocale),
|
|
99
|
+
useLocale(dataValidationLocale),
|
|
100
|
+
useLocale(conditionalFormattingLocale),
|
|
101
|
+
useLocale(hyperLinkLocale),
|
|
102
|
+
useLocale(noteLocale),
|
|
103
|
+
useLocale(threadCommentLocale),
|
|
104
|
+
useLocale(tableLocale),
|
|
105
|
+
useLocale(drawingLocale)
|
|
106
|
+
]
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function pluginCtor(entry) {
|
|
110
|
+
const ctor = Array.isArray(entry) ? entry[0] : entry;
|
|
111
|
+
return typeof ctor === "function" ? ctor : void 0;
|
|
112
|
+
}
|
|
113
|
+
function asPreset(value) {
|
|
114
|
+
if (Array.isArray(value) && value[0] && typeof value[0] === "object") return value[0];
|
|
115
|
+
return value;
|
|
116
|
+
}
|
|
117
|
+
function pluginsIn(preset) {
|
|
118
|
+
const body = asPreset(preset);
|
|
119
|
+
if (!body || typeof body !== "object" || !("plugins" in body)) return [];
|
|
120
|
+
const plugins = body.plugins;
|
|
121
|
+
return Array.isArray(plugins) ? plugins : [];
|
|
122
|
+
}
|
|
123
|
+
function pluginNamesOf(presets) {
|
|
124
|
+
const names = /* @__PURE__ */ new Set();
|
|
125
|
+
for (const preset of presets) {
|
|
126
|
+
for (const entry of pluginsIn(preset)) {
|
|
127
|
+
const name = pluginCtor(entry)?.pluginName;
|
|
128
|
+
if (name) names.add(name);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return names;
|
|
132
|
+
}
|
|
133
|
+
function omitPluginsNamed(presets, taken) {
|
|
134
|
+
if (taken.size === 0) return [...presets];
|
|
135
|
+
const out = [];
|
|
136
|
+
for (const preset of presets) {
|
|
137
|
+
const plugins = pluginsIn(preset);
|
|
138
|
+
if (plugins.length === 0) {
|
|
139
|
+
out.push(preset);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const kept = plugins.filter((entry) => {
|
|
143
|
+
const name = pluginCtor(entry)?.pluginName;
|
|
144
|
+
return !name || !taken.has(name);
|
|
145
|
+
});
|
|
146
|
+
if (kept.length === 0) continue;
|
|
147
|
+
if (kept.length === plugins.length) {
|
|
148
|
+
out.push(preset);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
out.push({ ...asPreset(preset), plugins: kept });
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
155
|
+
function SheetView({
|
|
156
|
+
source,
|
|
157
|
+
content,
|
|
158
|
+
readOnly,
|
|
159
|
+
className,
|
|
160
|
+
sheet,
|
|
161
|
+
onReady,
|
|
162
|
+
onError,
|
|
163
|
+
onWarnings
|
|
164
|
+
}) {
|
|
165
|
+
const hostRef = useRef(null);
|
|
166
|
+
const disposeRef = useRef(null);
|
|
167
|
+
const latest = useRef({ sheet, onReady, onError, onWarnings });
|
|
168
|
+
useEffect(() => {
|
|
169
|
+
latest.current = { sheet, onReady, onError, onWarnings };
|
|
170
|
+
});
|
|
171
|
+
useEffect(() => {
|
|
172
|
+
let cancelled = false;
|
|
173
|
+
const host = hostRef.current;
|
|
174
|
+
if (!host) return;
|
|
175
|
+
(async () => {
|
|
176
|
+
const { sheet: opts, onReady: ready, onError: fail, onWarnings: warn } = latest.current;
|
|
177
|
+
try {
|
|
178
|
+
const importPromise = !content && source ? import('./import-O7RUERND.js').then((m) => m.importSheetSource(source)) : null;
|
|
179
|
+
const [{ createUniver, LocaleType, merge }, sheetsCore, zhCN] = await Promise.all([
|
|
180
|
+
import('@univerjs/presets'),
|
|
181
|
+
import('@univerjs/preset-sheets-core'),
|
|
182
|
+
import('@univerjs/preset-sheets-core/locales/zh-CN'),
|
|
183
|
+
import('@univerjs/preset-sheets-core/lib/index.css')
|
|
184
|
+
]);
|
|
185
|
+
if (cancelled) return;
|
|
186
|
+
const { statusBarStatistic, footer, ...ui } = {
|
|
187
|
+
...readOnly ? { toolbar: false } : null,
|
|
188
|
+
...opts?.ui
|
|
189
|
+
};
|
|
190
|
+
const presets = [
|
|
191
|
+
sheetsCore.UniverSheetsCorePreset({
|
|
192
|
+
container: host,
|
|
193
|
+
...ui,
|
|
194
|
+
// 统计栏开关挂在 footer 底下;footer: false 是连底栏一起不要
|
|
195
|
+
footer: footer === false ? false : { statisticBar: statusBarStatistic !== false }
|
|
196
|
+
})
|
|
197
|
+
];
|
|
198
|
+
const locales = [zhCN.default];
|
|
199
|
+
const builtin = await loadBuiltinSheetPresets();
|
|
200
|
+
if (cancelled) return;
|
|
201
|
+
const hostPresets = opts?.presets ?? [];
|
|
202
|
+
presets.push(...omitPluginsNamed(builtin.presets, pluginNamesOf(hostPresets)));
|
|
203
|
+
locales.push(...builtin.locales);
|
|
204
|
+
if (opts?.findReplace) {
|
|
205
|
+
const [findReplace, findReplaceZhCN] = await Promise.all([
|
|
206
|
+
import('@univerjs/preset-sheets-find-replace'),
|
|
207
|
+
import('@univerjs/preset-sheets-find-replace/locales/zh-CN'),
|
|
208
|
+
import('@univerjs/preset-sheets-find-replace/lib/index.css')
|
|
209
|
+
]);
|
|
210
|
+
if (cancelled) return;
|
|
211
|
+
presets.push(
|
|
212
|
+
findReplace.UniverSheetsFindReplacePreset()
|
|
213
|
+
);
|
|
214
|
+
locales.push(findReplaceZhCN.default);
|
|
215
|
+
}
|
|
216
|
+
if (hostPresets.length) presets.push(...hostPresets);
|
|
217
|
+
if (opts?.locales?.length) locales.push(...opts.locales);
|
|
218
|
+
const imported = importPromise ? await importPromise : null;
|
|
219
|
+
if (cancelled) return;
|
|
220
|
+
const { univerAPI, univer } = createUniver({
|
|
221
|
+
locale: LocaleType.ZH_CN,
|
|
222
|
+
// createUniver 不会自动收集 preset 自带的 locales,得在这里一起合进来,
|
|
223
|
+
// 否则新加的 preset 菜单会显示成原始 i18n key
|
|
224
|
+
locales: { [LocaleType.ZH_CN]: merge({}, ...locales) },
|
|
225
|
+
presets
|
|
226
|
+
});
|
|
227
|
+
const dispose = () => univer.dispose();
|
|
228
|
+
if (cancelled) return dispose();
|
|
229
|
+
const book = univerAPI.createWorkbook(content ?? imported?.workbook ?? {});
|
|
230
|
+
if (readOnly) {
|
|
231
|
+
await book.getWorkbookPermission().setPoint(univerAPI.Enum.WorkbookPermissionPoint.Edit, false);
|
|
232
|
+
if (cancelled) return dispose();
|
|
233
|
+
}
|
|
234
|
+
if (imported?.warnings.length) warn?.(imported.warnings);
|
|
235
|
+
disposeRef.current = dispose;
|
|
236
|
+
ready?.(univerAPI);
|
|
237
|
+
} catch (e) {
|
|
238
|
+
const err = e instanceof Error ? e : new Error(String(e));
|
|
239
|
+
fail?.(
|
|
240
|
+
new Error(
|
|
241
|
+
`表格加载失败:${err.message}。若是引擎缺失,请确认已安装同一版本的可选依赖 ${SHEET_ENGINE_PACKAGES.join("、")}`
|
|
242
|
+
)
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
})();
|
|
246
|
+
return () => {
|
|
247
|
+
cancelled = true;
|
|
248
|
+
disposeRef.current?.();
|
|
249
|
+
disposeRef.current = null;
|
|
250
|
+
};
|
|
251
|
+
}, [source, content, readOnly]);
|
|
252
|
+
return /* @__PURE__ */ jsx("div", { ref: hostRef, className, style: { width: "100%", height: "100%" } });
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export { SheetView };
|
|
256
|
+
//# sourceMappingURL=chunk-JWHQF2CZ.js.map
|
|
257
|
+
//# sourceMappingURL=chunk-JWHQF2CZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/sheet-features.ts","../src/views/SheetView.tsx"],"names":[],"mappings":"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","file":"chunk-JWHQF2CZ.js","sourcesContent":["/**\n * 表格通道默认带上的开源能力。\n *\n * 每条 import 都必须是字面量:宿主的打包器在构建期就要解析到这些包,\n * 用变量拼路径解析不到,构建直接失败。所以「没装也能跳过」做不到。\n */\n\n/** 打开表格就得装齐、并且版本一致的包。查找替换没开也会被打包器解析到 */\nexport const SHEET_ENGINE_PACKAGES = [\n \"@univerjs/presets\",\n \"@univerjs/preset-sheets-core\",\n \"@univerjs/preset-sheets-filter\",\n \"@univerjs/preset-sheets-sort\",\n \"@univerjs/preset-sheets-data-validation\",\n \"@univerjs/preset-sheets-conditional-formatting\",\n \"@univerjs/preset-sheets-hyper-link\",\n \"@univerjs/preset-sheets-note\",\n \"@univerjs/preset-sheets-thread-comment\",\n \"@univerjs/preset-sheets-table\",\n \"@univerjs/preset-sheets-drawing\",\n \"@univerjs/preset-sheets-find-replace\",\n] as const\n\ntype PresetFactoryModule = Record<string, (config?: object) => unknown>\ntype LocaleModule = { default: object }\n\nfunction usePreset(mod: unknown, exportName: string): unknown {\n const factory = (mod as PresetFactoryModule)[exportName]\n if (typeof factory !== \"function\") {\n throw new Error(`Univer preset 缺少 ${exportName}`)\n }\n return factory()\n}\n\nfunction useLocale(mod: unknown): object {\n const locale = (mod as LocaleModule).default\n if (!locale || typeof locale !== \"object\") {\n throw new Error(\"Univer locale 包没有 default 导出\")\n }\n return locale\n}\n\n/** 筛选、排序、数据校验、条件格式、超链接、批注、评论、表格、浮动图片。查找替换另走开关 */\nexport async function loadBuiltinSheetPresets(): Promise<{\n presets: unknown[]\n locales: object[]\n}> {\n const [\n filter,\n filterLocale,\n sort,\n sortLocale,\n dataValidation,\n dataValidationLocale,\n conditionalFormatting,\n conditionalFormattingLocale,\n hyperLink,\n hyperLinkLocale,\n note,\n noteLocale,\n threadComment,\n threadCommentLocale,\n table,\n tableLocale,\n drawing,\n drawingLocale,\n ] = await Promise.all([\n import(\"@univerjs/preset-sheets-filter\"),\n import(\"@univerjs/preset-sheets-filter/locales/zh-CN\"),\n import(\"@univerjs/preset-sheets-sort\"),\n import(\"@univerjs/preset-sheets-sort/locales/zh-CN\"),\n import(\"@univerjs/preset-sheets-data-validation\"),\n import(\"@univerjs/preset-sheets-data-validation/locales/zh-CN\"),\n import(\"@univerjs/preset-sheets-conditional-formatting\"),\n import(\"@univerjs/preset-sheets-conditional-formatting/locales/zh-CN\"),\n import(\"@univerjs/preset-sheets-hyper-link\"),\n import(\"@univerjs/preset-sheets-hyper-link/locales/zh-CN\"),\n import(\"@univerjs/preset-sheets-note\"),\n import(\"@univerjs/preset-sheets-note/locales/zh-CN\"),\n import(\"@univerjs/preset-sheets-thread-comment\"),\n import(\"@univerjs/preset-sheets-thread-comment/locales/zh-CN\"),\n import(\"@univerjs/preset-sheets-table\"),\n import(\"@univerjs/preset-sheets-table/locales/zh-CN\"),\n import(\"@univerjs/preset-sheets-drawing\"),\n import(\"@univerjs/preset-sheets-drawing/locales/zh-CN\"),\n import(\"@univerjs/preset-sheets-filter/lib/index.css\"),\n import(\"@univerjs/preset-sheets-sort/lib/index.css\"),\n import(\"@univerjs/preset-sheets-data-validation/lib/index.css\"),\n import(\"@univerjs/preset-sheets-conditional-formatting/lib/index.css\"),\n import(\"@univerjs/preset-sheets-hyper-link/lib/index.css\"),\n import(\"@univerjs/preset-sheets-note/lib/index.css\"),\n import(\"@univerjs/preset-sheets-thread-comment/lib/index.css\"),\n import(\"@univerjs/preset-sheets-table/lib/index.css\"),\n import(\"@univerjs/preset-sheets-drawing/lib/index.css\"),\n ])\n\n return {\n presets: [\n usePreset(filter, \"UniverSheetsFilterPreset\"),\n usePreset(sort, \"UniverSheetsSortPreset\"),\n usePreset(dataValidation, \"UniverSheetsDataValidationPreset\"),\n usePreset(conditionalFormatting, \"UniverSheetsConditionalFormattingPreset\"),\n usePreset(hyperLink, \"UniverSheetsHyperLinkPreset\"),\n usePreset(note, \"UniverSheetsNotePreset\"),\n usePreset(threadComment, \"UniverSheetsThreadCommentPreset\"),\n usePreset(table, \"UniverSheetsTablePreset\"),\n usePreset(drawing, \"UniverSheetsDrawingPreset\"),\n ],\n locales: [\n useLocale(filterLocale),\n useLocale(sortLocale),\n useLocale(dataValidationLocale),\n useLocale(conditionalFormattingLocale),\n useLocale(hyperLinkLocale),\n useLocale(noteLocale),\n useLocale(threadCommentLocale),\n useLocale(tableLocale),\n useLocale(drawingLocale),\n ],\n }\n}\n\nfunction pluginCtor(entry: unknown): { pluginName?: string } | undefined {\n const ctor = Array.isArray(entry) ? entry[0] : entry\n return typeof ctor === \"function\" ? (ctor as { pluginName?: string }) : undefined\n}\n\n/** `[preset, options]` 这种元组剥掉配置,剩下的就是 preset 本体 */\nfunction asPreset(value: unknown): unknown {\n if (Array.isArray(value) && value[0] && typeof value[0] === \"object\") return value[0]\n return value\n}\n\nfunction pluginsIn(preset: unknown): unknown[] {\n const body = asPreset(preset)\n if (!body || typeof body !== \"object\" || !(\"plugins\" in body)) return []\n const plugins = (body as { plugins?: unknown }).plugins\n return Array.isArray(plugins) ? plugins : []\n}\n\n/** 宿主自己传进来的 preset 里已经有哪些插件 */\nexport function pluginNamesOf(presets: readonly unknown[]): Set<string> {\n const names = new Set<string>()\n for (const preset of presets) {\n for (const entry of pluginsIn(preset)) {\n const name = pluginCtor(entry)?.pluginName\n if (name) names.add(name)\n }\n }\n return names\n}\n\n/**\n * 去掉已经被宿主 preset 注册的插件。\n * Univer 对同名插件直接抛错,而 README 里曾经让宿主自己传筛选 preset。\n */\nexport function omitPluginsNamed(\n presets: readonly unknown[],\n taken: ReadonlySet<string>,\n): unknown[] {\n if (taken.size === 0) return [...presets]\n const out: unknown[] = []\n for (const preset of presets) {\n const plugins = pluginsIn(preset)\n if (plugins.length === 0) {\n out.push(preset)\n continue\n }\n const kept = plugins.filter((entry) => {\n const name = pluginCtor(entry)?.pluginName\n return !name || !taken.has(name)\n })\n if (kept.length === 0) continue\n if (kept.length === plugins.length) {\n out.push(preset)\n continue\n }\n out.push({ ...(asPreset(preset) as object), plugins: kept })\n }\n return out\n}\n","import { useEffect, useRef } from \"react\"\nimport type { DocumentViewProps } from \"../registry\"\nimport {\n loadBuiltinSheetPresets,\n omitPluginsNamed,\n pluginNamesOf,\n SHEET_ENGINE_PACKAGES,\n} from \"../sheet-features\"\nimport type { SheetUiOptions } from \"../sheet-options\"\n\n/**\n * sheet 通道:Univer 适配。\n *\n * 只用 Apache-2.0 的 OSS 核心。**不碰** `@univerjs-pro/*` 与 `univer-cli`:\n * 前者要自建 Univer Server 且需商业授权,后者 63MB、license 字段为 None、\n * 90/91 个 JS 被混淆、还会向 univer.ai 上报遥测 —— 不能进生产链路。\n *\n * 导入导出都在本包 `./xlsx`:导出直接读 Univer 快照拼 OOXML,导入把\n * xlsx/csv/tsv 解析成快照(`source` prop 走的就是这条路,File / Blob / URL\n * 都收)。两个方向都不引 SheetJS,文档不出内网。导入丢了什么(图片、\n * 条件格式等独立部件)通过 `onWarnings` 如实报告。\n *\n * 配置见 `SheetOptions`:UI 开关直接透传给 preset(Univer 的 class 是\n * `univer-` 前缀的原子类,没有稳定选择器,CSS 硬藏靠不住)。\n * 筛选、排序、数据校验、条件格式、超链接、批注、评论、表格和浮动图片随引擎一起加载。\n */\nexport default function SheetView({\n source,\n content,\n readOnly,\n className,\n sheet,\n onReady,\n onError,\n onWarnings,\n}: DocumentViewProps) {\n const hostRef = useRef<HTMLDivElement>(null)\n const disposeRef = useRef<(() => void) | null>(null)\n\n // 这几项都是「创建时读一次」的,且宿主多半传内联字面量/箭头函数。\n // 放进依赖数组 = 父组件每渲染一次就重建一次引擎(重下 871KB + 丢选区滚动位置),\n // 所以走 ref:取最新值,但不参与依赖比较。\n const latest = useRef({ sheet, onReady, onError, onWarnings })\n useEffect(() => {\n latest.current = { sheet, onReady, onError, onWarnings }\n })\n\n useEffect(() => {\n let cancelled = false\n const host = hostRef.current\n if (!host) return\n\n ;(async () => {\n const { sheet: opts, onReady: ready, onError: fail, onWarnings: warn } = latest.current\n try {\n // source 的解析和 871KB 引擎的下载并行:两边都是网络/CPU 大头,串行纯浪费。\n // content 优先于 source —— 已有快照就没有「导入」这回事\n const importPromise =\n !content && source\n ? import(\"../xlsx/import\").then((m) => m.importSheetSource(source))\n : null\n\n // 动态 import:871KB gzip 的引擎只在真的打开表格时才下载\n const [{ createUniver, LocaleType, merge }, sheetsCore, zhCN] = await Promise.all([\n import(\"@univerjs/presets\"),\n import(\"@univerjs/preset-sheets-core\"),\n import(\"@univerjs/preset-sheets-core/locales/zh-CN\"),\n import(\"@univerjs/preset-sheets-core/lib/index.css\"),\n ])\n if (cancelled) return\n\n // 只读时默认摘掉工具栏:整条 ribbon 全是死按钮,窄面板里还挤。\n // 宿主显式传了 toolbar 就以宿主为准。\n const { statusBarStatistic, footer, ...ui }: SheetUiOptions = {\n ...(readOnly ? { toolbar: false } : null),\n ...opts?.ui,\n }\n\n // 可选 peer:Univer 的包未安装时这里的类型解析不到,\n // 统一用 never 过桥,运行时由外层 try/catch 兜底并给出可读提示\n const presets: unknown[] = [\n (\n sheetsCore as unknown as { UniverSheetsCorePreset: (o: object) => never }\n ).UniverSheetsCorePreset({\n container: host,\n ...ui,\n // 统计栏开关挂在 footer 底下;footer: false 是连底栏一起不要\n footer: footer === false ? false : { statisticBar: statusBarStatistic !== false },\n }),\n ]\n const locales: unknown[] = [(zhCN as unknown as { default: object }).default]\n\n const builtin = await loadBuiltinSheetPresets()\n if (cancelled) return\n // 宿主若仍按旧文档自己传了筛选等 preset,同名插件用宿主那份,避免重复注册直接抛错\n const hostPresets = opts?.presets ?? []\n presets.push(...omitPluginsNamed(builtin.presets, pluginNamesOf(hostPresets)))\n locales.push(...builtin.locales)\n\n if (opts?.findReplace) {\n // 没开就完全不下载\n const [findReplace, findReplaceZhCN] = await Promise.all([\n import(\"@univerjs/preset-sheets-find-replace\"),\n import(\"@univerjs/preset-sheets-find-replace/locales/zh-CN\"),\n import(\"@univerjs/preset-sheets-find-replace/lib/index.css\"),\n ])\n if (cancelled) return\n presets.push(\n (\n findReplace as unknown as { UniverSheetsFindReplacePreset: () => never }\n ).UniverSheetsFindReplacePreset(),\n )\n locales.push((findReplaceZhCN as unknown as { default: object }).default)\n }\n\n if (hostPresets.length) presets.push(...hostPresets)\n if (opts?.locales?.length) locales.push(...opts.locales)\n\n // 导入失败不该等引擎起完才报:在创建引擎前结算,抛给外层统一 fail\n const imported = importPromise ? await importPromise : null\n if (cancelled) return\n\n const { univerAPI, univer } = createUniver({\n locale: LocaleType.ZH_CN,\n // createUniver 不会自动收集 preset 自带的 locales,得在这里一起合进来,\n // 否则新加的 preset 菜单会显示成原始 i18n key\n locales: { [LocaleType.ZH_CN]: merge({}, ...(locales as object[])) },\n presets: presets as never,\n })\n\n const dispose = () => (univer as unknown as { dispose: () => void }).dispose()\n // 卸载可能发生在上面任一个 await 期间:那时 cleanup 拿到的 disposeRef 还是 null,\n // 不在这儿自己收掉,引擎就挂在一个已脱离文档的 host 上泄漏了\n if (cancelled) return dispose()\n\n const book = univerAPI.createWorkbook((content ?? imported?.workbook ?? {}) as never)\n if (readOnly) {\n // 首个工作簿建好后 Univer 会异步按授权结果重置全部权限点:FWorkbook.setEditable(false)\n // 同步改的值会被冲回 true,得走权限点接口才排在重置之后。只关编辑点,复制仍可用\n await book\n .getWorkbookPermission()\n .setPoint(univerAPI.Enum.WorkbookPermissionPoint.Edit, false)\n if (cancelled) return dispose()\n }\n if (imported?.warnings.length) warn?.(imported.warnings)\n\n disposeRef.current = dispose\n ready?.(univerAPI)\n } catch (e) {\n const err = e instanceof Error ? e : new Error(String(e))\n fail?.(\n new Error(\n `表格加载失败:${err.message}。` +\n `若是引擎缺失,请确认已安装同一版本的可选依赖 ${SHEET_ENGINE_PACKAGES.join(\"、\")}`,\n ),\n )\n }\n })()\n\n return () => {\n cancelled = true\n disposeRef.current?.()\n disposeRef.current = null\n }\n }, [source, content, readOnly])\n\n return <div ref={hostRef} className={className} style={{ width: \"100%\", height: \"100%\" }} />\n}\n"]}
|
|
@@ -3,9 +3,9 @@ function snapshotFromUniver(univerAPI) {
|
|
|
3
3
|
const api = univerAPI;
|
|
4
4
|
const book = api?.getActiveWorkbook?.();
|
|
5
5
|
if (!book) throw new Error("拿不到当前工作簿:univerAPI 无效,或表格尚未就绪");
|
|
6
|
-
const snapshot = book.
|
|
6
|
+
const snapshot = book.save?.();
|
|
7
7
|
if (!snapshot || typeof snapshot !== "object") {
|
|
8
|
-
throw new Error("当前 Univer 版本没有
|
|
8
|
+
throw new Error("当前 Univer 版本没有 save(),无法取快照");
|
|
9
9
|
}
|
|
10
10
|
return snapshot;
|
|
11
11
|
}
|
|
@@ -17,5 +17,5 @@ function toSnapshot(source) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export { snapshotFromUniver, toSnapshot };
|
|
20
|
-
//# sourceMappingURL=chunk-
|
|
21
|
-
//# sourceMappingURL=chunk-
|
|
20
|
+
//# sourceMappingURL=chunk-JZ67Q3QI.js.map
|
|
21
|
+
//# sourceMappingURL=chunk-JZ67Q3QI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/xlsx/snapshot.ts"],"names":[],"mappings":";AAQO,SAAS,mBAAmB,SAAA,EAAkC;AACnE,EAAA,MAAM,GAAA,GAAM,SAAA;AACZ,EAAA,MAAM,IAAA,GAAO,KAAK,iBAAA,IAAoB;AACtC,EAAA,IAAI,CAAC,IAAA,EAAM,MAAM,IAAI,MAAM,+BAA+B,CAAA;AAC1D,EAAA,MAAM,QAAA,GAAW,KAAK,IAAA,IAAO;AAC7B,EAAA,IAAI,CAAC,QAAA,IAAY,OAAO,QAAA,KAAa,QAAA,EAAU;AAC7C,IAAA,MAAM,IAAI,MAAM,6BAA6B,CAAA;AAAA,EAC/C;AACA,EAAA,OAAO,QAAA;AACT;AAGO,SAAS,WAAW,MAAA,EAA8C;AACvE,EAAA,MAAM,KAAA,GAAQ,MAAA;AACd,EAAA,IAAI,SAAS,OAAO,KAAA,KAAU,QAAA,KAAa,QAAA,IAAY,SAAS,YAAA,IAAgB,KAAA,CAAA;AAC9E,IAAA,OAAO,KAAA;AACT,EAAA,OAAO,mBAAmB,MAAM,CAAA;AAClC","file":"chunk-JZ67Q3QI.js","sourcesContent":["/** 从 Univer 实例取快照。xlsx 与 csv 两条导出路径共用。 */\n\nimport type { WorkbookData } from \"./types.ts\"\n\n/**\n * 参数类型是 `unknown` 而不是 `FUniver`:`@univerjs/presets` 是可选 peer,\n * 写成具体类型会让没装它的项目 typecheck 直接红。\n */\nexport function snapshotFromUniver(univerAPI: unknown): WorkbookData {\n const api = univerAPI as { getActiveWorkbook?: () => { save?: () => unknown } | null } | null\n const book = api?.getActiveWorkbook?.()\n if (!book) throw new Error(\"拿不到当前工作簿:univerAPI 无效,或表格尚未就绪\")\n const snapshot = book.save?.()\n if (!snapshot || typeof snapshot !== \"object\") {\n throw new Error(\"当前 Univer 版本没有 save(),无法取快照\")\n }\n return snapshot as WorkbookData\n}\n\n/** 快照或 Univer 实例都收 —— 调用方不必自己判断手里是什么 */\nexport function toSnapshot(source: WorkbookData | unknown): WorkbookData {\n const maybe = source as WorkbookData\n if (maybe && typeof maybe === \"object\" && (\"sheets\" in maybe || \"sheetOrder\" in maybe))\n return maybe\n return snapshotFromUniver(source)\n}\n"]}
|
|
@@ -1,3 +1,45 @@
|
|
|
1
|
+
// src/xlsx/media.ts
|
|
2
|
+
var IMAGE_MIME = {
|
|
3
|
+
png: "image/png",
|
|
4
|
+
jpeg: "image/jpeg",
|
|
5
|
+
jpg: "image/jpeg",
|
|
6
|
+
gif: "image/gif",
|
|
7
|
+
bmp: "image/bmp"
|
|
8
|
+
};
|
|
9
|
+
function imageMimeOf(path) {
|
|
10
|
+
const ext = path.split(".").pop()?.toLowerCase();
|
|
11
|
+
return ext ? IMAGE_MIME[ext] : void 0;
|
|
12
|
+
}
|
|
13
|
+
function bytesToBase64(bytes) {
|
|
14
|
+
const B = globalThis.Buffer;
|
|
15
|
+
if (B) return B.from(bytes).toString("base64");
|
|
16
|
+
let bin = "";
|
|
17
|
+
const CHUNK = 32768;
|
|
18
|
+
for (let i = 0; i < bytes.length; i += CHUNK) {
|
|
19
|
+
bin += String.fromCharCode(...bytes.subarray(i, i + CHUNK));
|
|
20
|
+
}
|
|
21
|
+
return btoa(bin);
|
|
22
|
+
}
|
|
23
|
+
function bytesToDataUrl(bytes, mime) {
|
|
24
|
+
return `data:${mime};base64,${bytesToBase64(bytes)}`;
|
|
25
|
+
}
|
|
26
|
+
function dataUrlToImage(url) {
|
|
27
|
+
const match = /^data:([\w.+-]+\/[\w.+-]+);base64,([\s\S]*)$/.exec(url.trim());
|
|
28
|
+
if (!match) return void 0;
|
|
29
|
+
const mime = match[1].toLowerCase();
|
|
30
|
+
const ext = Object.keys(IMAGE_MIME).find((key) => IMAGE_MIME[key] === mime);
|
|
31
|
+
if (!ext) return void 0;
|
|
32
|
+
let bin;
|
|
33
|
+
try {
|
|
34
|
+
bin = atob(match[2].replace(/\s+/g, ""));
|
|
35
|
+
} catch {
|
|
36
|
+
return void 0;
|
|
37
|
+
}
|
|
38
|
+
const bytes = new Uint8Array(bin.length);
|
|
39
|
+
for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);
|
|
40
|
+
return { bytes, ext };
|
|
41
|
+
}
|
|
42
|
+
|
|
1
43
|
// src/xlsx/xml.ts
|
|
2
44
|
var CONTROL = /[\u0000-\u0008\u000B\u000C\u000E-\u001F\uFFFE\uFFFF]/g;
|
|
3
45
|
var LONE_SURROGATE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g;
|
|
@@ -102,6 +144,6 @@ function pointsToPx(pt) {
|
|
|
102
144
|
}
|
|
103
145
|
var XML_DECL = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n';
|
|
104
146
|
|
|
105
|
-
export { XML_DECL, argbToCss, cellRef, columnName, columnWidthToPx, escapeAttr, escapeXml, parseCellRef, parseRange, pointsToPx, pxToColumnWidth, pxToPoints, toArgb };
|
|
106
|
-
//# sourceMappingURL=chunk-
|
|
107
|
-
//# sourceMappingURL=chunk-
|
|
147
|
+
export { XML_DECL, argbToCss, bytesToBase64, bytesToDataUrl, cellRef, columnName, columnWidthToPx, dataUrlToImage, escapeAttr, escapeXml, imageMimeOf, parseCellRef, parseRange, pointsToPx, pxToColumnWidth, pxToPoints, toArgb };
|
|
148
|
+
//# sourceMappingURL=chunk-SDVGDHC4.js.map
|
|
149
|
+
//# sourceMappingURL=chunk-SDVGDHC4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/xlsx/media.ts","../src/xlsx/xml.ts"],"names":[],"mappings":"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","file":"chunk-SDVGDHC4.js","sourcesContent":["/**\n * 图片字节 ⇄ data URL。xlsx 的媒体部件是二进制,Univer 的 BASE64 图片源要完整的 data URL。\n */\n\n/**\n * 扩展名 → MIME。只收 Excel 认、浏览器也画得出来的 —— tif / emf / wmf 能进 xlsx,\n * 但到了浏览器里是张裂图,不如如实报告跳过。\n */\nconst IMAGE_MIME: Record<string, string> = {\n png: \"image/png\",\n jpeg: \"image/jpeg\",\n jpg: \"image/jpeg\",\n gif: \"image/gif\",\n bmp: \"image/bmp\",\n}\n\nexport function imageMimeOf(path: string): string | undefined {\n const ext = path.split(\".\").pop()?.toLowerCase()\n return ext ? IMAGE_MIME[ext] : undefined\n}\n\n/** 字节 → base64。浏览器没有 Buffer,得分块 btoa(一把梭会爆调用栈) */\nexport function bytesToBase64(bytes: Uint8Array): string {\n const B = (globalThis as { Buffer?: { from(b: Uint8Array): { toString(e: string): string } } })\n .Buffer\n if (B) return B.from(bytes).toString(\"base64\")\n let bin = \"\"\n const CHUNK = 0x8000\n for (let i = 0; i < bytes.length; i += CHUNK) {\n bin += String.fromCharCode(...bytes.subarray(i, i + CHUNK))\n }\n return btoa(bin)\n}\n\nexport function bytesToDataUrl(bytes: Uint8Array, mime: string): string {\n return `data:${mime};base64,${bytesToBase64(bytes)}`\n}\n\n/** data URL → 字节与扩展名。不是 base64 data URL、格式不在 `IMAGE_MIME` 里,都返回 undefined */\nexport function dataUrlToImage(url: string): { bytes: Uint8Array; ext: string } | undefined {\n const match = /^data:([\\w.+-]+\\/[\\w.+-]+);base64,([\\s\\S]*)$/.exec(url.trim())\n if (!match) return undefined\n const mime = (match[1] as string).toLowerCase()\n const ext = Object.keys(IMAGE_MIME).find((key) => IMAGE_MIME[key] === mime)\n if (!ext) return undefined\n let bin: string\n try {\n bin = atob((match[2] as string).replace(/\\s+/g, \"\"))\n } catch {\n return undefined\n }\n const bytes = new Uint8Array(bin.length)\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i)\n return { bytes, ext }\n}\n","/** OOXML 拼装与解析共用的小工具。没有依赖,Node 与浏览器通吃。 */\n\nimport type { CellRange, ColorStyle } from \"./types.ts\"\n\n/**\n * XML 1.0 不允许的字符必须清掉,否则整个 xlsx 打不开 ——\n * Excel 只报一句「无法读取内容」并给你一个空文档,不会说是哪个单元格。\n * 合法范围:#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]\n */\n// biome-ignore lint/suspicious/noControlCharactersInRegex: 匹配控制字符正是目的 —— 要把它们从输出里剔掉\nconst CONTROL = /[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\uFFFE\\uFFFF]/g\n/** 落单的代理项。成对的要留着 —— emoji 就是一对 */\nconst LONE_SURROGATE = /[\\uD800-\\uDBFF](?![\\uDC00-\\uDFFF])|(?<![\\uD800-\\uDBFF])[\\uDC00-\\uDFFF]/g\n\nexport function escapeXml(value: string): string {\n return value\n .replace(CONTROL, \"\")\n .replace(LONE_SURROGATE, \"\")\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n}\n\n/** 属性值还要额外躲掉单引号和换行(换行在属性里会被解析器规范化成空格) */\nexport function escapeAttr(value: string): string {\n return escapeXml(value).replace(/'/g, \"'\").replace(/\\r/g, \" \").replace(/\\n/g, \" \")\n}\n\n/** 0 → A,25 → Z,26 → AA */\nexport function columnName(index: number): string {\n let n = index\n let out = \"\"\n do {\n out = String.fromCharCode(65 + (n % 26)) + out\n n = Math.floor(n / 26) - 1\n } while (n >= 0)\n return out\n}\n\n/** (0, 0) → \"A1\" */\nexport function cellRef(row: number, column: number): string {\n return `${columnName(column)}${row + 1}`\n}\n\n/** \"A\" → 0,\"Z\" → 25,\"AA\" → 26。`columnName` 的逆。认不出返回 undefined */\nexport function columnIndex(name: string): number | undefined {\n if (!/^[A-Za-z]+$/.test(name)) return undefined\n let n = 0\n for (const ch of name.toUpperCase()) n = n * 26 + (ch.charCodeAt(0) - 64)\n return n - 1\n}\n\n/** \"A1\" → (0, 0)。`cellRef` 的逆。认不出返回 undefined */\nexport function parseCellRef(ref: string): { row: number; column: number } | undefined {\n const m = /^([A-Za-z]+)(\\d+)$/.exec(ref.trim())\n if (!m) return undefined\n const column = columnIndex(m[1] as string)\n const row = Number.parseInt(m[2] as string, 10) - 1\n if (column === undefined || row < 0) return undefined\n return { row, column }\n}\n\n/** \"A1:C3\" → CellRange。单格引用 \"B2\" 也收(起止同格)。认不出返回 undefined */\nexport function parseRange(ref: string): CellRange | undefined {\n const [a, b] = ref.trim().split(\":\")\n const start = a ? parseCellRef(a) : undefined\n if (!start) return undefined\n const end = b ? parseCellRef(b) : start\n if (!end) return undefined\n return {\n startRow: Math.min(start.row, end.row),\n startColumn: Math.min(start.column, end.column),\n endRow: Math.max(start.row, end.row),\n endColumn: Math.max(start.column, end.column),\n }\n}\n\n/** 十六进制两位,大写 */\nfunction hex2(n: number): string {\n return Math.max(0, Math.min(255, Math.round(n)))\n .toString(16)\n .toUpperCase()\n .padStart(2, \"0\")\n}\n\n/**\n * CSS 颜色 → xlsx 的 `AARRGGBB`。\n *\n * 认得 `#RGB` / `#RGBA` / `#RRGGBB` / `#RRGGBBAA` / `rgb()` / `rgba()`。\n * 认不出的(主题色 token、`currentColor`、颜色关键字)返回 undefined,\n * 由调用方跳过 —— 猜一个颜色写进去比不写更糟。\n */\nexport function toArgb(color: ColorStyle | string | null | undefined): string | undefined {\n const raw = typeof color === \"string\" ? color : color?.rgb\n if (!raw) return undefined\n const s = raw.trim()\n\n if (s.startsWith(\"#\")) {\n const h = s.slice(1)\n if (!/^[0-9a-fA-F]+$/.test(h)) return undefined\n const dup = (c: string) => c + c\n if (h.length === 3 || h.length === 4) {\n const [r, g, b, a] = h.split(\"\") as [string, string, string, string?]\n return `${a ? dup(a) : \"FF\"}${dup(r)}${dup(g)}${dup(b)}`.toUpperCase()\n }\n if (h.length === 6) return `FF${h.toUpperCase()}`\n // CSS 是 RRGGBBAA,xlsx 是 AARRGGBB —— alpha 要挪到前面\n if (h.length === 8) return `${h.slice(6, 8)}${h.slice(0, 6)}`.toUpperCase()\n return undefined\n }\n\n const m = /^rgba?\\(([^)]+)\\)$/i.exec(s)\n if (m) {\n const parts = (m[1] as string).split(/[,/\\s]+/).filter(Boolean)\n if (parts.length < 3) return undefined\n const [r, g, b, a] = parts as [string, string, string, string?]\n const alpha = a === undefined ? 1 : Number.parseFloat(a) / (a.includes(\"%\") ? 100 : 1)\n const chan = (v: string) =>\n v.includes(\"%\") ? (Number.parseFloat(v) / 100) * 255 : Number.parseFloat(v)\n if (!Number.isFinite(alpha)) return undefined\n return `${hex2(alpha * 255)}${hex2(chan(r))}${hex2(chan(g))}${hex2(chan(b))}`\n }\n\n return undefined\n}\n\n/**\n * xlsx 的 `AARRGGBB` / `RRGGBB` → CSS 颜色。`toArgb` 的逆。\n * 全不透明出 `#RRGGBB`,带 alpha 出 `rgba()`。认不出返回 undefined。\n */\nexport function argbToCss(argb: string | null | undefined): string | undefined {\n if (!argb) return undefined\n const h = argb.trim()\n if (!/^[0-9a-fA-F]{6}$|^[0-9a-fA-F]{8}$/.test(h)) return undefined\n if (h.length === 6) return `#${h.toUpperCase()}`\n const a = Number.parseInt(h.slice(0, 2), 16)\n const rgb = h.slice(2).toUpperCase()\n if (a === 255) return `#${rgb}`\n const alpha = Math.round((a / 255) * 1000) / 1000\n return `rgba(${Number.parseInt(rgb.slice(0, 2), 16)},${Number.parseInt(rgb.slice(2, 4), 16)},${Number.parseInt(rgb.slice(4, 6), 16)},${alpha})`\n}\n\n/** px → Excel 列宽(单位是默认字体最宽数字的宽度,Calibri 11 下 MDW = 7px) */\nexport function pxToColumnWidth(px: number): number {\n return Math.round(((px - 5) / 7) * 100) / 100\n}\n\n/** Excel 列宽 → px。`pxToColumnWidth` 的逆 */\nexport function columnWidthToPx(width: number): number {\n return Math.round(width * 7 + 5)\n}\n\n/** px → pt。Excel 的行高是磅值 */\nexport function pxToPoints(px: number): number {\n return Math.round(px * 0.75 * 100) / 100\n}\n\n/** pt → px。`pxToPoints` 的逆 */\nexport function pointsToPx(pt: number): number {\n return Math.round((pt / 0.75) * 100) / 100\n}\n\nexport const XML_DECL = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\\n'\n"]}
|
|
@@ -83,7 +83,7 @@ function csvFromSnapshot(workbook, options = {}) {
|
|
|
83
83
|
}
|
|
84
84
|
if (sawDateFormat) {
|
|
85
85
|
warnings.push(
|
|
86
|
-
"有单元格用的是日期/时间格式,csv 里会写成 Excel 序列号(如 45678)而不是日期文本 —— csv 不带格式信息,导入方需要自己按日期列解析"
|
|
86
|
+
"有单元格用的是日期/时间格式,csv 里会写成 Excel 序列号(如 45678)而不是日期文本 —— csv 不带格式信息,导入方需要自己按日期列解析" + (workbook.dateSystem === "date1904" ? "。注意本工作簿用 1904 日期系统,序列号从 1904-01-01 起算,按 1900 体系解析会早 1462 天" : "")
|
|
87
87
|
);
|
|
88
88
|
}
|
|
89
89
|
if (sawRichText) warnings.push("富文本单元格已压平成纯文本,段内的字体与颜色不保留");
|
|
@@ -124,5 +124,5 @@ function activeSheetId(univerAPI) {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
export { CSV_MIME, activeSheetId, csvFromSnapshot, escapeCsvField };
|
|
127
|
-
//# sourceMappingURL=chunk-
|
|
128
|
-
//# sourceMappingURL=chunk-
|
|
127
|
+
//# sourceMappingURL=chunk-XB6FEC4I.js.map
|
|
128
|
+
//# sourceMappingURL=chunk-XB6FEC4I.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/xlsx/csv.ts"],"names":["text"],"mappings":"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","file":"chunk-XB6FEC4I.js","sourcesContent":["/**\n * Univer 快照 → CSV。\n *\n * **csv 是单表格式,工作簿是多表的**,这是产品决定不是技术决定。本实现的口径:\n * 导**一张**表,其余的在 `warnings` 里**逐个点名**,和 xlsx 导出「如实报告丢了什么」\n * 保持一致 —— 静悄悄只给一张表,用户往往到对账时才发现少了东西。\n *\n * 「哪张是活动表」只有运行时的 Univer 实例知道,**快照里根本没有这个字段**。\n * 所以:传 `univerAPI` 时取真正的活动表;只传快照时取 `sheetOrder` 的第一张,\n * 并且照样把这件事写进 warnings。要指定就用 `options.sheet`(表 id 或表名)。\n */\n\nimport { looksLikeDateFormat, numericKeys, richTextToPlain } from \"./cell.ts\"\nimport type { CellData, StyleData, WorkbookData, WorksheetData } from \"./types.ts\"\n\nexport interface CsvOptions {\n /** 导哪张表:工作表 id 或表名。不传则用活动表(拿不到就用第一张) */\n sheet?: string\n /** 分隔符,默认 `,`。用 `\\t` 就是 tsv */\n delimiter?: string\n /** 行分隔,默认 `\\r\\n`(RFC 4180 规定,Excel 也最稳) */\n newline?: string\n /**\n * 是否加 UTF-8 BOM,默认 **true**。\n * 不加的话 Excel 会按本地编码(简中系统是 GBK)解析,中文全是乱码 ——\n * 这是 csv 导出最常见的投诉,默认就得挡掉。\n */\n bom?: boolean\n /** 公式格写 Univer 算好的值(默认)还是写公式文本 */\n formulas?: \"value\" | \"formula\"\n}\n\nexport interface CsvResult {\n /** 文本内容,不含 BOM */\n text: string\n /** 可直接落盘/上传的字节,按 `bom` 决定是否带 BOM */\n bytes: Uint8Array\n /** 导出时丢掉/降级了什么。**要展示给用户** */\n warnings: string[]\n stats: {\n sheetName: string\n rows: number\n columns: number\n cells: number\n /** 没被导出的工作表数 */\n skippedSheets: number\n }\n}\n\nexport const CSV_MIME = \"text/csv;charset=utf-8\"\n\n/** RFC 4180:字段含分隔符、引号或换行时整体加引号,内部引号翻倍 */\nexport function escapeCsvField(value: string, delimiter = \",\"): string {\n if (!value) return \"\"\n const needsQuote =\n value.includes(delimiter) || value.includes('\"') || value.includes(\"\\n\") || value.includes(\"\\r\")\n return needsQuote ? `\"${value.replace(/\"/g, '\"\"')}\"` : value\n}\n\nexport function csvFromSnapshot(workbook: WorkbookData, options: CsvOptions = {}): CsvResult {\n const { delimiter = \",\", newline = \"\\r\\n\", bom = true, formulas = \"value\" } = options\n\n const warnings: string[] = []\n const order = (\n workbook.sheetOrder?.length ? workbook.sheetOrder : Object.keys(workbook.sheets ?? {})\n ).filter((id) => workbook.sheets?.[id])\n\n if (!order.length) {\n return {\n text: \"\",\n bytes: encode(\"\", bom),\n warnings: [\"工作簿里没有工作表\"],\n stats: { sheetName: \"\", rows: 0, columns: 0, cells: 0, skippedSheets: 0 },\n }\n }\n\n // 指定 → 按 id 或表名找;没指定 → 第一张\n const wanted = options.sheet\n const pickedId =\n (wanted &&\n (order.find((id) => id === wanted) ??\n order.find((id) => (workbook.sheets?.[id] as WorksheetData)?.name === wanted))) ||\n (order[0] as string)\n if (\n wanted &&\n pickedId !== wanted &&\n (workbook.sheets?.[pickedId] as WorksheetData)?.name !== wanted\n ) {\n warnings.push(\n `找不到工作表「${wanted}」,已改导「${(workbook.sheets?.[pickedId] as WorksheetData)?.name ?? pickedId}」`,\n )\n }\n\n const sheet = workbook.sheets?.[pickedId] as WorksheetData\n const sheetName = sheet?.name ?? pickedId\n\n // 点名没导出的表 —— 这条是 csv 导出最容易被忽略的损失\n const skipped = order.filter((id) => id !== pickedId)\n if (skipped.length) {\n const names = skipped.map((id) => `「${(workbook.sheets?.[id] as WorksheetData)?.name ?? id}」`)\n warnings.push(\n `csv 是单表格式,只导出了「${sheetName}」。未导出的 ${skipped.length} 张表:${names.join(\"\")}`,\n )\n }\n\n const styleMap = workbook.styles ?? {}\n const resolveStyle = (s: StyleData | string | null | undefined): StyleData | undefined => {\n if (!s) return undefined\n if (typeof s === \"string\") return styleMap[s] ?? undefined\n return s\n }\n\n const cellData = sheet?.cellData ?? {}\n const rows = numericKeys(cellData)\n let maxCol = -1\n for (const r of rows) {\n const cols = numericKeys(cellData[r])\n const last = cols[cols.length - 1]\n if (last !== undefined && last > maxCol) maxCol = last\n }\n const maxRow = rows.length ? (rows[rows.length - 1] as number) : -1\n\n let cells = 0\n let sawDateFormat = false\n let sawRichText = false\n\n const lines: string[] = []\n for (let r = 0; r <= maxRow; r++) {\n const row = cellData[r]\n const fields: string[] = []\n for (let c = 0; c <= maxCol; c++) {\n const cell = row?.[c]\n const text = cell ? cellToText(cell) : \"\"\n if (text) cells++\n fields.push(escapeCsvField(text, delimiter))\n }\n lines.push(fields.join(delimiter))\n }\n\n function cellToText(cell: CellData): string {\n if (formulas === \"formula\" && cell.f) return cell.f\n\n const rich = richTextToPlain(cell)\n if (rich !== undefined) {\n sawRichText = true\n return rich\n }\n\n const v = cell.v\n if (v === undefined || v === null) return \"\"\n if (typeof v === \"boolean\") return v ? \"TRUE\" : \"FALSE\"\n if (typeof v === \"number\") {\n // 日期在 Univer 里是「序列号 + 数字格式」,值本身就是个数字。\n // 这里不猜着转,只记下来在 warnings 里说清楚\n if (looksLikeDateFormat(resolveStyle(cell.s)?.n?.pattern)) sawDateFormat = true\n return String(v)\n }\n return String(v)\n }\n\n if (sawDateFormat) {\n warnings.push(\n \"有单元格用的是日期/时间格式,csv 里会写成 Excel 序列号(如 45678)而不是日期文本 —— \" +\n \"csv 不带格式信息,导入方需要自己按日期列解析\" +\n (workbook.dateSystem === \"date1904\"\n ? \"。注意本工作簿用 1904 日期系统,序列号从 1904-01-01 起算,按 1900 体系解析会早 1462 天\"\n : \"\"),\n )\n }\n if (sawRichText) warnings.push(\"富文本单元格已压平成纯文本,段内的字体与颜色不保留\")\n if (sheet?.mergeData?.length) {\n warnings.push(`${sheet.mergeData.length} 处合并单元格已拆开:值留在左上角,其余为空`)\n }\n if (formulas === \"value\") {\n const hasFormula = rows.some((r) => numericKeys(cellData[r]).some((c) => cellData[r]?.[c]?.f))\n if (hasFormula) warnings.push(\"公式已写成 Univer 算出的值,公式本身不保留\")\n }\n\n const text = lines.join(newline)\n return {\n text,\n bytes: encode(text, bom),\n warnings,\n stats: {\n sheetName,\n rows: maxRow + 1,\n columns: maxCol + 1,\n cells,\n skippedSheets: skipped.length,\n },\n }\n}\n\nfunction encode(text: string, bom: boolean): Uint8Array {\n const body = new TextEncoder().encode(text)\n if (!bom) return body\n const out = new Uint8Array(body.length + 3)\n out.set([0xef, 0xbb, 0xbf])\n out.set(body, 3)\n return out\n}\n\n/**\n * 从 Univer 实例上问出当前活动表的 id。\n *\n * 参数是 `unknown` 而不是 `FUniver`:`@univerjs/presets` 是可选 peer,\n * 写具体类型会让没装它的项目 typecheck 直接红。\n */\nexport function activeSheetId(univerAPI: unknown): string | undefined {\n const book = (univerAPI as { getActiveWorkbook?: () => unknown } | null)?.getActiveWorkbook?.()\n const sheet = (book as { getActiveSheet?: () => unknown } | null)?.getActiveSheet?.()\n const id = (sheet as { getSheetId?: () => string } | null)?.getSheetId?.()\n return typeof id === \"string\" && id ? id : undefined\n}\n"]}
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
* 唯一需要改的地方。
|
|
12
12
|
*/
|
|
13
13
|
type CellValue = string | number | boolean;
|
|
14
|
+
/** 对齐 `DateSystem`:日期序列号从哪天起算 */
|
|
15
|
+
type DateSystem = "date1900" | "date1904";
|
|
14
16
|
interface ColorStyle {
|
|
15
17
|
/** `#RRGGBB` / `rgb(r,g,b)` / `rgba(r,g,b,a)` */
|
|
16
18
|
rgb?: string | null;
|
|
@@ -22,6 +24,7 @@ interface TextDecorationData {
|
|
|
22
24
|
/** 0 关 1 开 */
|
|
23
25
|
s?: number;
|
|
24
26
|
cl?: ColorStyle | null;
|
|
27
|
+
/** 线型,对齐 `TextDecoration`,下划线见 `UNDERLINE` */
|
|
25
28
|
t?: number;
|
|
26
29
|
}
|
|
27
30
|
interface BorderStyleData {
|
|
@@ -44,6 +47,8 @@ interface TextRotation {
|
|
|
44
47
|
interface StyleData {
|
|
45
48
|
/** fontFamily */
|
|
46
49
|
ff?: string | null;
|
|
50
|
+
/** 东亚字体,中日韩字符优先用它渲染。xlsx 的字体只有一个名字,导出时仅在没有 `ff` 时顶上 */
|
|
51
|
+
eastAsiaFontFamily?: string | null;
|
|
47
52
|
/** fontSize,pt */
|
|
48
53
|
fs?: number;
|
|
49
54
|
/** italic */
|
|
@@ -68,6 +73,8 @@ interface StyleData {
|
|
|
68
73
|
n?: {
|
|
69
74
|
pattern?: string;
|
|
70
75
|
} | null;
|
|
76
|
+
/** shrinkToFit:缩小字体填充,1 开 */
|
|
77
|
+
stf?: number;
|
|
71
78
|
/** textRotation */
|
|
72
79
|
tr?: TextRotation | null;
|
|
73
80
|
/** horizontalAlign */
|
|
@@ -89,6 +96,13 @@ interface CellData {
|
|
|
89
96
|
t?: number | null;
|
|
90
97
|
/** 原始公式,含前导 `=` */
|
|
91
98
|
f?: string | null;
|
|
99
|
+
/**
|
|
100
|
+
* 公式类型,见 `FORMULA_TYPE`。Univer 只保存不参与计算,用户改了公式就清空 ——
|
|
101
|
+
* 它存在的意义就是让导入的数组公式 / 模拟运算表在导出时能还原
|
|
102
|
+
*/
|
|
103
|
+
ft?: number | null;
|
|
104
|
+
/** 1 = 动态数组公式(Excel 365 的溢出公式),来自 metadata.xml 的 `dynamicArrayProperties@fDynamic` */
|
|
105
|
+
fd?: number | null;
|
|
92
106
|
/** 共享公式组 id。同组里只有一个单元格带 `f` */
|
|
93
107
|
si?: string | null;
|
|
94
108
|
/** 数组公式的引用范围 */
|
|
@@ -129,6 +143,15 @@ interface FreezeData {
|
|
|
129
143
|
startRow: number;
|
|
130
144
|
startColumn: number;
|
|
131
145
|
}
|
|
146
|
+
/** 对齐 `IWorksheetBackgroundImage`:平铺在单元格下面的工作表背景图 */
|
|
147
|
+
interface WorksheetBackgroundImage {
|
|
148
|
+
/** `BASE64` 时必须是完整的 data URL —— Univer 直接把它塞给 `img.src` */
|
|
149
|
+
source: string;
|
|
150
|
+
/** 对齐 `ImageSourceType` */
|
|
151
|
+
imageSourceType: "URL" | "UUID" | "BASE64";
|
|
152
|
+
scaleX?: number;
|
|
153
|
+
scaleY?: number;
|
|
154
|
+
}
|
|
132
155
|
/** `IObjectMatrixPrimitiveType<T>`:行号 → 列号 → 值,两层都是稀疏对象 */
|
|
133
156
|
type Matrix<T> = Record<number, Record<number, T> | undefined>;
|
|
134
157
|
interface WorksheetData {
|
|
@@ -136,7 +159,7 @@ interface WorksheetData {
|
|
|
136
159
|
name?: string;
|
|
137
160
|
/** `#RRGGBB` */
|
|
138
161
|
tabColor?: string;
|
|
139
|
-
/** 1 =
|
|
162
|
+
/** 对齐 `WorksheetHiddenState`:1 = 隐藏,2 = 深度隐藏(xlsx 的 veryHidden,「取消隐藏」里不列出) */
|
|
140
163
|
hidden?: number;
|
|
141
164
|
freeze?: FreezeData;
|
|
142
165
|
rowCount?: number;
|
|
@@ -154,6 +177,8 @@ interface WorksheetData {
|
|
|
154
177
|
/** 1 = 从右向左 */
|
|
155
178
|
rightToLeft?: number;
|
|
156
179
|
defaultStyle?: StyleData | string | null;
|
|
180
|
+
/** 渲染随表格通道内置的 drawing preset 一起加载;没装该包时快照里仍会原样保留 */
|
|
181
|
+
backgroundImage?: WorksheetBackgroundImage;
|
|
157
182
|
}
|
|
158
183
|
interface WorkbookData {
|
|
159
184
|
id?: string;
|
|
@@ -164,6 +189,8 @@ interface WorkbookData {
|
|
|
164
189
|
/** 样式表:`CellData.s` 为字符串时查这里 */
|
|
165
190
|
styles?: Record<string, StyleData | null | undefined>;
|
|
166
191
|
defaultStyle?: StyleData | string | null;
|
|
192
|
+
/** 缺省是 1900 体系。Univer 的格式化、日期编辑和公式都按它解释序列号 */
|
|
193
|
+
dateSystem?: DateSystem;
|
|
167
194
|
/**
|
|
168
195
|
* 各插件自己序列化的数据(图片、条件格式、数据校验、筛选……)。
|
|
169
196
|
* 导出读不了它们的私有结构,但**能据此如实报告丢了什么** —— 见 `warnings`。
|
package/dist/csv.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { W as WorkbookData } from './csv-parse-
|
|
2
|
-
export { C as CellData, a as CsvParseOptions, b as CsvToSnapshotResult, c as WorksheetData, d as csvToSnapshot, p as parseCsv } from './csv-parse-
|
|
1
|
+
import { W as WorkbookData } from './csv-parse-DXlwzoZ6.js';
|
|
2
|
+
export { C as CellData, a as CsvParseOptions, b as CsvToSnapshotResult, c as WorksheetData, d as csvToSnapshot, p as parseCsv } from './csv-parse-DXlwzoZ6.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Univer 快照 → CSV。
|
package/dist/csv.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { activeSheetId, csvFromSnapshot, CSV_MIME } from './chunk-
|
|
2
|
-
export { CSV_MIME, csvFromSnapshot } from './chunk-
|
|
3
|
-
import { toSnapshot } from './chunk-
|
|
4
|
-
export { csvToSnapshot, parseCsv } from './chunk-
|
|
1
|
+
import { activeSheetId, csvFromSnapshot, CSV_MIME } from './chunk-XB6FEC4I.js';
|
|
2
|
+
export { CSV_MIME, csvFromSnapshot } from './chunk-XB6FEC4I.js';
|
|
3
|
+
import { toSnapshot } from './chunk-JZ67Q3QI.js';
|
|
4
|
+
export { csvToSnapshot, parseCsv } from './chunk-2DI4FJPC.js';
|
|
5
5
|
import './chunk-5HMKRNIH.js';
|
|
6
6
|
|
|
7
7
|
// src/csv.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"import-
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"import-O7RUERND.js"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { D as DocumentViewProps, a as DocumentFormat } from './registry-
|
|
4
|
-
export { F as FormatAdapter, b as FormatCapabilities, S as SheetOptions, c as SheetUiOptions, d as detectFormat, g as getFormat, l as listFormats, r as registerFormat } from './registry-
|
|
3
|
+
import { D as DocumentViewProps, a as DocumentFormat } from './registry-BQ5T1Yko.js';
|
|
4
|
+
export { F as FormatAdapter, b as FormatCapabilities, S as SheetOptions, c as SheetUiOptions, d as detectFormat, g as getFormat, l as listFormats, r as registerFormat } from './registry-BQ5T1Yko.js';
|
|
5
5
|
import './code-types-Dqmit3xx.js';
|
|
6
6
|
import 'shiki';
|
|
7
7
|
|
package/dist/index.js
CHANGED
package/dist/pdf.d.ts
CHANGED