@tita-agent/dsh-data-table 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +172 -2
  3. package/cordis.patch.yml +7 -0
  4. package/lib/client.js +16766 -0
  5. package/lib/contract-envelope.d.ts +91 -0
  6. package/lib/contract-envelope.js +106 -0
  7. package/lib/contract-layout.d.ts +130 -0
  8. package/lib/contract-layout.js +138 -0
  9. package/lib/contract-refs.d.ts +39 -0
  10. package/lib/contract-refs.js +9 -0
  11. package/lib/contract-version.d.ts +311 -0
  12. package/lib/contract-version.js +270 -0
  13. package/lib/contract-wire.d.ts +147 -0
  14. package/lib/contract-wire.js +99 -0
  15. package/lib/contracts.d.ts +12 -0
  16. package/lib/contracts.js +12 -0
  17. package/lib/types/audit.d.ts +42 -0
  18. package/lib/types/audit.js +39 -0
  19. package/lib/types/client/ProjectImportMenu.d.ts +30 -0
  20. package/lib/types/client/ProjectImportMenu.js +70 -0
  21. package/lib/types/client/SheetPanel.d.ts +33 -0
  22. package/lib/types/client/SheetPanel.js +1766 -0
  23. package/lib/types/client/SheetToggle.d.ts +18 -0
  24. package/lib/types/client/SheetToggle.js +26 -0
  25. package/lib/types/client/index.d.ts +15 -0
  26. package/lib/types/client/index.js +110 -0
  27. package/lib/types/client/persistence/changes.d.ts +15 -0
  28. package/lib/types/client/persistence/changes.js +51 -0
  29. package/lib/types/client/persistence/ids.d.ts +34 -0
  30. package/lib/types/client/persistence/ids.js +48 -0
  31. package/lib/types/client/persistence/merge.d.ts +35 -0
  32. package/lib/types/client/persistence/merge.js +362 -0
  33. package/lib/types/client/store.d.ts +61 -0
  34. package/lib/types/client/store.js +152 -0
  35. package/lib/types/client/surface-context.d.ts +27 -0
  36. package/lib/types/client/surface-context.js +104 -0
  37. package/lib/types/client/surface-control.d.ts +2 -0
  38. package/lib/types/client/surface-control.js +12 -0
  39. package/lib/types/client/transport/workbookApi.d.ts +159 -0
  40. package/lib/types/client/transport/workbookApi.js +246 -0
  41. package/lib/types/client/univer/StandaloneWorkbookPage.d.ts +5 -0
  42. package/lib/types/client/univer/StandaloneWorkbookPage.js +7 -0
  43. package/lib/types/client/univer/WorkbookCanvas.d.ts +40 -0
  44. package/lib/types/client/univer/WorkbookCanvas.js +87 -0
  45. package/lib/types/client/univer/WorkbookView.d.ts +3 -0
  46. package/lib/types/client/univer/WorkbookView.js +2 -0
  47. package/lib/types/client/univer/loader.d.ts +18 -0
  48. package/lib/types/client/univer/loader.js +81 -0
  49. package/lib/types/client/univer/standalone-entry.d.ts +1 -0
  50. package/lib/types/client/univer/standalone-entry.js +19 -0
  51. package/lib/types/client/versions/VersionChrome.d.ts +33 -0
  52. package/lib/types/client/versions/VersionChrome.js +21 -0
  53. package/lib/types/client/versions/inspect.d.ts +70 -0
  54. package/lib/types/client/versions/inspect.js +88 -0
  55. package/lib/types/client/versions/preview-decoration.d.ts +11 -0
  56. package/lib/types/client/versions/preview-decoration.js +54 -0
  57. package/lib/types/client/versions/records.d.ts +19 -0
  58. package/lib/types/client/versions/records.js +70 -0
  59. package/lib/types/client/workspace-host.d.ts +61 -0
  60. package/lib/types/client/workspace-host.js +124 -0
  61. package/lib/types/collaboration-hub.d.ts +31 -0
  62. package/lib/types/collaboration-hub.js +69 -0
  63. package/lib/types/contract/ids.d.ts +24 -0
  64. package/lib/types/contract/ids.js +46 -0
  65. package/lib/types/contract/mutations.d.ts +25 -0
  66. package/lib/types/contract/mutations.js +782 -0
  67. package/lib/types/contract/operations.d.ts +54 -0
  68. package/lib/types/contract/operations.js +203 -0
  69. package/lib/types/contract/snapshots.d.ts +176 -0
  70. package/lib/types/contract/snapshots.js +351 -0
  71. package/lib/types/contract/univer-api-catalog.d.ts +29 -0
  72. package/lib/types/contract/univer-api-catalog.js +264 -0
  73. package/lib/types/errors.d.ts +8 -0
  74. package/lib/types/errors.js +12 -0
  75. package/lib/types/http/assets-routes.d.ts +3 -0
  76. package/lib/types/http/assets-routes.js +169 -0
  77. package/lib/types/http/collaboration.d.ts +10 -0
  78. package/lib/types/http/collaboration.js +154 -0
  79. package/lib/types/http/history.d.ts +15 -0
  80. package/lib/types/http/history.js +134 -0
  81. package/lib/types/http/project-files.d.ts +79 -0
  82. package/lib/types/http/project-files.js +206 -0
  83. package/lib/types/http/project-scope.d.ts +50 -0
  84. package/lib/types/http/project-scope.js +52 -0
  85. package/lib/types/http/routes.d.ts +98 -0
  86. package/lib/types/http/routes.js +323 -0
  87. package/lib/types/http/standalone.d.ts +9 -0
  88. package/lib/types/http/standalone.js +31 -0
  89. package/lib/types/http/trunk.d.ts +10 -0
  90. package/lib/types/http/trunk.js +322 -0
  91. package/lib/types/http/worktree.d.ts +9 -0
  92. package/lib/types/http/worktree.js +145 -0
  93. package/lib/types/index.d.ts +18 -0
  94. package/lib/types/index.js +156 -0
  95. package/lib/types/invariant.d.ts +15 -0
  96. package/lib/types/invariant.js +15 -0
  97. package/lib/types/request-params.d.ts +21 -0
  98. package/lib/types/request-params.js +76 -0
  99. package/lib/types/store/paths.d.ts +68 -0
  100. package/lib/types/store/paths.js +148 -0
  101. package/lib/types/store/project.d.ts +88 -0
  102. package/lib/types/store/project.js +120 -0
  103. package/lib/types/store/read.d.ts +110 -0
  104. package/lib/types/store/read.js +404 -0
  105. package/lib/types/store/retention.d.ts +27 -0
  106. package/lib/types/store/retention.js +111 -0
  107. package/lib/types/store/write.d.ts +22 -0
  108. package/lib/types/store/write.js +210 -0
  109. package/lib/types/tools/arguments.d.ts +40 -0
  110. package/lib/types/tools/arguments.js +130 -0
  111. package/lib/types/tools/cells.d.ts +50 -0
  112. package/lib/types/tools/cells.js +298 -0
  113. package/lib/types/tools/index.d.ts +2 -0
  114. package/lib/types/tools/index.js +250 -0
  115. package/lib/types/tools/render.d.ts +47 -0
  116. package/lib/types/tools/render.js +290 -0
  117. package/lib/types/tools/univer-api.d.ts +18 -0
  118. package/lib/types/tools/univer-api.js +198 -0
  119. package/lib/types/tools/workbook-catalog.d.ts +3 -0
  120. package/lib/types/tools/workbook-catalog.js +83 -0
  121. package/lib/types/tools/workbook-edit.d.ts +192 -0
  122. package/lib/types/tools/workbook-edit.js +912 -0
  123. package/lib/types/tools/workbook-find.d.ts +11 -0
  124. package/lib/types/tools/workbook-find.js +89 -0
  125. package/lib/types/tools/workbook-history.d.ts +2 -0
  126. package/lib/types/tools/workbook-history.js +59 -0
  127. package/lib/types/tools/workbook-read.d.ts +21 -0
  128. package/lib/types/tools/workbook-read.js +204 -0
  129. package/lib/types/types.d.ts +377 -0
  130. package/lib/types/types.js +34 -0
  131. package/lib/types/univer/apply-operation.d.ts +14 -0
  132. package/lib/types/univer/apply-operation.js +398 -0
  133. package/lib/types/univer/chunk.d.ts +68 -0
  134. package/lib/types/univer/chunk.js +16 -0
  135. package/lib/types/univer/decoration.d.ts +34 -0
  136. package/lib/types/univer/decoration.js +88 -0
  137. package/lib/types/univer/diagnostics.d.ts +31 -0
  138. package/lib/types/univer/diagnostics.js +141 -0
  139. package/lib/types/univer/engine.d.ts +33 -0
  140. package/lib/types/univer/engine.js +338 -0
  141. package/lib/types/univer/entry.d.ts +8 -0
  142. package/lib/types/univer/entry.js +11 -0
  143. package/lib/types/univer/facade.d.ts +107 -0
  144. package/lib/types/univer/facade.js +1 -0
  145. package/lib/types/univer/fonts.d.ts +202 -0
  146. package/lib/types/univer/fonts.js +140 -0
  147. package/lib/types/univer/plugins/collaboration.d.ts +23 -0
  148. package/lib/types/univer/plugins/collaboration.js +47 -0
  149. package/lib/types/univer/plugins/export.d.ts +39 -0
  150. package/lib/types/univer/plugins/export.js +246 -0
  151. package/lib/types/univer/plugins/history.d.ts +24 -0
  152. package/lib/types/univer/plugins/history.js +50 -0
  153. package/lib/types/univer/plugins/version.d.ts +13 -0
  154. package/lib/types/univer/plugins/version.js +13 -0
  155. package/lib/types/version/diff.d.ts +36 -0
  156. package/lib/types/version/diff.js +156 -0
  157. package/lib/types/version/grouping.d.ts +7 -0
  158. package/lib/types/version/grouping.js +94 -0
  159. package/lib/types/version/records.d.ts +17 -0
  160. package/lib/types/version/records.js +102 -0
  161. package/lib/types/version/session.d.ts +36 -0
  162. package/lib/types/version/session.js +89 -0
  163. package/lib/types/version/summary.d.ts +24 -0
  164. package/lib/types/version/summary.js +111 -0
  165. package/lib/types/workbook-manager.d.ts +191 -0
  166. package/lib/types/workbook-manager.js +935 -0
  167. package/lib/types/xlsx-export-worker.d.ts +5 -0
  168. package/lib/types/xlsx-export-worker.js +24 -0
  169. package/lib/types/xlsx-export.d.ts +21 -0
  170. package/lib/types/xlsx-export.js +371 -0
  171. package/lib/types/xlsx-import-worker.d.ts +1 -0
  172. package/lib/types/xlsx-import-worker.js +19 -0
  173. package/lib/univer-client.js +690 -0
  174. package/lib/workbook-page.js +23826 -0
  175. package/lib/xlsx-export-worker.js +104 -0
  176. package/lib/xlsx-import-worker.js +46 -0
  177. package/package.json +106 -3
  178. package/src/audit.ts +58 -0
  179. package/src/client/ProjectImportMenu.tsx +100 -0
  180. package/src/client/SheetPanel.module.css +1578 -0
  181. package/src/client/SheetPanel.tsx +1934 -0
  182. package/src/client/SheetToggle.module.css +73 -0
  183. package/src/client/SheetToggle.tsx +65 -0
  184. package/src/client/contract.d.ts +19 -0
  185. package/src/client/index.ts +131 -0
  186. package/src/client/persistence/changes.ts +58 -0
  187. package/src/client/persistence/ids.ts +60 -0
  188. package/src/client/persistence/merge.ts +392 -0
  189. package/src/client/store.ts +188 -0
  190. package/src/client/surface-context.ts +123 -0
  191. package/src/client/surface-control.ts +13 -0
  192. package/src/client/transport/workbookApi.ts +355 -0
  193. package/src/client/univer/SheetView.module.css +110 -0
  194. package/src/client/univer/StandaloneWorkbookPage.module.css +8 -0
  195. package/src/client/univer/StandaloneWorkbookPage.tsx +15 -0
  196. package/src/client/univer/WorkbookCanvas.tsx +128 -0
  197. package/src/client/univer/WorkbookView.module.css +30 -0
  198. package/src/client/univer/WorkbookView.tsx +3 -0
  199. package/src/client/univer/loader.ts +90 -0
  200. package/src/client/univer/react-dom-client.d.ts +10 -0
  201. package/src/client/univer/standalone-entry.tsx +19 -0
  202. package/src/client/univer/standalone.css +12 -0
  203. package/src/client/univer/univer-locales.d.ts +89 -0
  204. package/src/client/univer/univer-modules.d.ts +26 -0
  205. package/src/client/versions/VersionChrome.tsx +114 -0
  206. package/src/client/versions/inspect.ts +138 -0
  207. package/src/client/versions/preview-decoration.ts +54 -0
  208. package/src/client/versions/records.ts +78 -0
  209. package/src/client/workspace-host.ts +147 -0
  210. package/src/collaboration-hub.ts +83 -0
  211. package/src/contract/ids.ts +50 -0
  212. package/src/contract/mutations.ts +791 -0
  213. package/src/contract/operations.ts +221 -0
  214. package/src/contract/snapshots.ts +383 -0
  215. package/src/contract/univer-api-catalog.ts +289 -0
  216. package/src/css-modules.d.ts +6 -0
  217. package/src/errors.ts +25 -0
  218. package/src/http/assets-routes.ts +177 -0
  219. package/src/http/collaboration.ts +144 -0
  220. package/src/http/history.ts +151 -0
  221. package/src/http/project-files.ts +227 -0
  222. package/src/http/project-scope.ts +77 -0
  223. package/src/http/routes.ts +364 -0
  224. package/src/http/standalone.ts +32 -0
  225. package/src/http/trunk.ts +322 -0
  226. package/src/http/worktree.ts +119 -0
  227. package/src/index.ts +165 -0
  228. package/src/invariant.ts +17 -0
  229. package/src/request-params.ts +92 -0
  230. package/src/store/paths.ts +165 -0
  231. package/src/store/project.ts +137 -0
  232. package/src/store/read.ts +454 -0
  233. package/src/store/retention.ts +106 -0
  234. package/src/store/write.ts +230 -0
  235. package/src/tools/arguments.ts +128 -0
  236. package/src/tools/cells.ts +298 -0
  237. package/src/tools/index.ts +274 -0
  238. package/src/tools/render.ts +301 -0
  239. package/src/tools/univer-api.ts +243 -0
  240. package/src/tools/workbook-catalog.ts +94 -0
  241. package/src/tools/workbook-edit.ts +987 -0
  242. package/src/tools/workbook-find.ts +80 -0
  243. package/src/tools/workbook-history.ts +63 -0
  244. package/src/tools/workbook-read.ts +210 -0
  245. package/src/types.ts +432 -0
  246. package/src/univer/apply-operation.ts +369 -0
  247. package/src/univer/chunk.ts +77 -0
  248. package/src/univer/decoration.ts +111 -0
  249. package/src/univer/diagnostics.ts +136 -0
  250. package/src/univer/engine.ts +370 -0
  251. package/src/univer/entry.ts +14 -0
  252. package/src/univer/facade.ts +91 -0
  253. package/src/univer/fonts.ts +148 -0
  254. package/src/univer/overrides.css +33 -0
  255. package/src/univer/plugins/collaboration.ts +47 -0
  256. package/src/univer/plugins/export.ts +236 -0
  257. package/src/univer/plugins/history.ts +49 -0
  258. package/src/univer/plugins/version.ts +13 -0
  259. package/src/version/diff.ts +169 -0
  260. package/src/version/grouping.ts +96 -0
  261. package/src/version/records.ts +113 -0
  262. package/src/version/session.ts +90 -0
  263. package/src/version/summary.ts +117 -0
  264. package/src/workbook-manager.ts +1111 -0
  265. package/src/xlsx-export-worker.ts +34 -0
  266. package/src/xlsx-export.ts +373 -0
  267. package/src/xlsx-import-worker.ts +30 -0
