wendang-react 0.6.3 → 0.6.4
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/NOTICE.md +1 -1
- package/README.md +105 -0
- package/dist/bindings/yjs.js +1 -5
- package/dist/chunks/AnchoredPanel-C7jMoPze.js +1 -0
- package/dist/chunks/DocumentExportMenu-CUMsgq3w.js +2 -0
- package/dist/chunks/Dropdown-D98tXfe0.js +3 -0
- package/dist/chunks/MindMapCanvas-CVXQXNOg.js +163 -0
- package/dist/chunks/MindMapViewer-BI8zbQM1.js +13 -0
- package/dist/chunks/SpreadsheetViewer-CoQ4VIgj.js +23 -0
- package/dist/chunks/code-highlight-BmaqTe1m.js +1 -30
- package/dist/chunks/code-highlight-engine-BFDzDPzy.js +1 -40
- package/dist/chunks/comment-hint-BhUxKjKK.js +14 -0
- package/dist/chunks/composition-state-Bl-U1R_2.js +1 -40
- package/dist/chunks/extensions-C1fCBnEs.js +14 -0
- package/dist/chunks/fuzzy-match-DYQR-4w2.js +1 -89
- package/dist/chunks/hooks-C53Dp0pr.js +1 -35
- package/dist/chunks/i18n-B0kCsIjc.js +2 -0
- package/dist/chunks/index-COeA2QcQ.js +15 -0
- package/dist/chunks/katex-WjrodtTU.js +1 -71
- package/dist/chunks/locale-DWpIJ_9X.js +1 -0
- package/dist/chunks/mind-map-controller-Ce76mETT.js +1 -0
- package/dist/chunks/mind-map-delete-CVsxdXfs.js +1 -31
- package/dist/chunks/mind-map-input-CEWRz_t6.js +1 -43
- package/dist/chunks/mind-topic-text-Bn1waxff.js +31 -0
- package/dist/chunks/popover-placement-D3xVYdkt.js +1 -47
- package/dist/chunks/worksheet-engine-c84sdD4N.js +1 -0
- package/dist/chunks/worksheet-preview-DsDVWxIM.js +1 -129
- package/dist/document/viewer.js +30 -289
- package/dist/document.js +120 -3811
- package/dist/export/json.js +1 -5
- package/dist/export/markdown.js +1 -2
- package/dist/export/mindmap.js +1 -2
- package/dist/export/pdf.js +1 -6
- package/dist/export/word.js +1 -2
- package/dist/export.js +1 -2
- package/dist/i18n.js +1 -0
- package/dist/index.js +1 -8
- package/dist/locales/en-US.js +1 -0
- package/dist/locales/es-ES.js +1 -0
- package/dist/locales/ja-JP.js +1 -0
- package/dist/locales/ko-KR.js +1 -0
- package/dist/locales/zh-CN.js +1 -0
- package/dist/locales/zh-TW.js +1 -0
- package/dist/mindmap/viewer.js +1 -6
- package/dist/mindmap.js +3 -123
- package/dist/shared.js +1 -52
- package/dist/spreadsheet/viewer.js +1 -5
- package/dist/spreadsheet/xlsx.js +1 -299
- package/dist/spreadsheet.js +2 -120
- package/dist/styles/callout.css +1 -34
- package/dist/styles/code-block.css +1 -58
- package/dist/styles/content-style.css +1 -619
- package/dist/styles/content-tokens.css +1 -29
- package/dist/styles/editor-interaction.css +1 -621
- package/dist/styles/file-video.css +1 -12
- package/dist/styles/image-preview.css +1 -103
- package/dist/styles/mind-map-block.css +1 -14
- package/dist/styles/mind-map-canvas.css +1 -80
- package/dist/styles/mind-map-comments.css +1 -93
- package/dist/styles/mind-map-details.css +1 -7
- package/dist/styles/mind-map-preview.css +1 -7
- package/dist/styles/mind-map-topic.css +1 -112
- package/dist/styles/page-picker.css +1 -47
- package/dist/styles/renderer.css +1 -45
- package/dist/styles/spreadsheet-editor.css +1 -3
- package/dist/styles/tokens.css +1 -142
- package/dist/styles/video-dialog.css +1 -41
- package/dist/styles/video-embed.css +1 -35
- package/dist/styles.css +1 -2655
- package/dist/types/editor/BlockAffordance.d.ts +5 -2
- package/dist/types/editor/CalloutView.d.ts +2 -1
- package/dist/types/editor/ImagePreview.d.ts +1 -1
- package/dist/types/editor/PagePicker.d.ts +1 -1
- package/dist/types/editor/extensions.d.ts +4 -1
- package/dist/types/engine/editor/block-commands.d.ts +1 -1
- package/dist/types/engine/editor/block-menu-hover.d.ts +16 -0
- package/dist/types/engine/editor/extensions/locale.d.ts +3 -0
- package/dist/types/engine/editor/nodes/image-nodeview.d.ts +1 -1
- package/dist/types/engine/host.d.ts +60 -2
- package/dist/types/engine/renderer/attachments.d.ts +3 -3
- package/dist/types/engine/shared/video-feedback.d.ts +1 -1
- package/dist/types/engine/worksheets/worksheet-engine.d.ts +1 -0
- package/dist/types/engine/worksheets/worksheet-xlsx.d.ts +6 -1
- package/dist/types/host-types.d.ts +2 -60
- package/dist/types/host.d.ts +8 -1
- package/dist/types/i18n.d.ts +3 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/locales/en-US.d.ts +1 -0
- package/dist/types/locales/es-ES.d.ts +1 -0
- package/dist/types/locales/ja-JP.d.ts +1 -0
- package/dist/types/locales/ko-KR.d.ts +1 -0
- package/dist/types/locales/zh-CN.d.ts +1 -0
- package/dist/types/locales/zh-TW.d.ts +1 -0
- package/dist/types/spreadsheet/xlsx.d.ts +1 -1
- package/dist/types/wui/Dropdown.d.ts +2 -1
- package/dist/types/wui/index.d.ts +2 -1
- package/integrity.json +3135 -0
- package/package.json +15 -5
- package/verify-integrity.mjs +138 -0
- package/dist/chunks/AnchoredPanel-Cv4RURwF.js +0 -68
- package/dist/chunks/DocumentExportMenu-BrGipZ59.js +0 -75
- package/dist/chunks/MindMapCanvas-tkFBBs4g.js +0 -2090
- package/dist/chunks/MindMapViewer-DJrryb2Y.js +0 -180
- package/dist/chunks/SpreadsheetViewer-DxCxIUx_.js +0 -163
- package/dist/chunks/comment-hint-B9qcrqvn.js +0 -296
- package/dist/chunks/extensions-ByORRoRa.js +0 -4210
- package/dist/chunks/host-C-V688Rq.js +0 -197
- package/dist/chunks/index-DdfMnva8.js +0 -726
- package/dist/chunks/mind-map-controller-B6SxK3GZ.js +0 -479
- package/dist/chunks/mind-topic-text-DSyb95vL.js +0 -446
- package/dist/chunks/nodes-iKqTGr_N.js +0 -291
- package/dist/chunks/worksheet-engine-TJ54m0KC.js +0 -125
- package/third-party-notices/wendang-export@0.6.0-NOTICE.md.txt +0 -51
- package/third-party-notices/wendang-export@0.6.1-LICENSE.txt +0 -21
- package/third-party-notices/wendang-export@0.6.2-LICENSE.txt +0 -21
- package/third-party-notices/wendang-export@0.6.2-NOTICE.md.txt +0 -70
- /package/third-party-notices/{wendang-export@0.6.0-LICENSE.txt → wendang-export@0.6.3-LICENSE.txt} +0 -0
- /package/third-party-notices/{wendang-export@0.6.1-NOTICE.md.txt → wendang-export@0.6.3-NOTICE.md.txt} +0 -0
package/dist/export/json.js
CHANGED
package/dist/export/markdown.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
export * from "wendang-export/markdown";
|
|
1
|
+
"use client";export*from"wendang-export/markdown";
|
package/dist/export/mindmap.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
export * from "wendang-export/mindmap";
|
|
1
|
+
"use client";export*from"wendang-export/mindmap";
|
package/dist/export/pdf.js
CHANGED
|
@@ -1,6 +1 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
export * from "wendang-export/pdf";
|
|
3
|
-
import { defaultPdfFontUrl } from "wendang-export/font";
|
|
4
|
-
export {
|
|
5
|
-
defaultPdfFontUrl
|
|
6
|
-
};
|
|
1
|
+
"use client";export*from"wendang-export/pdf";import{defaultPdfFontUrl as e}from"wendang-export/font";export{e as defaultPdfFontUrl};
|
package/dist/export/word.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
export * from "wendang-export/word";
|
|
1
|
+
"use client";export*from"wendang-export/word";
|
package/dist/export.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
export * from "wendang-export";
|
|
1
|
+
"use client";export*from"wendang-export";
|
package/dist/i18n.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import"react";import{c as n}from"./chunks/i18n-B0kCsIjc.js";import{createI18n as r}from"wendang/i18n";export{r as createI18n,n as useI18n};
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { C, u, a, b } from "./chunks/host-C-V688Rq.js";
|
|
3
|
-
export {
|
|
4
|
-
C as ContentProvider,
|
|
5
|
-
u as unavailableAttachment,
|
|
6
|
-
a as useContentContext,
|
|
7
|
-
b as useContentHost
|
|
8
|
-
};
|
|
1
|
+
"use client";import{C as t,u as e,a as n,b as s,c as a}from"./chunks/i18n-B0kCsIjc.js";export{t as ContentProvider,e as unavailableAttachment,n as useContentContext,s as useContentHost,a as useI18n};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{default as e}from"wendang/locales/en-US";export{e as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{default as e}from"wendang/locales/es-ES";export{e as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{default as a}from"wendang/locales/ja-JP";export{a as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{default as e}from"wendang/locales/ko-KR";export{e as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{default as e}from"wendang/locales/zh-CN";export{e as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{default as e}from"wendang/locales/zh-TW";export{e as default};
|
package/dist/mindmap/viewer.js
CHANGED
package/dist/mindmap.js
CHANGED
|
@@ -1,123 +1,3 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import StarterKit from "@tiptap/starter-kit";
|
|
5
|
-
import { forwardRef, useRef, useState, useEffect, useImperativeHandle } from "react";
|
|
6
|
-
import { createMindMap, readMindMap } from "wendang/mindmap";
|
|
7
|
-
import { T as TextStyle, H as Highlight, M as MindMap, a as MindMapTopic, b as MindMapDescription, c as MindMapNote, d as MindMapRelation } from "./chunks/nodes-iKqTGr_N.js";
|
|
8
|
-
import { c as createMindMapController } from "./chunks/mind-map-controller-B6SxK3GZ.js";
|
|
9
|
-
import { b as useContentHost, u as unavailableAttachment } from "./chunks/host-C-V688Rq.js";
|
|
10
|
-
import { u as useLatest, a as useReady } from "./chunks/hooks-C53Dp0pr.js";
|
|
11
|
-
import { MindMapCanvas } from "./chunks/MindMapCanvas-tkFBBs4g.js";
|
|
12
|
-
const MindMapEditor = forwardRef(function MindMapEditor2(props, ref) {
|
|
13
|
-
var _a, _b, _c;
|
|
14
|
-
const latest = useLatest(props), host = useContentHost(), hostRef = useLatest(host), mount = useRef(null);
|
|
15
|
-
const [controller, setController] = useState(null), editor = useRef(null), [error, setError] = useState("");
|
|
16
|
-
const emitted = useRef(null), initial = useRef(props.value ?? props.defaultValue ?? createMindMap()), ready = useReady();
|
|
17
|
-
useEffect(() => {
|
|
18
|
-
var _a2, _b2;
|
|
19
|
-
if (!readMindMap(initial.current)) {
|
|
20
|
-
setError("思维导图格式无效");
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
const ed = new Editor({
|
|
24
|
-
element: mount.current,
|
|
25
|
-
editable: !latest.current.disabled,
|
|
26
|
-
extensions: [StarterKit.configure({ trailingNode: false }), TextStyle, Highlight, MindMap, MindMapTopic, MindMapDescription, MindMapNote, MindMapRelation],
|
|
27
|
-
content: { type: "doc", content: [latest.current.value ?? initial.current] },
|
|
28
|
-
onUpdate: ({ editor: editor2 }) => {
|
|
29
|
-
var _a3, _b3, _c2;
|
|
30
|
-
emitted.current = (_a3 = editor2.getJSON().content) == null ? void 0 : _a3[0];
|
|
31
|
-
initial.current = emitted.current;
|
|
32
|
-
(_c2 = (_b3 = latest.current).onChange) == null ? void 0 : _c2.call(_b3, emitted.current);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
editor.current = ed;
|
|
36
|
-
const control = createMindMapController(ed, () => 0, {
|
|
37
|
-
get pageId() {
|
|
38
|
-
return latest.current.resourceId;
|
|
39
|
-
},
|
|
40
|
-
canComment: () => !!latest.current.canComment && !!hostRef.current.comments,
|
|
41
|
-
canExport: () => !!latest.current.allowExport,
|
|
42
|
-
status: () => latest.current.saveStatus ?? "",
|
|
43
|
-
fetchAttachment: (id) => {
|
|
44
|
-
var _a3;
|
|
45
|
-
return (((_a3 = hostRef.current.attachments) == null ? void 0 : _a3.fetch) ?? unavailableAttachment)(id);
|
|
46
|
-
},
|
|
47
|
-
get uploadImage() {
|
|
48
|
-
var _a3;
|
|
49
|
-
return (_a3 = hostRef.current.attachments) == null ? void 0 : _a3.uploadImage;
|
|
50
|
-
},
|
|
51
|
-
awareness: latest.current.collabAwareness,
|
|
52
|
-
viewState: latest.current.viewState
|
|
53
|
-
});
|
|
54
|
-
setController(control);
|
|
55
|
-
ready.markReady();
|
|
56
|
-
(_b2 = (_a2 = latest.current).onReady) == null ? void 0 : _b2.call(_a2);
|
|
57
|
-
return () => {
|
|
58
|
-
control.dispose();
|
|
59
|
-
ed.destroy();
|
|
60
|
-
editor.current = null;
|
|
61
|
-
};
|
|
62
|
-
}, [(_b = (_a = props.value) == null ? void 0 : _a.attrs) == null ? void 0 : _b.id, props.collabAwareness, props.viewState]);
|
|
63
|
-
useEffect(() => {
|
|
64
|
-
const ed = editor.current;
|
|
65
|
-
if (ed) {
|
|
66
|
-
ed.setEditable(!props.disabled, false);
|
|
67
|
-
ed.view.dispatch(ed.state.tr.setMeta("content-capabilities", true));
|
|
68
|
-
}
|
|
69
|
-
}, [props.disabled]);
|
|
70
|
-
useEffect(() => {
|
|
71
|
-
var _a2, _b2;
|
|
72
|
-
if (!props.value || props.value === emitted.current || !editor.current) return;
|
|
73
|
-
if (!readMindMap(props.value)) {
|
|
74
|
-
(_b2 = (_a2 = latest.current).onError) == null ? void 0 : _b2.call(_a2, new Error("思维导图格式无效"));
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
editor.current.commands.setContent({ type: "doc", content: [props.value] }, { emitUpdate: false });
|
|
78
|
-
}, [props.value]);
|
|
79
|
-
const snapshot = () => {
|
|
80
|
-
var _a2, _b2;
|
|
81
|
-
return ((_b2 = (_a2 = editor.current) == null ? void 0 : _a2.getJSON().content) == null ? void 0 : _b2[0]) ?? latest.current.value ?? initial.current;
|
|
82
|
-
};
|
|
83
|
-
useImperativeHandle(ref, () => ({
|
|
84
|
-
isReady: ready.isReady,
|
|
85
|
-
whenReady: ready.whenReady,
|
|
86
|
-
getSnapshot: snapshot,
|
|
87
|
-
async prepareSnapshot() {
|
|
88
|
-
if (!editor.current || !controller || controller.hasActiveText()) throw new Error("请先完成主题输入");
|
|
89
|
-
return snapshot();
|
|
90
|
-
},
|
|
91
|
-
undo: () => (controller == null ? void 0 : controller.undo()) ?? false,
|
|
92
|
-
redo: () => (controller == null ? void 0 : controller.redo()) ?? false,
|
|
93
|
-
focus: () => {
|
|
94
|
-
var _a2, _b2, _c2;
|
|
95
|
-
return (_c2 = (_b2 = (_a2 = mount.current) == null ? void 0 : _a2.parentElement) == null ? void 0 : _b2.querySelector('[aria-label="思维导图画布"]')) == null ? void 0 : _c2.focus();
|
|
96
|
-
}
|
|
97
|
-
}));
|
|
98
|
-
const model = readMindMap(props.value ?? initial.current);
|
|
99
|
-
return /* @__PURE__ */ jsxs("section", { "aria-label": "思维导图编辑器", className: "wr-mind-editor", children: [
|
|
100
|
-
/* @__PURE__ */ jsx("div", { ref: mount, hidden: true, "aria-hidden": "true" }),
|
|
101
|
-
error && /* @__PURE__ */ jsx("p", { role: "alert", children: error }),
|
|
102
|
-
controller && model && ((_c = controller.snapshot()) == null ? void 0 : _c.id) === model.id && /* @__PURE__ */ jsx(
|
|
103
|
-
MindMapCanvas,
|
|
104
|
-
{
|
|
105
|
-
inline: true,
|
|
106
|
-
model,
|
|
107
|
-
controller,
|
|
108
|
-
allowExport: props.allowExport,
|
|
109
|
-
showSaveHint: props.showSaveHint,
|
|
110
|
-
saveStatus: props.saveStatus,
|
|
111
|
-
pageId: props.resourceId,
|
|
112
|
-
canComment: props.canComment,
|
|
113
|
-
openComments: props.openComments,
|
|
114
|
-
onCommentsChanged: props.onCommentsChanged
|
|
115
|
-
},
|
|
116
|
-
model.id
|
|
117
|
-
)
|
|
118
|
-
] });
|
|
119
|
-
});
|
|
120
|
-
export {
|
|
121
|
-
MindMapEditor,
|
|
122
|
-
createMindMapController
|
|
123
|
-
};
|
|
1
|
+
"use client";import{jsxs as e,jsx as t}from"react/jsx-runtime";import{c as r,b as n,u as a}from"./chunks/i18n-B0kCsIjc.js";import{Editor as o}from"@tiptap/core";import u from"@tiptap/starter-kit";import{T as l,H as c,M as s,a as i,b as d,c as m,d as p,l as v}from"./chunks/locale-DWpIJ_9X.js";import{forwardRef as h,useRef as f,useState as w,useEffect as g,useImperativeHandle as C}from"react";import{createMindMap as S,readMindMap as b}from"wendang/mindmap";import{c as y}from"./chunks/mind-map-controller-Ce76mETT.js";import{u as E,a as k}from"./chunks/hooks-C53Dp0pr.js";import{MindMapCanvas as x}from"./chunks/MindMapCanvas-CVXQXNOg.js";const I=h(function MindMapEditor2(h,I){var j,M,R;const N=r(),A=N.text,T=E(h),H=n(),J=E(H),O=f(null),[X,D]=w(null),U=f(null),[V,q]=w(""),B=f(null),Q=f(h.value??h.defaultValue??S()),W=k();g(()=>{var e,t;if(!b(Q.current))return void q(A("思维导图格式无效"));const r=new o({element:O.current,editable:!T.current.disabled,extensions:[v(N),u.configure({trailingNode:!1}),l,c,s,i,d,m,p],content:{type:"doc",content:[T.current.value??Q.current]},onUpdate:({editor:e})=>{var t,r,n;B.current=null==(t=e.getJSON().content)?void 0:t[0],Q.current=B.current,null==(n=(r=T.current).onChange)||n.call(r,B.current)}});U.current=r;const n=y(r,()=>0,{get pageId(){return T.current.resourceId},canComment:()=>!!T.current.canComment&&!!J.current.comments,canExport:()=>!!T.current.allowExport,status:()=>T.current.saveStatus??"",fetchAttachment:e=>{var t;return((null==(t=J.current.attachments)?void 0:t.fetch)??a)(e)},get uploadImage(){var e;return null==(e=J.current.attachments)?void 0:e.uploadImage},awareness:T.current.collabAwareness,viewState:T.current.viewState});return D(n),W.markReady(),null==(t=(e=T.current).onReady)||t.call(e),()=>{n.dispose(),r.destroy(),U.current=null}},[null==(M=null==(j=h.value)?void 0:j.attrs)?void 0:M.id,h.collabAwareness,h.viewState]),g(()=>{const e=U.current;e&&(e.setEditable(!h.disabled,!1),e.view.dispatch(e.state.tr.setMeta("content-capabilities",!0)))},[h.disabled]),g(()=>{var e,t;h.value&&h.value!==B.current&&U.current&&(b(h.value)?U.current.commands.setContent({type:"doc",content:[h.value]},{emitUpdate:!1}):null==(t=(e=T.current).onError)||t.call(e,new Error(A("思维导图格式无效"))))},[h.value]);const snapshot=()=>{var e,t;return(null==(t=null==(e=U.current)?void 0:e.getJSON().content)?void 0:t[0])??T.current.value??Q.current};C(I,()=>({isReady:W.isReady,whenReady:W.whenReady,getSnapshot:snapshot,async prepareSnapshot(){if(!U.current||!X||X.hasActiveText())throw new Error(A("请先完成主题输入"));return snapshot()},undo:()=>(null==X?void 0:X.undo())??!1,redo:()=>(null==X?void 0:X.redo())??!1,focus:()=>{var e,t,r;return null==(r=null==(t=null==(e=O.current)?void 0:e.parentElement)?void 0:t.querySelector(".mind-canvas-stage"))?void 0:r.focus()}}));const _=b(h.value??Q.current);/* @__PURE__ */
|
|
2
|
+
return e("section",{"aria-label":A("思维导图编辑器"),className:"wr-mind-editor",children:[
|
|
3
|
+
/* @__PURE__ */t("div",{ref:O,hidden:!0,"aria-hidden":"true"}),V&&/* @__PURE__ */t("p",{role:"alert",children:V}),X&&_&&(null==(R=X.snapshot())?void 0:R.id)===_.id&&/* @__PURE__ */t(x,{inline:!0,model:_,controller:X,allowExport:h.allowExport,showSaveHint:h.showSaveHint,saveStatus:h.saveStatus,pageId:h.resourceId,canComment:h.canComment,openComments:h.openComments,onCommentsChanged:h.onCommentsChanged},_.id)]})});export{I as MindMapEditor,y as createMindMapController};
|
package/dist/shared.js
CHANGED
|
@@ -1,52 +1 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
export * from "wendang/shared";
|
|
3
|
-
import { M, c, e } from "./chunks/code-highlight-BmaqTe1m.js";
|
|
4
|
-
import { highlightCode } from "./chunks/code-highlight-engine-BFDzDPzy.js";
|
|
5
|
-
import { c as c2, m, p, r } from "./chunks/fuzzy-match-DYQR-4w2.js";
|
|
6
|
-
import { I, b, e as e2, i, r as r2, s } from "./chunks/composition-state-Bl-U1R_2.js";
|
|
7
|
-
import { A, a, b as b2, p as p2 } from "./chunks/popover-placement-D3xVYdkt.js";
|
|
8
|
-
import { m as m2, r as r3, s as s2 } from "./chunks/mind-map-input-CEWRz_t6.js";
|
|
9
|
-
import { p as p3 } from "./chunks/mind-map-delete-CVsxdXfs.js";
|
|
10
|
-
export * from "wendang/internal/code-block";
|
|
11
|
-
export * from "wendang/internal/inline-comments";
|
|
12
|
-
function createModalStack() {
|
|
13
|
-
const entries = [];
|
|
14
|
-
return {
|
|
15
|
-
push(entry) {
|
|
16
|
-
entries.push(entry);
|
|
17
|
-
},
|
|
18
|
-
remove(entry) {
|
|
19
|
-
const index = entries.indexOf(entry);
|
|
20
|
-
if (index >= 0) entries.splice(index, 1);
|
|
21
|
-
},
|
|
22
|
-
top: () => entries.at(-1),
|
|
23
|
-
get size() {
|
|
24
|
-
return entries.length;
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
export {
|
|
29
|
-
A as ANCHORED_POPOVER_ARROW_INSET,
|
|
30
|
-
a as ANCHORED_POPOVER_GAP,
|
|
31
|
-
b2 as ANCHORED_POPOVER_VIEW_MARGIN,
|
|
32
|
-
I as IME_SETTLE_DELAY_MS,
|
|
33
|
-
M as MAX_HIGHLIGHT_LENGTH,
|
|
34
|
-
b as beginComposition,
|
|
35
|
-
c2 as clearPinyinCache,
|
|
36
|
-
c as codeTokens,
|
|
37
|
-
createModalStack,
|
|
38
|
-
e2 as endComposition,
|
|
39
|
-
e as ensureCodeHighlight,
|
|
40
|
-
highlightCode,
|
|
41
|
-
i as isComposingNow,
|
|
42
|
-
m as matchTitle,
|
|
43
|
-
m2 as mindCanvasShortcut,
|
|
44
|
-
p as pinyinIndex,
|
|
45
|
-
p2 as placeAnchoredPopover,
|
|
46
|
-
p3 as planMindTopicDeletion,
|
|
47
|
-
r as rankPages,
|
|
48
|
-
r2 as resetCompositionState,
|
|
49
|
-
r3 as resetMindZoom,
|
|
50
|
-
s2 as selectMindTopic,
|
|
51
|
-
s as shouldIgnoreForIme
|
|
52
|
-
};
|
|
1
|
+
"use client";export*from"wendang/shared";import{M as s,c as e,e as o}from"./chunks/code-highlight-BmaqTe1m.js";import{highlightCode as a}from"./chunks/code-highlight-engine-BFDzDPzy.js";import{c as n,m as t,p as i,r}from"./chunks/fuzzy-match-DYQR-4w2.js";import{I as m,b as c,e as p,i as d,r as h,s as l}from"./chunks/composition-state-Bl-U1R_2.js";import{A as u,a as g,b as _,p as f}from"./chunks/popover-placement-D3xVYdkt.js";import{m as E,r as k,s as C}from"./chunks/mind-map-input-CEWRz_t6.js";import{p as R}from"./chunks/mind-map-delete-CVsxdXfs.js";export*from"wendang/internal/code-block";export*from"wendang/internal/inline-comments";function createModalStack(){const s=[];return{push(e){s.push(e)},remove(e){const o=s.indexOf(e);o>=0&&s.splice(o,1)},top:()=>s.at(-1),get size(){return s.length}}}export{u as ANCHORED_POPOVER_ARROW_INSET,g as ANCHORED_POPOVER_GAP,_ as ANCHORED_POPOVER_VIEW_MARGIN,m as IME_SETTLE_DELAY_MS,s as MAX_HIGHLIGHT_LENGTH,c as beginComposition,n as clearPinyinCache,e as codeTokens,createModalStack,p as endComposition,o as ensureCodeHighlight,a as highlightCode,d as isComposingNow,t as matchTitle,E as mindCanvasShortcut,i as pinyinIndex,f as placeAnchoredPopover,R as planMindTopicDeletion,r as rankPages,h as resetCompositionState,k as resetMindZoom,C as selectMindTopic,l as shouldIgnoreForIme};
|
package/dist/spreadsheet/xlsx.js
CHANGED
|
@@ -1,299 +1 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import ExcelJS from "exceljs";
|
|
3
|
-
import JSZip from "jszip";
|
|
4
|
-
import { w as workbookFilters, b as cellStyleData, c as columnName, e as dateSerial, F as FILTER_RESOURCE } from "../chunks/worksheet-preview-DsDVWxIM.js";
|
|
5
|
-
import { validateWorkbook, workbookCellText, WORKBOOK_LIMITS, emptyWorkbook } from "wendang/internal/workbook";
|
|
6
|
-
const MAX_FILE_BYTES = 5 * 1024 * 1024;
|
|
7
|
-
function checkArchive(buffer) {
|
|
8
|
-
const view = new DataView(buffer);
|
|
9
|
-
let end = -1;
|
|
10
|
-
for (let i = view.byteLength - 22; i >= Math.max(0, view.byteLength - 65557); i--) {
|
|
11
|
-
if (view.getUint32(i, true) === 101010256) {
|
|
12
|
-
end = i;
|
|
13
|
-
break;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
if (end < 0) throw new Error("文件不是有效的 XLSX 工作簿");
|
|
17
|
-
const count = view.getUint16(end + 10, true);
|
|
18
|
-
let cursor = view.getUint32(end + 16, true), expanded = 0;
|
|
19
|
-
if (count > 2e3 || count === 65535 || cursor === 4294967295) throw new Error("XLSX 压缩包结构超出范围");
|
|
20
|
-
for (let i = 0; i < count; i++) {
|
|
21
|
-
if (cursor + 46 > end || view.getUint32(cursor, true) !== 33639248) throw new Error("XLSX 压缩包目录损坏");
|
|
22
|
-
const size = view.getUint32(cursor + 24, true);
|
|
23
|
-
expanded += size;
|
|
24
|
-
if (view.getUint16(cursor + 8, true) & 1 || size === 4294967295 || expanded > 20 * 1024 * 1024) {
|
|
25
|
-
throw new Error("XLSX 不支持加密或展开超过 20MB 的文件");
|
|
26
|
-
}
|
|
27
|
-
cursor += 46 + view.getUint16(cursor + 28, true) + view.getUint16(cursor + 30, true) + view.getUint16(cursor + 32, true);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
function color(value) {
|
|
31
|
-
if ((value == null ? void 0 : value.argb) && /^[\da-f]{8}$/i.test(value.argb)) return `#${value.argb.slice(2)}`;
|
|
32
|
-
return void 0;
|
|
33
|
-
}
|
|
34
|
-
const BORDER_STYLES = [
|
|
35
|
-
"",
|
|
36
|
-
"thin",
|
|
37
|
-
"hair",
|
|
38
|
-
"dotted",
|
|
39
|
-
"dashed",
|
|
40
|
-
"dashDot",
|
|
41
|
-
"dashDotDot",
|
|
42
|
-
"double",
|
|
43
|
-
"medium",
|
|
44
|
-
"mediumDashed",
|
|
45
|
-
"mediumDashDot",
|
|
46
|
-
"mediumDashDotDot",
|
|
47
|
-
"slantDashDot",
|
|
48
|
-
"thick"
|
|
49
|
-
];
|
|
50
|
-
function styleFromExcel(cell) {
|
|
51
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
|
|
52
|
-
const s = {};
|
|
53
|
-
if ((_a = cell.font) == null ? void 0 : _a.bold) s.bl = 1;
|
|
54
|
-
if ((_b = cell.font) == null ? void 0 : _b.italic) s.it = 1;
|
|
55
|
-
if ((_c = cell.font) == null ? void 0 : _c.size) s.fs = cell.font.size;
|
|
56
|
-
if ((_d = cell.font) == null ? void 0 : _d.name) s.ff = cell.font.name;
|
|
57
|
-
if ((_e = cell.font) == null ? void 0 : _e.underline) s.ul = { s: 1, t: String(cell.font.underline).startsWith("double") ? 1 : 0 };
|
|
58
|
-
if ((_f = cell.font) == null ? void 0 : _f.strike) s.st = { s: 1 };
|
|
59
|
-
const foreground = color((_g = cell.font) == null ? void 0 : _g.color);
|
|
60
|
-
if (foreground) s.cl = { rgb: foreground };
|
|
61
|
-
if (((_h = cell.fill) == null ? void 0 : _h.type) === "pattern") {
|
|
62
|
-
const background = color(cell.fill.fgColor);
|
|
63
|
-
if (background) s.bg = { rgb: background };
|
|
64
|
-
}
|
|
65
|
-
if (cell.numFmt && cell.numFmt !== "General") s.n = { pattern: cell.numFmt };
|
|
66
|
-
if ((_i = cell.alignment) == null ? void 0 : _i.horizontal) s.ht = { left: 1, center: 2, right: 3 }[cell.alignment.horizontal] ?? 1;
|
|
67
|
-
if ((_j = cell.alignment) == null ? void 0 : _j.wrapText) s.tb = 3;
|
|
68
|
-
if ((_k = cell.alignment) == null ? void 0 : _k.vertical) s.vt = { top: 1, middle: 2, bottom: 3 }[cell.alignment.vertical] ?? 1;
|
|
69
|
-
const borders = {};
|
|
70
|
-
for (const [excel, key] of [["top", "t"], ["bottom", "b"], ["left", "l"], ["right", "r"]]) {
|
|
71
|
-
const border = (_l = cell.border) == null ? void 0 : _l[excel];
|
|
72
|
-
const index = BORDER_STYLES.indexOf(border == null ? void 0 : border.style);
|
|
73
|
-
if (index > 0) borders[key] = { s: index, cl: { rgb: color(border == null ? void 0 : border.color) ?? "#000000" } };
|
|
74
|
-
}
|
|
75
|
-
if (Object.keys(borders).length) s.bd = borders;
|
|
76
|
-
return s;
|
|
77
|
-
}
|
|
78
|
-
function colNumber(letters) {
|
|
79
|
-
return Array.from(letters.toUpperCase()).reduce((n, c) => n * 26 + c.charCodeAt(0) - 64, 0) - 1;
|
|
80
|
-
}
|
|
81
|
-
async function importXlsx(file) {
|
|
82
|
-
var _a;
|
|
83
|
-
if (file.size > MAX_FILE_BYTES) throw new Error("XLSX 文件不能超过 5MB");
|
|
84
|
-
const buffer = await file.arrayBuffer();
|
|
85
|
-
checkArchive(buffer);
|
|
86
|
-
const archive = await JSZip.loadAsync(buffer);
|
|
87
|
-
const warnings = /* @__PURE__ */ new Set();
|
|
88
|
-
const paths = Object.keys(archive.files);
|
|
89
|
-
if (paths.some((name) => /vbaProject\.bin$/i.test(name))) throw new Error("不支持包含宏的文件,请先另存为不含宏的 XLSX");
|
|
90
|
-
if (paths.some((name) => /^xl\/(charts|media|drawings)\//.test(name))) warnings.add("图表、图片和绘图对象未转换。");
|
|
91
|
-
if (paths.some((name) => /^xl\/pivot/.test(name))) warnings.add("透视表与缓存未转换。");
|
|
92
|
-
if (paths.some((name) => /^xl\/externalLinks\//.test(name))) warnings.add("外部链接未转换,相关公式需在导入后核对。");
|
|
93
|
-
if (paths.some((name) => /^xl\/comments/.test(name))) warnings.add("Excel 批注未转换为工作表讨论。");
|
|
94
|
-
for (const name of paths.filter((name2) => /^xl\/(worksheets\/sheet\d+|workbook)\.xml$/.test(name2))) {
|
|
95
|
-
const xml = await archive.file(name).async("string");
|
|
96
|
-
if (/<(?:\w+:)?conditionalFormatting[\s>]/.test(xml)) warnings.add("条件格式规则未转换。");
|
|
97
|
-
if (/<(?:\w+:)?dataValidation[\s>]/.test(xml)) warnings.add("下拉选项和数据校验规则未转换。");
|
|
98
|
-
if (/<(?:\w+:)?filterColumn[\s>]/.test(xml)) warnings.add("筛选范围已保留;筛选条件未转换,隐藏行按文件当前状态保留。");
|
|
99
|
-
if (/<(?:\w+:)?definedName[\s>]/.test(xml)) warnings.add("命名区域未转换,使用名称引用的公式请核对。");
|
|
100
|
-
if (/<(?:\w+:)?hyperlink[\s>]/.test(xml)) warnings.add("超链接保留显示文字,链接目标未转换。");
|
|
101
|
-
if (/<(?:\w+:)?sheetProtection[\s>]/.test(xml)) warnings.add("Excel 工作表保护未转换;导入后以本系统页面权限为准。");
|
|
102
|
-
if (/<(?:\w+:)?pageSetup[\s>]/.test(xml)) warnings.add("打印设置未转换。");
|
|
103
|
-
}
|
|
104
|
-
const book = new ExcelJS.Workbook();
|
|
105
|
-
await book.xlsx.load(buffer);
|
|
106
|
-
if (!book.worksheets.length || book.worksheets.length > WORKBOOK_LIMITS.sheets) throw new Error("工作表页数应为 1–20");
|
|
107
|
-
const doc = emptyWorkbook(crypto.randomUUID());
|
|
108
|
-
doc.workbook.sheetOrder = [];
|
|
109
|
-
doc.workbook.sheets = {};
|
|
110
|
-
const filters = {};
|
|
111
|
-
const inspection = { sheets: [], warnings: [] };
|
|
112
|
-
let actualCells = 0;
|
|
113
|
-
if (book.properties.date1904) warnings.add("1904 日期系统已按实际日期转换为 1900 系统;公式中的日期序号常量请核对。");
|
|
114
|
-
for (const ws of book.worksheets) {
|
|
115
|
-
if (ws.rowCount > WORKBOOK_LIMITS.rows || ws.columnCount > WORKBOOK_LIMITS.columns) throw new Error("文件行列超出范围(10000 行、200 列)");
|
|
116
|
-
const id = `sheet-${ws.id}`;
|
|
117
|
-
const sheet = {
|
|
118
|
-
id,
|
|
119
|
-
name: ws.name,
|
|
120
|
-
rowCount: Math.max(100, ws.rowCount + 20),
|
|
121
|
-
columnCount: Math.max(26, ws.columnCount),
|
|
122
|
-
cellData: {},
|
|
123
|
-
rowData: {},
|
|
124
|
-
columnData: {},
|
|
125
|
-
mergeData: [],
|
|
126
|
-
hidden: ws.state === "veryHidden" ? 2 : ws.state === "hidden" ? 1 : 0,
|
|
127
|
-
freeze: { xSplit: 0, ySplit: 0, startRow: -1, startColumn: -1 }
|
|
128
|
-
};
|
|
129
|
-
sheet.rowCount = Math.min(WORKBOOK_LIMITS.rows, sheet.rowCount);
|
|
130
|
-
ws.columns.forEach((column, c) => {
|
|
131
|
-
const style = styleFromExcel(column.style ?? {});
|
|
132
|
-
if (column.width || column.hidden || Object.keys(style).length) sheet.columnData[c] = {
|
|
133
|
-
...column.width ? { w: Math.round(column.width * 7 + 5) } : {},
|
|
134
|
-
...column.hidden ? { hd: 1 } : {},
|
|
135
|
-
...Object.keys(style).length ? { s: style } : {}
|
|
136
|
-
};
|
|
137
|
-
});
|
|
138
|
-
const frozen = (_a = ws.views) == null ? void 0 : _a.find((view) => view.state === "frozen");
|
|
139
|
-
if ((frozen == null ? void 0 : frozen.state) === "frozen") sheet.freeze = {
|
|
140
|
-
xSplit: frozen.xSplit ?? 0,
|
|
141
|
-
ySplit: frozen.ySplit ?? 0,
|
|
142
|
-
startColumn: frozen.xSplit || -1,
|
|
143
|
-
startRow: frozen.ySplit || -1
|
|
144
|
-
};
|
|
145
|
-
let count = 0;
|
|
146
|
-
ws.eachRow({ includeEmpty: true }, (row, r) => {
|
|
147
|
-
const style = styleFromExcel(row);
|
|
148
|
-
if (row.height || row.hidden || Object.keys(style).length) sheet.rowData[r - 1] = {
|
|
149
|
-
...row.height ? { h: row.height * 96 / 72 } : {},
|
|
150
|
-
...row.hidden ? { hd: 1 } : {},
|
|
151
|
-
...Object.keys(style).length ? { s: style } : {}
|
|
152
|
-
};
|
|
153
|
-
row.eachCell({ includeEmpty: true }, (cell, c) => {
|
|
154
|
-
var _a2, _b, _c, _d;
|
|
155
|
-
if (cell.isMerged && cell.master.address !== cell.address) return;
|
|
156
|
-
const value = cell.value;
|
|
157
|
-
const data = {};
|
|
158
|
-
if (cell.formula) {
|
|
159
|
-
if (typeof value === "object" && value && "shareType" in value && value.shareType === "array") {
|
|
160
|
-
throw new Error("暂不支持数组公式文件,请先在 Excel 中转换后导入");
|
|
161
|
-
}
|
|
162
|
-
data.f = `=${cell.formula}`;
|
|
163
|
-
const result = cell.result;
|
|
164
|
-
if (result instanceof Date) {
|
|
165
|
-
data.v = dateSerial(result);
|
|
166
|
-
data.t = 2;
|
|
167
|
-
} else if (typeof result === "string" || typeof result === "number" || typeof result === "boolean") data.v = result;
|
|
168
|
-
else if (result && typeof result === "object" && "error" in result) {
|
|
169
|
-
data.v = String(result.error);
|
|
170
|
-
data.t = 4;
|
|
171
|
-
}
|
|
172
|
-
if (data.v === void 0) warnings.add("部分公式没有缓存结果,需在编辑器计算后保存;只读显示为待计算。");
|
|
173
|
-
if (/\[.+\]|_xlfn\.|_xlws\./i.test(cell.formula)) warnings.add("存在外部引用或扩展函数,公式兼容性需核对。");
|
|
174
|
-
} else if (value instanceof Date) {
|
|
175
|
-
data.v = dateSerial(value);
|
|
176
|
-
data.t = 2;
|
|
177
|
-
} else if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
178
|
-
data.v = value;
|
|
179
|
-
data.t = typeof value === "number" ? 2 : typeof value === "boolean" ? 3 : 1;
|
|
180
|
-
} else if (value && typeof value === "object" && "richText" in value) {
|
|
181
|
-
data.v = value.richText.map((part) => part.text).join("");
|
|
182
|
-
data.t = 1;
|
|
183
|
-
warnings.add("单元格内富文本保留文字,分段字体样式未转换。");
|
|
184
|
-
} else if (value && typeof value === "object" && "text" in value) {
|
|
185
|
-
data.v = String(value.text);
|
|
186
|
-
data.t = 1;
|
|
187
|
-
} else if (value && typeof value === "object" && "error" in value) {
|
|
188
|
-
data.v = value.error;
|
|
189
|
-
data.t = 4;
|
|
190
|
-
}
|
|
191
|
-
if ([
|
|
192
|
-
(_a2 = cell.font) == null ? void 0 : _a2.color,
|
|
193
|
-
((_b = cell.fill) == null ? void 0 : _b.type) === "pattern" ? cell.fill.fgColor : void 0,
|
|
194
|
-
...Object.values(cell.border ?? {}).map((b) => b == null ? void 0 : b.color)
|
|
195
|
-
].some((c2) => c2 && (c2.theme !== void 0 || "indexed" in c2))) {
|
|
196
|
-
warnings.add("部分主题色或索引色未转换;基础 RGB 颜色可保留。");
|
|
197
|
-
}
|
|
198
|
-
const style2 = styleFromExcel(cell);
|
|
199
|
-
if (Object.keys(style2).length) data.s = style2;
|
|
200
|
-
if (Object.keys(data).length) {
|
|
201
|
-
if (++actualCells > WORKBOOK_LIMITS.cells) throw new Error("工作簿实际单元格超过 50000 个");
|
|
202
|
-
((_c = sheet.cellData)[_d = r - 1] ?? (_c[_d] = {}))[c - 1] = data;
|
|
203
|
-
count++;
|
|
204
|
-
}
|
|
205
|
-
});
|
|
206
|
-
});
|
|
207
|
-
for (const address of ws.model.merges ?? []) {
|
|
208
|
-
const match = /^([A-Z]+)(\d+):([A-Z]+)(\d+)$/i.exec(address);
|
|
209
|
-
if (match) sheet.mergeData.push({ startRow: +match[2] - 1, endRow: +match[4] - 1, startColumn: colNumber(match[1]), endColumn: colNumber(match[3]) });
|
|
210
|
-
}
|
|
211
|
-
const autoFilter = ws.autoFilter;
|
|
212
|
-
if (autoFilter) {
|
|
213
|
-
const ref = typeof autoFilter === "string" ? autoFilter : `${typeof autoFilter.from === "string" ? autoFilter.from : `${columnName(autoFilter.from.column - 1)}${autoFilter.from.row}`}:${typeof autoFilter.to === "string" ? autoFilter.to : `${columnName(autoFilter.to.column - 1)}${autoFilter.to.row}`}`;
|
|
214
|
-
const match = /^\$?([A-Z]+)\$?(\d+):\$?([A-Z]+)\$?(\d+)$/i.exec(ref);
|
|
215
|
-
if (match) filters[id] = { ref: { startRow: +match[2] - 1, endRow: +match[4] - 1, startColumn: colNumber(match[1]), endColumn: colNumber(match[3]) } };
|
|
216
|
-
}
|
|
217
|
-
doc.workbook.sheetOrder.push(id);
|
|
218
|
-
doc.workbook.sheets[id] = sheet;
|
|
219
|
-
inspection.sheets.push({ name: ws.name, rows: ws.rowCount, columns: ws.columnCount, cells: count, hidden: sheet.hidden !== 0 });
|
|
220
|
-
}
|
|
221
|
-
doc.workbook.resources = [{ name: FILTER_RESOURCE, data: JSON.stringify(filters) }];
|
|
222
|
-
warnings.add("请保留原文件;仅对本次检查列明的基础格式与数据范围进行转换。");
|
|
223
|
-
inspection.warnings = [...warnings];
|
|
224
|
-
return { doc: validateWorkbook(doc), warnings: inspection.warnings, inspection };
|
|
225
|
-
}
|
|
226
|
-
function rgb(value) {
|
|
227
|
-
const color2 = value && typeof value === "object" ? value.rgb : void 0;
|
|
228
|
-
return typeof color2 === "string" && /^#[\da-f]{6}$/i.test(color2) ? `FF${color2.slice(1)}` : void 0;
|
|
229
|
-
}
|
|
230
|
-
async function exportXlsx(raw) {
|
|
231
|
-
var _a, _b, _c;
|
|
232
|
-
const doc = validateWorkbook(raw), book = new ExcelJS.Workbook();
|
|
233
|
-
book.calcProperties.fullCalcOnLoad = true;
|
|
234
|
-
const filters = workbookFilters(doc);
|
|
235
|
-
for (const id of doc.workbook.sheetOrder) {
|
|
236
|
-
const sheet = doc.workbook.sheets[id], ws = book.addWorksheet(sheet.name, {
|
|
237
|
-
state: sheet.hidden === 2 ? "veryHidden" : sheet.hidden === 1 ? "hidden" : "visible"
|
|
238
|
-
});
|
|
239
|
-
for (const [r, row] of Object.entries(sheet.cellData ?? {})) {
|
|
240
|
-
for (const [c, data] of Object.entries(row)) {
|
|
241
|
-
if (!data) continue;
|
|
242
|
-
const cell = ws.getCell(+r + 1, +c + 1);
|
|
243
|
-
const value = data.t === 4 ? { error: data.v } : data.v;
|
|
244
|
-
cell.value = data.f ? { formula: data.f.replace(/^=/, ""), result: value ?? void 0 } : value ?? workbookCellText(data);
|
|
245
|
-
const style = cellStyleData(doc, sheet, +r, +c);
|
|
246
|
-
if (style && typeof style === "object") {
|
|
247
|
-
cell.font = {
|
|
248
|
-
bold: style.bl === 1,
|
|
249
|
-
italic: style.it === 1,
|
|
250
|
-
...typeof style.fs === "number" ? { size: style.fs } : {},
|
|
251
|
-
...typeof style.ff === "string" ? { name: style.ff } : {},
|
|
252
|
-
...rgb(style.cl) ? { color: { argb: rgb(style.cl) } } : {},
|
|
253
|
-
...((_a = style.ul) == null ? void 0 : _a.s) === 1 ? { underline: true } : {},
|
|
254
|
-
...((_b = style.st) == null ? void 0 : _b.s) === 1 ? { strike: true } : {}
|
|
255
|
-
};
|
|
256
|
-
if (rgb(style.bg)) cell.fill = { type: "pattern", pattern: "solid", fgColor: { argb: rgb(style.bg) } };
|
|
257
|
-
const numFmt = style.n;
|
|
258
|
-
if (typeof (numFmt == null ? void 0 : numFmt.pattern) === "string") cell.numFmt = numFmt.pattern;
|
|
259
|
-
cell.alignment = {
|
|
260
|
-
horizontal: style.ht === 2 ? "center" : style.ht === 3 ? "right" : "left",
|
|
261
|
-
vertical: style.vt === 2 ? "middle" : style.vt === 3 ? "bottom" : "top",
|
|
262
|
-
wrapText: style.tb === 3
|
|
263
|
-
};
|
|
264
|
-
const borders = style.bd;
|
|
265
|
-
for (const [excel, key] of [["top", "t"], ["bottom", "b"], ["left", "l"], ["right", "r"]]) {
|
|
266
|
-
const border = borders == null ? void 0 : borders[key], borderStyle = (border == null ? void 0 : border.s) && BORDER_STYLES[border.s];
|
|
267
|
-
if (borderStyle) cell.border = { ...cell.border, [excel]: {
|
|
268
|
-
style: borderStyle,
|
|
269
|
-
color: { argb: rgb(border.cl) ?? "FF000000" }
|
|
270
|
-
} };
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
for (const [r, data] of Object.entries(sheet.rowData ?? {})) {
|
|
276
|
-
if (typeof data.h === "number") ws.getRow(+r + 1).height = data.h * 72 / 96;
|
|
277
|
-
if (data.hd === 1) {
|
|
278
|
-
const row = ws.getRow(+r + 1);
|
|
279
|
-
row.hidden = true;
|
|
280
|
-
row.height ?? (row.height = 18);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
for (const r of ((_c = filters[id]) == null ? void 0 : _c.cachedFilteredOut) ?? []) if (Number.isInteger(r) && r >= 0 && r < sheet.rowCount) ws.getRow(r + 1).hidden = true;
|
|
284
|
-
for (const [c, data] of Object.entries(sheet.columnData ?? {})) {
|
|
285
|
-
if (typeof data.w === "number") ws.getColumn(+c + 1).width = Math.max(1, (data.w - 5) / 7);
|
|
286
|
-
if (data.hd === 1) ws.getColumn(+c + 1).hidden = true;
|
|
287
|
-
}
|
|
288
|
-
const freeze = sheet.freeze;
|
|
289
|
-
if (freeze && (freeze.xSplit || freeze.ySplit)) ws.views = [{ state: "frozen", xSplit: freeze.xSplit ?? 0, ySplit: freeze.ySplit ?? 0 }];
|
|
290
|
-
const filter = filters[id];
|
|
291
|
-
if (filter == null ? void 0 : filter.ref) ws.autoFilter = `${columnName(filter.ref.startColumn)}${filter.ref.startRow + 1}:${columnName(filter.ref.endColumn)}${filter.ref.endRow + 1}`;
|
|
292
|
-
for (const range of sheet.mergeData ?? []) ws.mergeCells(range.startRow + 1, range.startColumn + 1, range.endRow + 1, range.endColumn + 1);
|
|
293
|
-
}
|
|
294
|
-
return new Uint8Array(await book.xlsx.writeBuffer());
|
|
295
|
-
}
|
|
296
|
-
export {
|
|
297
|
-
exportXlsx,
|
|
298
|
-
importXlsx
|
|
299
|
-
};
|
|
1
|
+
"use client";import t from"exceljs";import{createI18n as e}from"wendang/i18n";import o from"jszip";import{w as n,b as r,c as s,e as i,F as l}from"../chunks/worksheet-preview-DsDVWxIM.js";import{validateWorkbook as a,workbookCellText as d,WORKBOOK_LIMITS as c,emptyWorkbook as f}from"wendang/internal/workbook";function color(t){if((null==t?void 0:t.argb)&&/^[\da-f]{8}$/i.test(t.argb))return`#${t.argb.slice(2)}`}const u=["","thin","hair","dotted","dashed","dashDot","dashDotDot","double","medium","mediumDashed","mediumDashDot","mediumDashDotDot","slantDashDot","thick"];function styleFromExcel(t){var e,o,n,r,s,i,l,a,d,c,f,m;const h={};(null==(e=t.font)?void 0:e.bold)&&(h.bl=1),(null==(o=t.font)?void 0:o.italic)&&(h.it=1),(null==(n=t.font)?void 0:n.size)&&(h.fs=t.font.size),(null==(r=t.font)?void 0:r.name)&&(h.ff=t.font.name),(null==(s=t.font)?void 0:s.underline)&&(h.ul={s:1,t:String(t.font.underline).startsWith("double")?1:0}),(null==(i=t.font)?void 0:i.strike)&&(h.st={s:1});const w=color(null==(l=t.font)?void 0:l.color);if(w&&(h.cl={rgb:w}),"pattern"===(null==(a=t.fill)?void 0:a.type)){const e=color(t.fill.fgColor);e&&(h.bg={rgb:e})}t.numFmt&&"General"!==t.numFmt&&(h.n={pattern:t.numFmt}),(null==(d=t.alignment)?void 0:d.horizontal)&&(h.ht={left:1,center:2,right:3}[t.alignment.horizontal]??1),(null==(c=t.alignment)?void 0:c.wrapText)&&(h.tb=3),(null==(f=t.alignment)?void 0:f.vertical)&&(h.vt={top:1,middle:2,bottom:3}[t.alignment.vertical]??1);const g={};for(const[e,o]of[["top","t"],["bottom","b"],["left","l"],["right","r"]]){const n=null==(m=t.border)?void 0:m[e],r=u.indexOf(null==n?void 0:n.style);r>0&&(g[o]={s:r,cl:{rgb:color(null==n?void 0:n.color)??"#000000"}})}return Object.keys(g).length&&(h.bd=g),h}function colNumber(t){return Array.from(t.toUpperCase()).reduce((t,e)=>26*t+e.charCodeAt(0)-64,0)-1}async function importXlsx(n,r={}){const d=e(r.locale,r.messages);try{const e=await async function readXlsx(e){var n;if(e.size>5242880)throw new Error("XLSX 文件不能超过 5MB");const r=await e.arrayBuffer();!function checkArchive(t){const e=new DataView(t);let o=-1;for(let t=e.byteLength-22;t>=Math.max(0,e.byteLength-65557);t--)if(101010256===e.getUint32(t,!0)){o=t;break}if(o<0)throw new Error("文件不是有效的 XLSX 工作簿");const n=e.getUint16(o+10,!0);let r=e.getUint32(o+16,!0),s=0;if(n>2e3||65535===n||4294967295===r)throw new Error("XLSX 压缩包结构超出范围");for(let t=0;t<n;t++){if(r+46>o||33639248!==e.getUint32(r,!0))throw new Error("XLSX 压缩包目录损坏");const t=e.getUint32(r+24,!0);if(s+=t,1&e.getUint16(r+8,!0)||4294967295===t||s>20971520)throw new Error("XLSX 不支持加密或展开超过 20MB 的文件");r+=46+e.getUint16(r+28,!0)+e.getUint16(r+30,!0)+e.getUint16(r+32,!0)}}(r);const d=await o.loadAsync(r),u=/* @__PURE__ */new Set,m=Object.keys(d.files);if(m.some(t=>/vbaProject\.bin$/i.test(t)))throw new Error("不支持包含宏的文件,请先另存为不含宏的 XLSX");m.some(t=>/^xl\/(charts|media|drawings)\//.test(t))&&u.add("图表、图片和绘图对象未转换。"),m.some(t=>/^xl\/pivot/.test(t))&&u.add("透视表与缓存未转换。"),m.some(t=>/^xl\/externalLinks\//.test(t))&&u.add("外部链接未转换,相关公式需在导入后核对。"),m.some(t=>/^xl\/comments/.test(t))&&u.add("Excel 批注未转换为工作表讨论。");for(const t of m.filter(t=>/^xl\/(worksheets\/sheet\d+|workbook)\.xml$/.test(t))){const e=await d.file(t).async("string");/<(?:\w+:)?conditionalFormatting[\s>]/.test(e)&&u.add("条件格式规则未转换。"),/<(?:\w+:)?dataValidation[\s>]/.test(e)&&u.add("下拉选项和数据校验规则未转换。"),/<(?:\w+:)?filterColumn[\s>]/.test(e)&&u.add("筛选范围已保留;筛选条件未转换,隐藏行按文件当前状态保留。"),/<(?:\w+:)?definedName[\s>]/.test(e)&&u.add("命名区域未转换,使用名称引用的公式请核对。"),/<(?:\w+:)?hyperlink[\s>]/.test(e)&&u.add("超链接保留显示文字,链接目标未转换。"),/<(?:\w+:)?sheetProtection[\s>]/.test(e)&&u.add("Excel 工作表保护未转换;导入后以本系统页面权限为准。"),/<(?:\w+:)?pageSetup[\s>]/.test(e)&&u.add("打印设置未转换。")}const h=new t.Workbook;if(await h.xlsx.load(r),!h.worksheets.length||h.worksheets.length>c.sheets)throw new Error("工作表页数应为 1–20");const w=f(crypto.randomUUID());w.workbook.sheetOrder=[],w.workbook.sheets={};const g={},b={sheets:[],warnings:[]};let p=0;h.properties.date1904&&u.add("1904 日期系统已按实际日期转换为 1900 系统;公式中的日期序号常量请核对。");for(const t of h.worksheets){if(t.rowCount>c.rows||t.columnCount>c.columns)throw new Error("文件行列超出范围(10000 行、200 列)");const e=`sheet-${t.id}`,o={id:e,name:t.name,rowCount:Math.max(100,t.rowCount+20),columnCount:Math.max(26,t.columnCount),cellData:{},rowData:{},columnData:{},mergeData:[],hidden:"veryHidden"===t.state?2:"hidden"===t.state?1:0,freeze:{xSplit:0,ySplit:0,startRow:-1,startColumn:-1}};o.rowCount=Math.min(c.rows,o.rowCount),t.columns.forEach((t,e)=>{const n=styleFromExcel(t.style??{});(t.width||t.hidden||Object.keys(n).length)&&(o.columnData[e]={...t.width?{w:Math.round(7*t.width+5)}:{},...t.hidden?{hd:1}:{},...Object.keys(n).length?{s:n}:{}})});const r=null==(n=t.views)?void 0:n.find(t=>"frozen"===t.state);"frozen"===(null==r?void 0:r.state)&&(o.freeze={xSplit:r.xSplit??0,ySplit:r.ySplit??0,startColumn:r.xSplit||-1,startRow:r.ySplit||-1});let l=0;t.eachRow({includeEmpty:!0},(t,e)=>{const n=styleFromExcel(t);(t.height||t.hidden||Object.keys(n).length)&&(o.rowData[e-1]={...t.height?{h:96*t.height/72}:{},...t.hidden?{hd:1}:{},...Object.keys(n).length?{s:n}:{}}),t.eachCell({includeEmpty:!0},(t,n)=>{var r,s,a,d;if(t.isMerged&&t.master.address!==t.address)return;const f=t.value,m={};if(t.formula){if("object"==typeof f&&f&&"shareType"in f&&"array"===f.shareType)throw new Error("暂不支持数组公式文件,请先在 Excel 中转换后导入");m.f=`=${t.formula}`;const e=t.result;e instanceof Date?(m.v=i(e),m.t=2):"string"==typeof e||"number"==typeof e||"boolean"==typeof e?m.v=e:e&&"object"==typeof e&&"error"in e&&(m.v=String(e.error),m.t=4),void 0===m.v&&u.add("部分公式没有缓存结果,需在编辑器计算后保存;只读显示为待计算。"),/\[.+\]|_xlfn\.|_xlws\./i.test(t.formula)&&u.add("存在外部引用或扩展函数,公式兼容性需核对。")}else f instanceof Date?(m.v=i(f),m.t=2):"string"==typeof f||"number"==typeof f||"boolean"==typeof f?(m.v=f,m.t="number"==typeof f?2:"boolean"==typeof f?3:1):f&&"object"==typeof f&&"richText"in f?(m.v=f.richText.map(t=>t.text).join(""),m.t=1,u.add("单元格内富文本保留文字,分段字体样式未转换。")):f&&"object"==typeof f&&"text"in f?(m.v=String(f.text),m.t=1):f&&"object"==typeof f&&"error"in f&&(m.v=f.error,m.t=4);[null==(r=t.font)?void 0:r.color,"pattern"===(null==(s=t.fill)?void 0:s.type)?t.fill.fgColor:void 0,...Object.values(t.border??{}).map(t=>null==t?void 0:t.color)].some(t=>t&&(void 0!==t.theme||"indexed"in t))&&u.add("部分主题色或索引色未转换;基础 RGB 颜色可保留。");const h=styleFromExcel(t);if(Object.keys(h).length&&(m.s=h),Object.keys(m).length){if(++p>c.cells)throw new Error("工作簿实际单元格超过 50000 个");((a=o.cellData)[d=e-1]??(a[d]={}))[n-1]=m,l++}})});for(const e of t.model.merges??[]){const t=/^([A-Z]+)(\d+):([A-Z]+)(\d+)$/i.exec(e);t&&o.mergeData.push({startRow:+t[2]-1,endRow:+t[4]-1,startColumn:colNumber(t[1]),endColumn:colNumber(t[3])})}const a=t.autoFilter;if(a){const t="string"==typeof a?a:`${"string"==typeof a.from?a.from:`${s(a.from.column-1)}${a.from.row}`}:${"string"==typeof a.to?a.to:`${s(a.to.column-1)}${a.to.row}`}`,o=/^\$?([A-Z]+)\$?(\d+):\$?([A-Z]+)\$?(\d+)$/i.exec(t);o&&(g[e]={ref:{startRow:+o[2]-1,endRow:+o[4]-1,startColumn:colNumber(o[1]),endColumn:colNumber(o[3])}})}w.workbook.sheetOrder.push(e),w.workbook.sheets[e]=o,b.sheets.push({name:t.name,rows:t.rowCount,columns:t.columnCount,cells:l,hidden:0!==o.hidden})}return w.workbook.resources=[{name:l,data:JSON.stringify(g)}],u.add("请保留原文件;仅对本次检查列明的基础格式与数据范围进行转换。"),b.warnings=[...u],{doc:a(w),warnings:b.warnings,inspection:b}}(n),r=e.warnings.map(t=>d.text(t));return{...e,warnings:r,inspection:{...e.inspection,warnings:r}}}catch(t){if(!(t instanceof Error))throw t;const e=d.text(t.message);if(e===t.message)throw t;throw new Error(e,{cause:t})}}function rgb(t){const e=t&&"object"==typeof t?t.rgb:void 0;return"string"==typeof e&&/^#[\da-f]{6}$/i.test(e)?`FF${e.slice(1)}`:void 0}async function exportXlsx(e){var o,i,l;const c=a(e),f=new t.Workbook;f.calcProperties.fullCalcOnLoad=!0;const m=n(c);for(const t of c.workbook.sheetOrder){const e=c.workbook.sheets[t],n=f.addWorksheet(e.name,{state:2===e.hidden?"veryHidden":1===e.hidden?"hidden":"visible"});for(const[t,s]of Object.entries(e.cellData??{}))for(const[l,a]of Object.entries(s)){if(!a)continue;const s=n.getCell(+t+1,+l+1),f=4===a.t?{error:a.v}:a.v;s.value=a.f?{formula:a.f.replace(/^=/,""),result:f??void 0}:f??d(a);const m=r(c,e,+t,+l);if(m&&"object"==typeof m){s.font={bold:1===m.bl,italic:1===m.it,..."number"==typeof m.fs?{size:m.fs}:{},..."string"==typeof m.ff?{name:m.ff}:{},...rgb(m.cl)?{color:{argb:rgb(m.cl)}}:{},...1===(null==(o=m.ul)?void 0:o.s)?{underline:!0}:{},...1===(null==(i=m.st)?void 0:i.s)?{strike:!0}:{}},rgb(m.bg)&&(s.fill={type:"pattern",pattern:"solid",fgColor:{argb:rgb(m.bg)}});const t=m.n;"string"==typeof(null==t?void 0:t.pattern)&&(s.numFmt=t.pattern),s.alignment={horizontal:2===m.ht?"center":3===m.ht?"right":"left",vertical:2===m.vt?"middle":3===m.vt?"bottom":"top",wrapText:3===m.tb};const e=m.bd;for(const[t,o]of[["top","t"],["bottom","b"],["left","l"],["right","r"]]){const n=null==e?void 0:e[o],r=(null==n?void 0:n.s)&&u[n.s];r&&(s.border={...s.border,[t]:{style:r,color:{argb:rgb(n.cl)??"FF000000"}}})}}}for(const[t,o]of Object.entries(e.rowData??{}))if("number"==typeof o.h&&(n.getRow(+t+1).height=72*o.h/96),1===o.hd){const e=n.getRow(+t+1);e.hidden=!0,e.height??(e.height=18)}for(const o of(null==(l=m[t])?void 0:l.cachedFilteredOut)??[])Number.isInteger(o)&&o>=0&&o<e.rowCount&&(n.getRow(o+1).hidden=!0);for(const[t,o]of Object.entries(e.columnData??{}))"number"==typeof o.w&&(n.getColumn(+t+1).width=Math.max(1,(o.w-5)/7)),1===o.hd&&(n.getColumn(+t+1).hidden=!0);const a=e.freeze;a&&(a.xSplit||a.ySplit)&&(n.views=[{state:"frozen",xSplit:a.xSplit??0,ySplit:a.ySplit??0}]);const h=m[t];(null==h?void 0:h.ref)&&(n.autoFilter=`${s(h.ref.startColumn)}${h.ref.startRow+1}:${s(h.ref.endColumn)}${h.ref.endRow+1}`);for(const t of e.mergeData??[])n.mergeCells(t.startRow+1,t.startColumn+1,t.endRow+1,t.endColumn+1)}return new Uint8Array(await f.xlsx.writeBuffer())}export{exportXlsx,importXlsx};
|