@@ -0,0 +1,5 @@
1
+ /**
2
+ * On-demand export worker. SheetJS is intentionally isolated from the Univer
3
+ * main thread so large workbook encoding does not freeze scrolling/editing.
4
+ */
5
+ export {};
@@ -0,0 +1,24 @@
1
+ /**
2
+ * On-demand export worker. SheetJS is intentionally isolated from the Univer
3
+ * main thread so large workbook encoding does not freeze scrolling/editing.
4
+ */
5
+ import { workbookCsvText, workbookXlsxBytes } from "./xlsx-export.js";
6
+ const workerScope = globalThis;
7
+ workerScope.onmessage = event => {
8
+ try {
9
+ if (event.data.format === 'csv') {
10
+ const csv = workbookCsvText(event.data.snapshot);
11
+ workerScope.postMessage({ ok: true, format: 'csv', value: csv });
12
+ return;
13
+ }
14
+ const bytes = workbookXlsxBytes(event.data.snapshot);
15
+ if (bytes === null) {
16
+ workerScope.postMessage({ ok: true, format: 'xlsx', value: null });
17
+ return;
18
+ }
19
+ workerScope.postMessage({ ok: true, format: 'xlsx', value: bytes }, [bytes]);
20
+ }
21
+ catch (error) {
22
+ workerScope.postMessage({ ok: false, error: error instanceof Error ? error.message : String(error) });
23
+ }
24
+ };
@@ -0,0 +1,21 @@
1
+ /**
2
+ * XLSX/CSV exchange adapter for Datasheet.
3
+ *
4
+ * The free Univer presets intentionally do not include Univer PRO's exchange
5
+ * plugin. SheetJS is used here as the file-format adapter, while the stored
6
+ * representation remains a normal Univer snapshot. Values, formulas, sheet
7
+ * names, merges, dimensions, number formats and basic cell styles round-trip
8
+ * without making the host process depend on a browser-only API.
9
+ * @module dsh-data-table/xlsx-export
10
+ */
11
+ /** Download the first workbook sheet as UTF-8 CSV. */
12
+ export declare function downloadWorkbookCsv(snapshot: unknown, filenameBase: string): void;
13
+ /** Download all workbook sheets as an XLSX file. */
14
+ export declare function downloadWorkbookXlsx(snapshot: unknown, filenameBase: string): void;
15
+ /** Encode the first sheet as CSV without touching browser APIs. */
16
+ export declare function workbookCsvText(snapshot: unknown): string | null;
17
+ /** Encode all sheets as XLSX without touching browser APIs. */
18
+ export declare function workbookXlsxBytes(snapshot: unknown): ArrayBuffer | null;
19
+ /** Parse an uploaded XLSX file into a Univer-compatible snapshot. */
20
+ export declare function readWorkbookXlsx(data: ArrayBuffer, filename?: string): object;
21
+ export declare function downloadBlob(blob: Blob, filename: string): void;
@@ -0,0 +1,371 @@
1
+ /**
2
+ * XLSX/CSV exchange adapter for Datasheet.
3
+ *
4
+ * The free Univer presets intentionally do not include Univer PRO's exchange
5
+ * plugin. SheetJS is used here as the file-format adapter, while the stored
6
+ * representation remains a normal Univer snapshot. Values, formulas, sheet
7
+ * names, merges, dimensions, number formats and basic cell styles round-trip
8
+ * without making the host process depend on a browser-only API.
9
+ * @module dsh-data-table/xlsx-export
10
+ */
11
+ import * as XLSX from 'xlsx';
12
+ import { DEFAULT_SHEET_FONT_FAMILY, DEFAULT_SHEET_ROWS, DEFAULT_SHEET_COLUMNS } from "./contract/snapshots.js";
13
+ import { SHEET_MAX_COLUMNS, SHEET_MAX_PHYSICAL_ROWS, SHEET_MAX_ROWS } from "./types.js";
14
+ /** Download the first workbook sheet as UTF-8 CSV. */
15
+ export function downloadWorkbookCsv(snapshot, filenameBase) {
16
+ const csv = workbookCsvText(snapshot);
17
+ if (csv === null)
18
+ return;
19
+ downloadBlob(new Blob([csv], { type: 'text/csv;charset=utf-8' }), `${safeFilename(filenameBase)}.csv`);
20
+ }
21
+ /** Download all workbook sheets as an XLSX file. */
22
+ export function downloadWorkbookXlsx(snapshot, filenameBase) {
23
+ const bytes = workbookXlsxBytes(snapshot);
24
+ if (bytes === null)
25
+ return;
26
+ downloadBlob(new Blob([bytes], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }), `${safeFilename(filenameBase)}.xlsx`);
27
+ }
28
+ /** Encode the first sheet as CSV without touching browser APIs. */
29
+ export function workbookCsvText(snapshot) {
30
+ const sheet = orderedSheets(snapshot)[0];
31
+ if (sheet === undefined)
32
+ return null;
33
+ const bounds = usedBounds(sheet.sheet);
34
+ const lines = [];
35
+ for (let row = 0; row <= bounds.endRow; row += 1) {
36
+ const values = [];
37
+ for (let column = 0; column <= bounds.endColumn; column += 1) {
38
+ values.push(escapeCsv(displayCellValue(getCell(sheet.sheet, row, column))));
39
+ }
40
+ lines.push(values.join(','));
41
+ }
42
+ return `\uFEFF${lines.join('\n')}`;
43
+ }
44
+ /** Encode all sheets as XLSX without touching browser APIs. */
45
+ export function workbookXlsxBytes(snapshot) {
46
+ const workbook = snapshotToXlsx(snapshot);
47
+ if (workbook.SheetNames.length === 0)
48
+ return null;
49
+ return XLSX.write(workbook, { bookType: 'xlsx', type: 'array', cellStyles: true, compression: true });
50
+ }
51
+ /** Parse an uploaded XLSX file into a Univer-compatible snapshot. */
52
+ export function readWorkbookXlsx(data, filename = 'workbook') {
53
+ const workbook = XLSX.read(data, { type: 'array', cellFormula: true, cellStyles: true, cellDates: true, dense: false });
54
+ if (workbook.SheetNames.length === 0)
55
+ throw new Error('Excel 文件不包含工作表');
56
+ if (workbook.SheetNames.length > 100)
57
+ throw new Error('Excel 文件超过 Datasheet 上限(最多 100 个工作表)');
58
+ const sheets = {};
59
+ const sheetOrder = [];
60
+ const styles = {};
61
+ const styleIds = new Map();
62
+ for (const [index, name] of workbook.SheetNames.entries()) {
63
+ const source = workbook.Sheets[name];
64
+ const ref = source['!ref'] ?? 'A1:A1';
65
+ const range = XLSX.utils.decode_range(ref);
66
+ if (range.s.r < 0 || range.s.c < 0 || range.e.r >= SHEET_MAX_PHYSICAL_ROWS || range.e.c >= SHEET_MAX_COLUMNS)
67
+ throw new Error(`Excel 文件超过 Datasheet 上限(${SHEET_MAX_ROWS} 条数据行 + 表头 × ${SHEET_MAX_COLUMNS} 列)`);
68
+ const id = `sheet${index + 1}`;
69
+ const sheet = {
70
+ id,
71
+ name: safeSheetName(name, index),
72
+ rowCount: Math.max(DEFAULT_SHEET_ROWS, range.e.r + 1),
73
+ columnCount: Math.max(DEFAULT_SHEET_COLUMNS, range.e.c + 1),
74
+ defaultStyle: { ff: DEFAULT_SHEET_FONT_FAMILY },
75
+ cellData: {},
76
+ };
77
+ for (let row = range.s.r; row <= range.e.r; row += 1) {
78
+ for (let column = range.s.c; column <= range.e.c; column += 1) {
79
+ const address = XLSX.utils.encode_cell({ r: row, c: column });
80
+ const sourceCell = source[address];
81
+ if (sourceCell === undefined)
82
+ continue;
83
+ const cell = { v: normalizeImportedValue(sourceCell.v) };
84
+ if (typeof sourceCell.f === 'string' && sourceCell.f.length > 0)
85
+ cell.f = sourceCell.f;
86
+ const style = xlsxStyleToUniver(sourceCell.s, sourceCell.z);
87
+ if (Object.keys(style).length > 0) {
88
+ const signature = stableStyleSignature(style);
89
+ let styleId = styleIds.get(signature);
90
+ if (styleId === undefined) {
91
+ styleId = `xlsx-style-${styleIds.size + 1}`;
92
+ styleIds.set(signature, styleId);
93
+ styles[styleId] = style;
94
+ }
95
+ cell.s = styleId;
96
+ }
97
+ ;
98
+ (sheet.cellData ??= {})[String(row)] ??= {};
99
+ sheet.cellData[String(row)][String(column)] = cell;
100
+ }
101
+ }
102
+ if (Array.isArray(source['!merges']))
103
+ sheet.mergeData = source['!merges'].map(merge => ({
104
+ startRow: merge.s.r,
105
+ startColumn: merge.s.c,
106
+ endRow: merge.e.r,
107
+ endColumn: merge.e.c,
108
+ }));
109
+ if (Array.isArray(source['!cols']))
110
+ sheet.columnData = Object.fromEntries(source['!cols'].map((column, columnIndex) => [String(columnIndex), column]));
111
+ if (Array.isArray(source['!rows']))
112
+ sheet.rowData = Object.fromEntries(source['!rows'].map((row, rowIndex) => [String(rowIndex), row]));
113
+ sheets[id] = sheet;
114
+ sheetOrder.push(id);
115
+ }
116
+ return { id: 'imported', name: filename.replace(/\.[^.]+$/, '') || 'workbook', sheetOrder, sheets, ...(Object.keys(styles).length > 0 ? { styles } : {}) };
117
+ }
118
+ function snapshotToXlsx(snapshot) {
119
+ const root = (typeof snapshot === 'object' && snapshot !== null ? snapshot : {});
120
+ const workbook = XLSX.utils.book_new();
121
+ for (const entry of orderedSheets(root)) {
122
+ const worksheet = {};
123
+ const bounds = usedBounds(entry.sheet);
124
+ for (let row = 0; row <= bounds.endRow; row += 1) {
125
+ for (let column = 0; column <= bounds.endColumn; column += 1) {
126
+ const cell = getCell(entry.sheet, row, column);
127
+ if (cell.v === undefined && cell.f === undefined)
128
+ continue;
129
+ const target = XLSX.utils.encode_cell({ r: row, c: column });
130
+ const output = { v: cell.v === null ? undefined : cell.v, t: cellType(cell.v) };
131
+ if (typeof cell.f === 'string' && cell.f.length > 0)
132
+ output.f = cell.f.replace(/^=/, '');
133
+ const style = resolveCellStyle(root, cell);
134
+ const styleNumberFormat = typeof style?.n === 'string' ? style.n : undefined;
135
+ if (typeof cell.n === 'string')
136
+ output.z = cell.n;
137
+ else if (styleNumberFormat !== undefined)
138
+ output.z = styleNumberFormat;
139
+ if (style !== undefined) {
140
+ const xlsxStyle = univerStyleToXlsx(style);
141
+ if (Object.keys(xlsxStyle).length > 0)
142
+ output.s = xlsxStyle;
143
+ }
144
+ worksheet[target] = output;
145
+ }
146
+ }
147
+ worksheet['!ref'] = `A1:${XLSX.utils.encode_cell({ r: bounds.endRow, c: bounds.endColumn })}`;
148
+ const merges = Array.isArray(entry.sheet.mergeData) ? entry.sheet.mergeData : [];
149
+ worksheet['!merges'] = merges.filter(isRange).map(range => ({
150
+ s: { r: range.startRow, c: range.startColumn },
151
+ e: { r: range.endRow, c: range.endColumn },
152
+ }));
153
+ if (entry.sheet.columnData !== undefined)
154
+ worksheet['!cols'] = dimensionArray(entry.sheet.columnData, 'width', 'wch');
155
+ if (entry.sheet.rowData !== undefined)
156
+ worksheet['!rows'] = dimensionArray(entry.sheet.rowData, 'height', 'hpt');
157
+ XLSX.utils.book_append_sheet(workbook, worksheet, entry.name);
158
+ }
159
+ workbook.Props = { ...(workbook.Props ?? {}), Title: root.name ?? 'Datasheet' };
160
+ return workbook;
161
+ }
162
+ function orderedSheets(snapshot) {
163
+ const root = (typeof snapshot === 'object' && snapshot !== null ? snapshot : {});
164
+ const sheets = root.sheets ?? {};
165
+ const ids = root.sheetOrder?.filter(id => sheets[id] !== undefined) ?? Object.keys(sheets);
166
+ const usedNames = new Set();
167
+ return ids.map((id, index) => ({ id, name: uniqueSheetName(safeSheetName(sheets[id]?.name ?? id, index), usedNames, index), sheet: sheets[id] ?? {} }));
168
+ }
169
+ function uniqueSheetName(name, usedNames, index) {
170
+ let candidate = name;
171
+ let suffix = 2;
172
+ while (usedNames.has(candidate)) {
173
+ const suffixText = ` (${suffix++})`;
174
+ candidate = `${name.slice(0, Math.max(1, 31 - suffixText.length))}${suffixText}`;
175
+ }
176
+ usedNames.add(candidate);
177
+ return candidate || `Sheet${index + 1}`;
178
+ }
179
+ function safeSheetName(name, index) {
180
+ return name.replace(/[\\/:?*\[\]]/g, ' ').trim().slice(0, 31) || `Sheet${index + 1}`;
181
+ }
182
+ function getCell(sheet, row, column) {
183
+ const value = sheet.cellData?.[String(row)]?.[String(column)];
184
+ if (typeof value === 'object' && value !== null)
185
+ return value;
186
+ return { v: value };
187
+ }
188
+ function usedBounds(sheet) {
189
+ let endRow = -1;
190
+ let endColumn = -1;
191
+ for (const [rowKey, row] of Object.entries(sheet.cellData ?? {})) {
192
+ const rowNumber = Number(rowKey);
193
+ if (!Number.isInteger(rowNumber) || rowNumber < 0)
194
+ continue;
195
+ for (const columnKey of Object.keys(row)) {
196
+ const columnNumber = Number(columnKey);
197
+ if (!Number.isInteger(columnNumber) || columnNumber < 0)
198
+ continue;
199
+ endRow = Math.max(endRow, rowNumber);
200
+ endColumn = Math.max(endColumn, columnNumber);
201
+ }
202
+ }
203
+ return { endRow: Math.max(0, endRow), endColumn: Math.max(0, endColumn) };
204
+ }
205
+ function displayCellValue(cell) {
206
+ if (cell.f !== undefined && cell.v === undefined)
207
+ return `=${cell.f.replace(/^=/, '')}`;
208
+ return cell.v ?? '';
209
+ }
210
+ function normalizeImportedValue(value) {
211
+ return value instanceof Date ? value.toISOString() : value ?? null;
212
+ }
213
+ function xlsxStyleToUniver(value, numberFormat) {
214
+ const source = asRecord(value);
215
+ const font = asRecord(source.font);
216
+ const fill = asRecord(source.fill);
217
+ const alignment = asRecord(source.alignment);
218
+ const style = {};
219
+ if (typeof font.name === 'string' && font.name.length > 0)
220
+ style.ff = font.name;
221
+ if (typeof font.sz === 'number' && Number.isFinite(font.sz))
222
+ style.fs = font.sz;
223
+ if (font.bold === true)
224
+ style.bl = true;
225
+ if (font.italic === true)
226
+ style.it = true;
227
+ if (font.underline === true || font.underline === 'single')
228
+ style.ul = true;
229
+ if (font.strike === true)
230
+ style.st = true;
231
+ const fontColor = colorValue(font.color);
232
+ if (fontColor !== undefined)
233
+ style.cl = fontColor;
234
+ const fillColor = colorValue(fill.fgColor ?? fill.bgColor);
235
+ if (fillColor !== undefined && fill.patternType !== 'none')
236
+ style.bg = fillColor;
237
+ if (alignment.horizontal === 'left')
238
+ style.ht = 1;
239
+ else if (alignment.horizontal === 'center' || alignment.horizontal === 'centerContinuous')
240
+ style.ht = 2;
241
+ else if (alignment.horizontal === 'right')
242
+ style.ht = 3;
243
+ if (alignment.vertical === 'top')
244
+ style.vt = 1;
245
+ else if (alignment.vertical === 'center')
246
+ style.vt = 2;
247
+ else if (alignment.vertical === 'bottom')
248
+ style.vt = 3;
249
+ if (typeof alignment.textRotation === 'number' && Number.isFinite(alignment.textRotation))
250
+ style.tr = alignment.textRotation;
251
+ if (typeof numberFormat === 'string' && numberFormat.length > 0 && numberFormat !== 'General')
252
+ style.n = numberFormat;
253
+ return style;
254
+ }
255
+ function resolveCellStyle(root, cell) {
256
+ if (typeof cell.s === 'string') {
257
+ const style = root.styles?.[cell.s];
258
+ return style !== undefined ? style : undefined;
259
+ }
260
+ return cell.s !== null && typeof cell.s === 'object' ? cell.s : undefined;
261
+ }
262
+ function univerStyleToXlsx(style) {
263
+ const font = {};
264
+ if (typeof style.ff === 'string')
265
+ font.name = style.ff;
266
+ if (typeof style.fs === 'number')
267
+ font.sz = style.fs;
268
+ if (style.bl !== undefined)
269
+ font.bold = style.bl;
270
+ if (style.it !== undefined)
271
+ font.italic = style.it;
272
+ if (style.ul !== undefined)
273
+ font.underline = style.ul ? 'single' : undefined;
274
+ if (style.st !== undefined)
275
+ font.strike = style.st;
276
+ const fontColor = colorValue(style.cl);
277
+ if (fontColor !== undefined)
278
+ font.color = { rgb: toArgb(fontColor) };
279
+ const fillColor = colorValue(style.bg);
280
+ const fill = fillColor === undefined ? undefined : { patternType: 'solid', fgColor: { rgb: toArgb(fillColor) } };
281
+ const alignment = {};
282
+ if (style.ht === 1)
283
+ alignment.horizontal = 'left';
284
+ else if (style.ht === 2)
285
+ alignment.horizontal = 'center';
286
+ else if (style.ht === 3)
287
+ alignment.horizontal = 'right';
288
+ if (style.vt === 1)
289
+ alignment.vertical = 'top';
290
+ else if (style.vt === 2)
291
+ alignment.vertical = 'center';
292
+ else if (style.vt === 3)
293
+ alignment.vertical = 'bottom';
294
+ if (style.tr !== undefined)
295
+ alignment.textRotation = style.tr;
296
+ return {
297
+ ...(Object.keys(font).length > 0 ? { font } : {}),
298
+ ...(fill === undefined ? {} : { fill }),
299
+ ...(Object.keys(alignment).length > 0 ? { alignment } : {}),
300
+ };
301
+ }
302
+ function asRecord(value) {
303
+ return value !== null && typeof value === 'object' && !Array.isArray(value) ? value : {};
304
+ }
305
+ function colorValue(value) {
306
+ const record = asRecord(value);
307
+ const raw = typeof value === 'string' ? value : typeof record.rgb === 'string' ? record.rgb : undefined;
308
+ if (raw === undefined || raw.length === 0)
309
+ return undefined;
310
+ const normalized = raw.replace(/^#/, '');
311
+ if (!/^[0-9a-fA-F]{6}([0-9a-fA-F]{2})?$/.test(normalized))
312
+ return raw;
313
+ return `#${normalized.length === 8 ? normalized.slice(2) : normalized}`;
314
+ }
315
+ function toArgb(value) {
316
+ const normalized = value.replace(/^#/, '');
317
+ return normalized.length === 6 ? `FF${normalized}` : normalized;
318
+ }
319
+ function stableStyleSignature(style) {
320
+ return JSON.stringify(Object.entries(style).sort(([left], [right]) => left.localeCompare(right)));
321
+ }
322
+ function cellType(value) {
323
+ if (typeof value === 'number')
324
+ return 'n';
325
+ if (typeof value === 'boolean')
326
+ return 'b';
327
+ if (value instanceof Date)
328
+ return 'd';
329
+ return 's';
330
+ }
331
+ function isRange(value) {
332
+ if (typeof value !== 'object' || value === null)
333
+ return false;
334
+ const range = value;
335
+ return ['startRow', 'startColumn', 'endRow', 'endColumn'].every(key => typeof range[key] === 'number');
336
+ }
337
+ function dimensionSize(value, key) {
338
+ if (typeof value !== 'object' || value === null)
339
+ return undefined;
340
+ const size = value[key];
341
+ return typeof size === 'number' && Number.isFinite(size) ? size : undefined;
342
+ }
343
+ function dimensionArray(data, sourceKey, targetKey) {
344
+ const indexes = Object.keys(data).map(Number).filter(Number.isInteger);
345
+ const result = [];
346
+ for (const index of indexes) {
347
+ const value = data[String(index)];
348
+ result[index] = { ...(typeof value === 'object' && value !== null ? value : {}), [targetKey]: dimensionSize(value, sourceKey) };
349
+ }
350
+ return result;
351
+ }
352
+ function escapeCsv(value) {
353
+ const raw = value === null || value === undefined ? '' : String(value);
354
+ // Prevent formula injection when a CSV is opened by spreadsheet software.
355
+ // The apostrophe is visible only as a safety marker in Excel/Sheets.
356
+ const text = /^[=+\-@]/.test(raw) ? `'${raw}` : raw;
357
+ return /[",\n\r]/.test(text) ? `"${text.replace(/"/g, '""')}"` : text;
358
+ }
359
+ function safeFilename(value) {
360
+ return value.replace(/[\\/:*?"<>|]/g, '-').trim() || 'workbook';
361
+ }
362
+ export function downloadBlob(blob, filename) {
363
+ const url = URL.createObjectURL(blob);
364
+ const anchor = document.createElement('a');
365
+ anchor.href = url;
366
+ anchor.download = filename;
367
+ document.body.append(anchor);
368
+ anchor.click();
369
+ anchor.remove();
370
+ window.setTimeout(() => URL.revokeObjectURL(url), 0);
371
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,19 @@
1
+ /**
2
+ * XLSX import worker. SheetJS parsing is intentionally kept off the Univer
3
+ * interaction thread; the node half serves this file as a static asset.
4
+ */
5
+ import { readWorkbookXlsx } from "./xlsx-export.js";
6
+ const workerScope = globalThis;
7
+ workerScope.onmessage = event => {
8
+ try {
9
+ const request = event.data;
10
+ if (request === undefined || !(request.data instanceof ArrayBuffer)) {
11
+ throw new Error('导入请求数据无效');
12
+ }
13
+ const snapshot = readWorkbookXlsx(request.data, request.filename ?? 'workbook');
14
+ workerScope.postMessage({ ok: true, snapshot });
15
+ }
16
+ catch (error) {
17
+ workerScope.postMessage({ ok: false, error: error instanceof Error ? error.message : String(error) });
18
+ }
19
+ };