@l1yp/file-viewer 0.1.4 → 0.1.6

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 (177) hide show
  1. package/README.md +57 -6
  2. package/dist/assets/step.worker-CfDTYOf_.js.map +1 -0
  3. package/dist/components/AnsiText.d.ts +47 -0
  4. package/dist/components/AnsiText.js +41 -0
  5. package/dist/components/AnsiText.js.map +1 -0
  6. package/dist/components/CertViewer.js +1 -1
  7. package/dist/components/CertViewer.js.map +1 -1
  8. package/dist/components/CertViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  9. package/dist/components/CodeView.js +1 -1
  10. package/dist/components/CodeView.js.map +1 -1
  11. package/dist/components/CodeView.vue_vue_type_script_setup_true_lang.js +80 -71
  12. package/dist/components/CodeView.vue_vue_type_script_setup_true_lang.js.map +1 -1
  13. package/dist/components/DocxEmbeddedFiles.js +9 -0
  14. package/dist/components/DocxEmbeddedFiles.js.map +1 -0
  15. package/dist/components/DocxEmbeddedFiles.vue.d.ts +15 -0
  16. package/dist/components/DocxEmbeddedFiles.vue_vue_type_script_setup_true_lang.js +69 -0
  17. package/dist/components/DocxEmbeddedFiles.vue_vue_type_script_setup_true_lang.js.map +1 -0
  18. package/dist/components/DocxNavigationPane.js +1 -1
  19. package/dist/components/DocxNavigationPane.js.map +1 -1
  20. package/dist/components/DocxNavigationPane.vue_vue_type_script_setup_true_lang.js.map +1 -1
  21. package/dist/components/DocxViewer.js +1 -1
  22. package/dist/components/DocxViewer.js.map +1 -1
  23. package/dist/components/DocxViewer.vue.d.ts +1 -1
  24. package/dist/components/DocxViewer.vue_vue_type_script_setup_true_lang.js +182 -50
  25. package/dist/components/DocxViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  26. package/dist/components/EplViewer.js +1 -1
  27. package/dist/components/EplViewer.js.map +1 -1
  28. package/dist/components/EplViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  29. package/dist/components/FileViewerBody.js +1 -1
  30. package/dist/components/FileViewerBody.js.map +1 -1
  31. package/dist/components/FileViewerBody.vue.d.ts +1 -0
  32. package/dist/components/FileViewerBody.vue_vue_type_script_setup_true_lang.js +292 -281
  33. package/dist/components/FileViewerBody.vue_vue_type_script_setup_true_lang.js.map +1 -1
  34. package/dist/components/FileViewerPanel.js +1 -1
  35. package/dist/components/FileViewerPanel.js.map +1 -1
  36. package/dist/components/FileViewerPanel.vue.d.ts +6 -1
  37. package/dist/components/FileViewerPanel.vue_vue_type_script_setup_true_lang.js +53 -51
  38. package/dist/components/FileViewerPanel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  39. package/dist/components/HarViewer.js +1 -1
  40. package/dist/components/HarViewer.js.map +1 -1
  41. package/dist/components/HarViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  42. package/dist/components/JksViewer.js +1 -1
  43. package/dist/components/JksViewer.js.map +1 -1
  44. package/dist/components/JksViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  45. package/dist/components/LogViewer.js +1 -1
  46. package/dist/components/LogViewer.js.map +1 -1
  47. package/dist/components/LogViewer.vue.d.ts +3 -1
  48. package/dist/components/LogViewer.vue_vue_type_script_setup_true_lang.js +284 -280
  49. package/dist/components/LogViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  50. package/dist/components/ModelViewModes.js +9 -0
  51. package/dist/components/ModelViewModes.js.map +1 -0
  52. package/dist/components/ModelViewModes.vue.d.ts +11 -0
  53. package/dist/components/ModelViewModes.vue_vue_type_script_setup_true_lang.js +49 -0
  54. package/dist/components/ModelViewModes.vue_vue_type_script_setup_true_lang.js.map +1 -0
  55. package/dist/components/ModelViewer.js +1 -1
  56. package/dist/components/ModelViewer.js.map +1 -1
  57. package/dist/components/ModelViewer.vue.d.ts +2 -1
  58. package/dist/components/ModelViewer.vue_vue_type_script_setup_true_lang.js +183 -96
  59. package/dist/components/ModelViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  60. package/dist/components/PdfNavigationPane.js +1 -1
  61. package/dist/components/PdfNavigationPane.js.map +1 -1
  62. package/dist/components/PdfNavigationPane.vue_vue_type_script_setup_true_lang.js.map +1 -1
  63. package/dist/components/PdfViewer.js +1 -1
  64. package/dist/components/PdfViewer.js.map +1 -1
  65. package/dist/components/PdfViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  66. package/dist/components/PptxNavigationPane.js +1 -1
  67. package/dist/components/PptxNavigationPane.js.map +1 -1
  68. package/dist/components/PptxNavigationPane.vue_vue_type_script_setup_true_lang.js.map +1 -1
  69. package/dist/components/PsdViewer.js +1 -1
  70. package/dist/components/PsdViewer.js.map +1 -1
  71. package/dist/components/PsdViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  72. package/dist/components/SqliteViewer.js +1 -1
  73. package/dist/components/SqliteViewer.js.map +1 -1
  74. package/dist/components/SqliteViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  75. package/dist/components/ViewerLoadError.js +9 -0
  76. package/dist/components/ViewerLoadError.js.map +1 -0
  77. package/dist/components/ViewerLoadError.vue.d.ts +17 -0
  78. package/dist/components/ViewerLoadError.vue_vue_type_script_setup_true_lang.js +58 -0
  79. package/dist/components/ViewerLoadError.vue_vue_type_script_setup_true_lang.js.map +1 -0
  80. package/dist/components/XlsxChart.js +1 -1
  81. package/dist/components/XlsxChart.js.map +1 -1
  82. package/dist/components/XlsxChart.vue_vue_type_script_setup_true_lang.js +9 -9
  83. package/dist/components/XlsxChart.vue_vue_type_script_setup_true_lang.js.map +1 -1
  84. package/dist/components/XlsxImageLayer.js +9 -0
  85. package/dist/components/XlsxImageLayer.js.map +1 -0
  86. package/dist/components/XlsxImageLayer.vue.d.ts +9 -0
  87. package/dist/components/XlsxImageLayer.vue_vue_type_script_setup_true_lang.js +46 -0
  88. package/dist/components/XlsxImageLayer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  89. package/dist/components/XlsxViewer.js +1 -1
  90. package/dist/components/XlsxViewer.js.map +1 -1
  91. package/dist/components/XlsxViewer.vue_vue_type_script_setup_true_lang.js +230 -216
  92. package/dist/components/XlsxViewer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  93. package/dist/components/epl/EplResource.js +1 -1
  94. package/dist/components/epl/EplResource.js.map +1 -1
  95. package/dist/components/epl/EplResource.vue_vue_type_script_setup_true_lang.js.map +1 -1
  96. package/dist/components/optionalViewer.d.ts +3 -2
  97. package/dist/components/optionalViewer.js +6 -3
  98. package/dist/components/optionalViewer.js.map +1 -1
  99. package/dist/composables/useFileViewer.d.ts +11 -3
  100. package/dist/composables/useFileViewer.js.map +1 -1
  101. package/dist/composables/useTeleportTheme.d.ts +7 -0
  102. package/dist/composables/useTeleportTheme.js +42 -0
  103. package/dist/composables/useTeleportTheme.js.map +1 -0
  104. package/dist/index.d.ts +1 -0
  105. package/dist/index.js +29 -28
  106. package/dist/lib/ansi.d.ts +44 -0
  107. package/dist/lib/ansi.js +224 -0
  108. package/dist/lib/ansi.js.map +1 -0
  109. package/dist/lib/cfb.d.ts +37 -0
  110. package/dist/lib/cfb.js +112 -0
  111. package/dist/lib/cfb.js.map +1 -0
  112. package/dist/lib/docxEmbeddedDom.d.ts +22 -0
  113. package/dist/lib/docxEmbeddedDom.js +128 -0
  114. package/dist/lib/docxEmbeddedDom.js.map +1 -0
  115. package/dist/lib/docxEmbeddings.d.ts +41 -0
  116. package/dist/lib/docxEmbeddings.js +226 -0
  117. package/dist/lib/docxEmbeddings.js.map +1 -0
  118. package/dist/lib/docxTheme.d.ts +6 -0
  119. package/dist/lib/docxTheme.js +64 -0
  120. package/dist/lib/docxTheme.js.map +1 -0
  121. package/dist/lib/epl/code/structures.js +82 -0
  122. package/dist/lib/epl/code/structures.js.map +1 -0
  123. package/dist/lib/epl/code/variable.js +16 -0
  124. package/dist/lib/epl/code/variable.js.map +1 -0
  125. package/dist/lib/epl/eplDocument.js +28 -22
  126. package/dist/lib/epl/eplDocument.js.map +1 -1
  127. package/dist/lib/epl/index.d.ts +2 -1
  128. package/dist/lib/epl/index.js.map +1 -1
  129. package/dist/lib/epl/sections/code.js +37 -0
  130. package/dist/lib/epl/sections/code.js.map +1 -0
  131. package/dist/lib/epl/sections/esystemInfo.js +29 -0
  132. package/dist/lib/epl/sections/esystemInfo.js.map +1 -0
  133. package/dist/lib/epl/sections/losable.js +33 -0
  134. package/dist/lib/epl/sections/losable.js.map +1 -0
  135. package/dist/lib/epl/sections/projectConfig.js +39 -0
  136. package/dist/lib/epl/sections/projectConfig.js.map +1 -0
  137. package/dist/lib/epl/sections/resource.js +84 -0
  138. package/dist/lib/epl/sections/resource.js.map +1 -0
  139. package/dist/lib/fileType.d.ts +3 -1
  140. package/dist/lib/fileType.js +150 -137
  141. package/dist/lib/fileType.js.map +1 -1
  142. package/dist/lib/modelAppearance.d.ts +7 -0
  143. package/dist/lib/modelAppearance.js +41 -0
  144. package/dist/lib/modelAppearance.js.map +1 -0
  145. package/dist/lib/msi.js +62 -154
  146. package/dist/lib/msi.js.map +1 -1
  147. package/dist/lib/olePackage.d.ts +8 -0
  148. package/dist/lib/olePackage.js +37 -0
  149. package/dist/lib/olePackage.js.map +1 -0
  150. package/dist/lib/pptxFirstSlide.d.ts +11 -0
  151. package/dist/lib/pptxFirstSlide.js +34 -0
  152. package/dist/lib/pptxFirstSlide.js.map +1 -0
  153. package/dist/lib/step.d.ts +10 -0
  154. package/dist/lib/step.js +35 -0
  155. package/dist/lib/step.js.map +1 -0
  156. package/dist/lib/step.worker.d.ts +1 -0
  157. package/dist/lib/step.worker.js +18 -0
  158. package/dist/lib/step.worker.js.map +1 -0
  159. package/dist/lib/stepObject.d.ts +4 -0
  160. package/dist/lib/stepObject.js +52 -0
  161. package/dist/lib/stepObject.js.map +1 -0
  162. package/dist/lib/stepTypes.d.ts +60 -0
  163. package/dist/lib/viewerKind.js +10 -5
  164. package/dist/lib/viewerKind.js.map +1 -1
  165. package/dist/lib/xlsx.d.ts +1 -1
  166. package/dist/lib/xlsx.js +106 -89
  167. package/dist/lib/xlsx.js.map +1 -1
  168. package/dist/lib/xlsxCharts.js +71 -119
  169. package/dist/lib/xlsxCharts.js.map +1 -1
  170. package/dist/lib/xlsxImages.d.ts +43 -0
  171. package/dist/lib/xlsxImages.js +114 -0
  172. package/dist/lib/xlsxImages.js.map +1 -0
  173. package/dist/lib/xlsxParts.d.ts +17 -0
  174. package/dist/lib/xlsxParts.js +86 -0
  175. package/dist/lib/xlsxParts.js.map +1 -0
  176. package/dist/style.css +1 -1
  177. package/package.json +8 -3
@@ -1,123 +1,88 @@
1
- import { extractZipEntry as e, readZip as t, zipSupported as n } from "./zip.js";
1
+ import { openXlsxParts as e, tag as t, tags as n, worksheetDrawings as r } from "./xlsxParts.js";
2
2
  //#region src/lib/xlsxCharts.ts
3
- var r = 9525, i = (e) => Math.round(e / r);
4
- function a(e, t) {
5
- return Array.from(e.getElementsByTagNameNS("*", t));
6
- }
7
- function o(e, t) {
8
- return e.getElementsByTagNameNS("*", t)[0];
9
- }
10
- function s(e) {
3
+ var i = 9525, a = (e) => Math.round(e / i);
4
+ function o(e) {
11
5
  return e?.getAttribute("val") ?? void 0;
12
6
  }
13
- function c(e, t) {
14
- let n = (e ? e.split("/") : []).concat(t.split("/")), r = [];
15
- for (let e of n) e === "" || e === "." || (e === ".." ? r.pop() : r.push(e));
16
- return r.join("/");
17
- }
18
- var l = (e) => e.split("/").slice(0, -1).join("/");
19
- function u(t, n) {
20
- let r = new Map(n.map((e) => [e.path, e])), i = /* @__PURE__ */ new Map(), a = new TextDecoder("utf-8");
21
- return (n) => {
22
- let o = i.get(n);
23
- return o || (o = (async () => {
24
- let i = r.get(n);
25
- if (!i) return null;
26
- let o = await e(t, i), s = new DOMParser().parseFromString(a.decode(o), "application/xml");
27
- return s.querySelector("parsererror") ? null : s;
28
- })(), i.set(n, o)), o;
29
- };
30
- }
31
- function d(e, t) {
32
- let n = /* @__PURE__ */ new Map();
33
- if (!e) return n;
34
- for (let r of a(e, "Relationship")) {
35
- let e = r.getAttribute("Id"), i = r.getAttribute("Target");
36
- e && i && !/^[a-z]+:\/\//i.test(i) && n.set(e, c(t, i));
37
- }
38
- return n;
39
- }
40
- function f(e) {
7
+ function s(e) {
41
8
  if (!e) return [];
42
- let t = o(e, "strCache") || o(e, "numCache");
43
- if (!t) return [];
44
- let n = parseInt(s(o(t, "ptCount")) || "0", 10) || 0, r = Array.from({ length: n }, () => "");
45
- for (let e of a(t, "pt")) {
46
- let t = parseInt(e.getAttribute("idx") || "-1", 10), n = o(e, "v")?.textContent ?? "";
47
- t >= 0 && (t >= r.length && (r.length = t + 1), r[t] = n);
9
+ let r = t(e, "strCache") || t(e, "numCache");
10
+ if (!r) return [];
11
+ let i = parseInt(o(t(r, "ptCount")) || "0", 10) || 0, a = Array.from({ length: i }, () => "");
12
+ for (let e of n(r, "pt")) {
13
+ let n = parseInt(e.getAttribute("idx") || "-1", 10), r = t(e, "v")?.textContent ?? "";
14
+ n >= 0 && (n >= a.length && (a.length = n + 1), a[n] = r);
48
15
  }
49
- return r;
16
+ return a;
50
17
  }
51
- function p(e) {
18
+ function c(e) {
52
19
  if (!e) return [];
53
- let t = o(e, "numCache") || o(e, "strCache");
54
- if (!t) return [];
55
- let n = parseInt(s(o(t, "ptCount")) || "0", 10) || 0, r = Array.from({ length: n }, () => null);
56
- for (let e of a(t, "pt")) {
57
- let t = parseInt(e.getAttribute("idx") || "-1", 10), n = o(e, "v")?.textContent, i = n == null || n === "" ? null : Number(n);
58
- t >= 0 && (t >= r.length && (r.length = t + 1), r[t] = i != null && Number.isFinite(i) ? i : null);
20
+ let r = t(e, "numCache") || t(e, "strCache");
21
+ if (!r) return [];
22
+ let i = parseInt(o(t(r, "ptCount")) || "0", 10) || 0, a = Array.from({ length: i }, () => null);
23
+ for (let e of n(r, "pt")) {
24
+ let n = parseInt(e.getAttribute("idx") || "-1", 10), r = t(e, "v")?.textContent, i = r == null || r === "" ? null : Number(r);
25
+ n >= 0 && (n >= a.length && (a.length = n + 1), a[n] = i != null && Number.isFinite(i) ? i : null);
59
26
  }
60
- return r;
27
+ return a;
61
28
  }
62
- function m(e) {
63
- return o(e, "lineChart") ? "line" : o(e, "barChart") ? s(o(o(e, "barChart"), "barDir")) === "bar" ? "barH" : "bar" : o(e, "pieChart") || o(e, "doughnutChart") ? "pie" : o(e, "areaChart") ? "area" : o(e, "scatterChart") ? "scatter" : "unknown";
29
+ function l(e) {
30
+ return t(e, "lineChart") ? "line" : t(e, "barChart") ? o(t(t(e, "barChart"), "barDir")) === "bar" ? "barH" : "bar" : t(e, "pieChart") || t(e, "doughnutChart") ? "pie" : t(e, "areaChart") ? "area" : t(e, "scatterChart") ? "scatter" : "unknown";
64
31
  }
65
- function h(e) {
66
- let t = o(e, "spPr");
67
- if (!t) return;
68
- let n = o(t, "ln"), r = (n && o(n, "srgbClr") || o(t, "srgbClr"))?.getAttribute("val");
69
- return r && /^[0-9a-fA-F]{6}$/.test(r) ? `#${r}` : void 0;
32
+ function u(e) {
33
+ let n = t(e, "spPr");
34
+ if (!n) return;
35
+ let r = t(n, "ln"), i = (r && t(r, "srgbClr") || t(n, "srgbClr"))?.getAttribute("val");
36
+ return i && /^[0-9a-fA-F]{6}$/.test(i) ? `#${i}` : void 0;
70
37
  }
71
- function g(e) {
72
- let t = o(e, "plotArea");
73
- if (!t) return null;
74
- let n = m(t), r = o(e, "title"), i = r ? a(r, "t").map((e) => e.textContent ?? "").join("").trim() : "", c = [], l = [];
75
- for (let e of a(t, "ser")) {
76
- let t = f(o(e, "cat"));
77
- t.length > c.length && (c = t);
78
- let n = o(o(e, "tx") || e, "v")?.textContent;
79
- l.push({
80
- name: (n || `系列 ${l.length + 1}`).trim(),
81
- color: h(e),
82
- values: p(o(e, "val"))
38
+ function d(e) {
39
+ let r = t(e, "plotArea");
40
+ if (!r) return null;
41
+ let i = l(r), a = t(e, "title"), d = a ? n(a, "t").map((e) => e.textContent ?? "").join("").trim() : "", f = [], p = [];
42
+ for (let e of n(r, "ser")) {
43
+ let n = s(t(e, "cat"));
44
+ n.length > f.length && (f = n);
45
+ let r = t(t(e, "tx") || e, "v")?.textContent;
46
+ p.push({
47
+ name: (r || `系列 ${p.length + 1}`).trim(),
48
+ color: u(e),
49
+ values: c(t(e, "val"))
83
50
  });
84
51
  }
85
- let u, d;
86
- for (let e of a(t, "valAx")) {
87
- let t = o(e, "scaling");
88
- if (!t) continue;
89
- let n = s(o(t, "max")), r = s(o(t, "min"));
90
- n != null && Number.isFinite(Number(n)) && (d = Number(n)), r != null && Number.isFinite(Number(r)) && (u = Number(r));
52
+ let m, h;
53
+ for (let e of n(r, "valAx")) {
54
+ let n = t(e, "scaling");
55
+ if (!n) continue;
56
+ let r = o(t(n, "max")), i = o(t(n, "min"));
57
+ r != null && Number.isFinite(Number(r)) && (h = Number(r)), i != null && Number.isFinite(Number(i)) && (m = Number(i));
91
58
  }
92
59
  return {
93
- type: n,
94
- title: i,
95
- categories: c,
96
- series: l,
97
- yMin: u,
98
- yMax: d
60
+ type: i,
61
+ title: d,
62
+ categories: f,
63
+ series: p,
64
+ yMin: m,
65
+ yMax: h
99
66
  };
100
67
  }
101
- async function _(e, t) {
102
- let n = await t(e);
103
- if (!n) return [];
104
- let r = d(await t(`${l(e)}/_rels/${e.split("/").pop()}.rels`), l(e)), s = [];
105
- for (let e of [...a(n, "twoCellAnchor"), ...a(n, "oneCellAnchor")]) {
106
- let n = o(e, "graphicFrame");
68
+ async function f(e, r) {
69
+ let { doc: i, rels: o } = e, s = [];
70
+ for (let e of [...n(i, "twoCellAnchor"), ...n(i, "oneCellAnchor")]) {
71
+ let n = t(e, "graphicFrame");
107
72
  if (!n) continue;
108
- let a = o(n, "chart"), c = a?.getAttributeNS("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id") || a?.getAttribute("r:id"), l = c ? r.get(c) : void 0;
73
+ let i = t(n, "chart"), c = i?.getAttributeNS("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id") || i?.getAttribute("r:id"), l = c ? o.get(c) : void 0;
109
74
  if (!l) continue;
110
- let u = await t(l);
75
+ let u = await r(l);
111
76
  if (!u) continue;
112
- let d = g(u);
113
- if (!d || !d.series.length) continue;
114
- let f = o(e, "from"), p = parseInt(o(f, "col")?.textContent || "0", 10), m = parseInt(o(f, "row")?.textContent || "0", 10), h = i(parseInt(o(f, "colOff")?.textContent || "0", 10)), _ = i(parseInt(o(f, "rowOff")?.textContent || "0", 10)), v = o(n, "ext"), y = v ? i(parseInt(v.getAttribute("cx") || "0", 10)) : 384, b = v ? i(parseInt(v.getAttribute("cy") || "0", 10)) : 230;
77
+ let f = d(u);
78
+ if (!f || !f.series.length) continue;
79
+ let p = t(e, "from"), m = parseInt(t(p, "col")?.textContent || "0", 10), h = parseInt(t(p, "row")?.textContent || "0", 10), g = a(parseInt(t(p, "colOff")?.textContent || "0", 10)), _ = a(parseInt(t(p, "rowOff")?.textContent || "0", 10)), v = t(n, "ext"), y = v ? a(parseInt(v.getAttribute("cx") || "0", 10)) : 384, b = v ? a(parseInt(v.getAttribute("cy") || "0", 10)) : 230;
115
80
  s.push({
116
- ...d,
81
+ ...f,
117
82
  anchor: {
118
- fromCol: p,
119
- fromRow: m,
120
- offX: h,
83
+ fromCol: m,
84
+ fromRow: h,
85
+ offX: g,
121
86
  offY: _,
122
87
  wPx: y,
123
88
  hPx: b
@@ -126,29 +91,16 @@ async function _(e, t) {
126
91
  }
127
92
  return s;
128
93
  }
129
- async function v(e) {
130
- let r = /* @__PURE__ */ new Map();
131
- if (!n() || typeof DOMParser > "u") return r;
132
- let i;
133
- try {
134
- i = t(e);
135
- } catch {
136
- return r;
137
- }
138
- let s = u(e, i), c = await s("xl/workbook.xml");
139
- if (!c) return r;
140
- let f = d(await s("xl/_rels/workbook.xml.rels"), "xl");
141
- for (let e of a(c, "sheet")) {
142
- let t = e.getAttribute("name") || "", n = e.getAttributeNS("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id") || e.getAttribute("r:id"), i = n ? f.get(n) : void 0;
143
- if (!i) continue;
144
- let a = d(await s(`${l(i)}/_rels/${i.split("/").pop()}.rels`), l(i)), c = await s(i), u = c ? o(c, "drawing") : void 0, p = u?.getAttributeNS("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "id") || u?.getAttribute("r:id"), m = p ? a.get(p) : void 0;
145
- if (!m) continue;
146
- let h = await _(m, s);
147
- h.length && r.set(t, h);
94
+ async function p(t) {
95
+ let n = /* @__PURE__ */ new Map(), i = e(t);
96
+ if (!i) return n;
97
+ for (let e of await r(i)) {
98
+ let t = await f(e, i.xml);
99
+ t.length && n.set(e.sheetName, [...n.get(e.sheetName) ?? [], ...t]);
148
100
  }
149
- return r;
101
+ return n;
150
102
  }
151
103
  //#endregion
152
- export { v as parseXlsxCharts };
104
+ export { p as parseXlsxCharts };
153
105
 
154
106
  //# sourceMappingURL=xlsxCharts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"xlsxCharts.js","names":[],"sources":["../../src/lib/xlsxCharts.ts"],"sourcesContent":["/**\n * Extract embedded **charts** from an `.xlsx` for the spreadsheet preview.\n *\n * exceljs parses cells and styles but NOT charts (and a workbook can hold native line/bar/pie charts with no\n * raster image anywhere — `wb.model.media` is empty). So we read them ourselves: an `.xlsx` is a ZIP, and we\n * already have a dependency-free reader ({@link readZip}/{@link extractZipEntry}). We walk\n * worksheet → drawing → chart, parse the chart's cached series/categories straight out of the OOXML\n * (`<c:numCache>`/`<c:strCache>` — the values Excel last computed, so no recomputation needed), and hand the\n * viewer a small model it renders as SVG ({@link XlsxChart}). Browser-only (DOMParser + DecompressionStream);\n * charts simply don't appear under SSR.\n */\nimport { extractZipEntry, readZip, zipSupported, type ZipEntry } from '@/lib/zip'\n\nexport type ChartType = 'line' | 'bar' | 'barH' | 'pie' | 'area' | 'scatter' | 'unknown'\n\nexport interface ChartSeries {\n name: string\n /** Series line/fill colour as CSS `#RRGGBB`, when the chart specifies one. */\n color?: string\n /** Cached y-values, one per category (null = a gap/blank point). */\n values: (number | null)[]\n}\n\n/** Where a chart sits on the sheet — top-left cell + pixel size, converted from the drawing anchor's EMUs. */\nexport interface ChartAnchor {\n /** 0-based column / row of the anchor's top-left cell. */\n fromCol: number\n fromRow: number\n /** Pixel offset into that cell, and the chart's pixel width/height (from the frame's EMU extent). */\n offX: number\n offY: number\n wPx: number\n hPx: number\n}\n\nexport interface XlsxChart {\n type: ChartType\n title: string\n categories: string[]\n series: ChartSeries[]\n /** Explicit value-axis bounds, when the chart pins them (else the renderer auto-scales). */\n yMin?: number\n yMax?: number\n anchor: ChartAnchor\n}\n\nconst EMU_PER_PX = 9525 // 914400 EMU per inch / 96 px per inch\nconst emuToPx = (emu: number): number => Math.round(emu / EMU_PER_PX)\n\n// Descendants matching a localName, regardless of namespace prefix (xdr:/c:/a: vary by producer).\nfunction tags(el: Element | Document, localName: string): Element[] {\n return Array.from(el.getElementsByTagNameNS('*', localName))\n}\nfunction tag(el: Element | Document, localName: string): Element | undefined {\n return el.getElementsByTagNameNS('*', localName)[0]\n}\nfunction attrVal(el: Element | undefined): string | undefined {\n return el?.getAttribute('val') ?? undefined\n}\n\n// Resolve an OOXML relationship target (often \"../charts/chart3.xml\") against the part that referenced it.\nfunction resolvePath(baseDir: string, rel: string): string {\n const parts = (baseDir ? baseDir.split('/') : []).concat(rel.split('/'))\n const out: string[] = []\n for (const p of parts) {\n if (p === '' || p === '.') continue\n if (p === '..') out.pop()\n else out.push(p)\n }\n return out.join('/')\n}\nconst dirOf = (path: string): string => path.split('/').slice(0, -1).join('/')\n\n/** A loader bound to one workbook's ZIP: lazily inflate + XML-parse parts, cached by path. */\nfunction makeLoader(\n buf: ArrayBuffer,\n entries: ZipEntry[],\n): (path: string) => Promise<Document | null> {\n const byPath = new Map(entries.map((e) => [e.path, e]))\n const cache = new Map<string, Promise<Document | null>>()\n const decoder = new TextDecoder('utf-8')\n return (path: string) => {\n let p = cache.get(path)\n if (!p) {\n p = (async () => {\n const e = byPath.get(path)\n if (!e) return null\n const bytes = await extractZipEntry(buf, e)\n const doc = new DOMParser().parseFromString(decoder.decode(bytes), 'application/xml')\n return doc.querySelector('parsererror') ? null : doc\n })()\n cache.set(path, p)\n }\n return p\n }\n}\n\n// Parse a \"rels\" part into { relId → resolved absolute path }.\nfunction relsMap(doc: Document | null, baseDir: string): Map<string, string> {\n const m = new Map<string, string>()\n if (!doc) return m\n for (const r of tags(doc, 'Relationship')) {\n const id = r.getAttribute('Id')\n const target = r.getAttribute('Target')\n if (id && target && !/^[a-z]+:\\/\\//i.test(target)) m.set(id, resolvePath(baseDir, target))\n }\n return m\n}\n\n// Pull the ordered category labels (or numbers) out of a <c:cat>'s cached points.\nfunction readCacheStrings(parent: Element | undefined): string[] {\n if (!parent) return []\n const cache = tag(parent, 'strCache') || tag(parent, 'numCache')\n if (!cache) return []\n const count = parseInt(attrVal(tag(cache, 'ptCount')) || '0', 10) || 0\n const out: string[] = Array.from({ length: count }, () => '')\n for (const pt of tags(cache, 'pt')) {\n const idx = parseInt(pt.getAttribute('idx') || '-1', 10)\n const v = tag(pt, 'v')?.textContent ?? ''\n if (idx >= 0) {\n if (idx >= out.length) out.length = idx + 1\n out[idx] = v\n }\n }\n return out\n}\n\n// Pull cached numeric values out of a <c:val>'s numCache (blank/non-numeric → null).\nfunction readCacheNumbers(parent: Element | undefined): (number | null)[] {\n if (!parent) return []\n const cache = tag(parent, 'numCache') || tag(parent, 'strCache')\n if (!cache) return []\n const count = parseInt(attrVal(tag(cache, 'ptCount')) || '0', 10) || 0\n const out: (number | null)[] = Array.from({ length: count }, () => null)\n for (const pt of tags(cache, 'pt')) {\n const idx = parseInt(pt.getAttribute('idx') || '-1', 10)\n const raw = tag(pt, 'v')?.textContent\n const n = raw == null || raw === '' ? null : Number(raw)\n if (idx >= 0) {\n if (idx >= out.length) out.length = idx + 1\n out[idx] = n != null && Number.isFinite(n) ? n : null\n }\n }\n return out\n}\n\nfunction chartTypeOf(plot: Element): ChartType {\n if (tag(plot, 'lineChart')) return 'line'\n if (tag(plot, 'barChart')) {\n const dir = attrVal(tag(tag(plot, 'barChart')!, 'barDir'))\n return dir === 'bar' ? 'barH' : 'bar'\n }\n if (tag(plot, 'pieChart') || tag(plot, 'doughnutChart')) return 'pie'\n if (tag(plot, 'areaChart')) return 'area'\n if (tag(plot, 'scatterChart')) return 'scatter'\n return 'unknown'\n}\n\n// First explicit series colour: prefer the line stroke, else any solid fill in the series' shape props.\nfunction seriesColor(ser: Element): string | undefined {\n const spPr = tag(ser, 'spPr')\n if (!spPr) return undefined\n const ln = tag(spPr, 'ln')\n const clr = (ln && tag(ln, 'srgbClr')) || tag(spPr, 'srgbClr')\n const val = clr?.getAttribute('val')\n return val && /^[0-9a-fA-F]{6}$/.test(val) ? `#${val}` : undefined\n}\n\nfunction parseChart(doc: Document): Omit<XlsxChart, 'anchor'> | null {\n const plot = tag(doc, 'plotArea')\n if (!plot) return null\n const type = chartTypeOf(plot)\n // Title: concatenate the rich-text runs under <c:title>.\n const titleEl = tag(doc, 'title')\n const title = titleEl\n ? tags(titleEl, 't')\n .map((t) => t.textContent ?? '')\n .join('')\n .trim()\n : ''\n\n let categories: string[] = []\n const series: ChartSeries[] = []\n for (const ser of tags(plot, 'ser')) {\n const cats = readCacheStrings(tag(ser, 'cat'))\n if (cats.length > categories.length) categories = cats\n const txV = tag(tag(ser, 'tx') || ser, 'v')?.textContent\n series.push({\n name: (txV || `系列 ${series.length + 1}`).trim(),\n color: seriesColor(ser),\n values: readCacheNumbers(tag(ser, 'val')),\n })\n }\n\n // Value-axis explicit bounds, if any.\n let yMin: number | undefined\n let yMax: number | undefined\n for (const ax of tags(plot, 'valAx')) {\n const sc = tag(ax, 'scaling')\n if (!sc) continue\n const mx = attrVal(tag(sc, 'max'))\n const mn = attrVal(tag(sc, 'min'))\n if (mx != null && Number.isFinite(Number(mx))) yMax = Number(mx)\n if (mn != null && Number.isFinite(Number(mn))) yMin = Number(mn)\n }\n return { type, title, categories, series, yMin, yMax }\n}\n\n// Read a drawing's anchors, resolving each graphicFrame's chart part via the drawing's own rels.\nasync function parseDrawing(\n drawingPath: string,\n load: (path: string) => Promise<Document | null>,\n): Promise<XlsxChart[]> {\n const doc = await load(drawingPath)\n if (!doc) return []\n const rels = relsMap(\n await load(`${dirOf(drawingPath)}/_rels/${drawingPath.split('/').pop()}.rels`),\n dirOf(drawingPath),\n )\n const out: XlsxChart[] = []\n for (const anchor of [...tags(doc, 'twoCellAnchor'), ...tags(doc, 'oneCellAnchor')]) {\n const frame = tag(anchor, 'graphicFrame')\n if (!frame) continue\n const chartRef = tag(frame, 'chart') // <c:chart r:id=\"rIdN\"/>\n const rId =\n chartRef?.getAttributeNS(\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',\n 'id',\n ) || chartRef?.getAttribute('r:id')\n const chartPath = rId ? rels.get(rId) : undefined\n if (!chartPath) continue\n const chartDoc = await load(chartPath)\n if (!chartDoc) continue\n const parsed = parseChart(chartDoc)\n if (!parsed || !parsed.series.length) continue\n\n const from = tag(anchor, 'from')\n const fromCol = parseInt(tag(from!, 'col')?.textContent || '0', 10)\n const fromRow = parseInt(tag(from!, 'row')?.textContent || '0', 10)\n const offX = emuToPx(parseInt(tag(from!, 'colOff')?.textContent || '0', 10))\n const offY = emuToPx(parseInt(tag(from!, 'rowOff')?.textContent || '0', 10))\n const ext = tag(frame, 'ext') // <a:ext cx cy> in EMU\n const wPx = ext ? emuToPx(parseInt(ext.getAttribute('cx') || '0', 10)) : 384\n const hPx = ext ? emuToPx(parseInt(ext.getAttribute('cy') || '0', 10)) : 230\n out.push({ ...parsed, anchor: { fromCol, fromRow, offX, offY, wPx, hPx } })\n }\n return out\n}\n\n/**\n * Parse every chart in the workbook, grouped by worksheet **name** (matching {@link XlsxSheet.name}). Returns\n * an empty map under SSR or if the bytes can't be unzipped — charts are a best-effort enhancement, never fatal.\n */\nexport async function parseXlsxCharts(buf: ArrayBuffer): Promise<Map<string, XlsxChart[]>> {\n const result = new Map<string, XlsxChart[]>()\n if (!zipSupported() || typeof DOMParser === 'undefined') return result\n let entries: ZipEntry[]\n try {\n entries = readZip(buf)\n } catch {\n return result\n }\n const load = makeLoader(buf, entries)\n\n const wb = await load('xl/workbook.xml')\n if (!wb) return result\n const wbRels = relsMap(await load('xl/_rels/workbook.xml.rels'), 'xl')\n\n for (const sheetEl of tags(wb, 'sheet')) {\n const name = sheetEl.getAttribute('name') || ''\n const rId =\n sheetEl.getAttributeNS(\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',\n 'id',\n ) || sheetEl.getAttribute('r:id')\n const sheetPath = rId ? wbRels.get(rId) : undefined\n if (!sheetPath) continue\n const sheetRels = relsMap(\n await load(`${dirOf(sheetPath)}/_rels/${sheetPath.split('/').pop()}.rels`),\n dirOf(sheetPath),\n )\n // Find the worksheet's drawing relationship, then its charts.\n const sheetDoc = await load(sheetPath)\n const drawingEl = sheetDoc ? tag(sheetDoc, 'drawing') : undefined\n const drawRid =\n drawingEl?.getAttributeNS(\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',\n 'id',\n ) || drawingEl?.getAttribute('r:id')\n const drawingPath = drawRid ? sheetRels.get(drawRid) : undefined\n if (!drawingPath) continue\n const charts = await parseDrawing(drawingPath, load)\n if (charts.length) result.set(name, charts)\n }\n return result\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"xlsxCharts.js","names":[],"sources":["../../src/lib/xlsxCharts.ts"],"sourcesContent":["/**\n * Extract embedded **charts** from an `.xlsx` for the spreadsheet preview.\n *\n * exceljs parses cells and styles but NOT charts (and a workbook can hold native line/bar/pie charts with no\n * raster image anywhere — `wb.model.media` is empty). So we read them ourselves: an `.xlsx` is a ZIP, and we\n * already have a dependency-free reader wrapped by {@link openXlsxParts}. We walk\n * worksheet → drawing → chart, parse the chart's cached series/categories straight out of the OOXML\n * (`<c:numCache>`/`<c:strCache>` — the values Excel last computed, so no recomputation needed), and hand the\n * viewer a small model it renders as SVG ({@link XlsxChart}). Browser-only (DOMParser + DecompressionStream);\n * charts simply don't appear under SSR.\n */\nimport { openXlsxParts, worksheetDrawings, tags, tag, type WorksheetDrawing } from '@/lib/xlsxParts'\n\nexport type ChartType = 'line' | 'bar' | 'barH' | 'pie' | 'area' | 'scatter' | 'unknown'\n\nexport interface ChartSeries {\n name: string\n /** Series line/fill colour as CSS `#RRGGBB`, when the chart specifies one. */\n color?: string\n /** Cached y-values, one per category (null = a gap/blank point). */\n values: (number | null)[]\n}\n\n/** Where a chart sits on the sheet — top-left cell + pixel size, converted from the drawing anchor's EMUs. */\nexport interface ChartAnchor {\n /** 0-based column / row of the anchor's top-left cell. */\n fromCol: number\n fromRow: number\n /** Pixel offset into that cell, and the chart's pixel width/height (from the frame's EMU extent). */\n offX: number\n offY: number\n wPx: number\n hPx: number\n}\n\nexport interface XlsxChart {\n type: ChartType\n title: string\n categories: string[]\n series: ChartSeries[]\n /** Explicit value-axis bounds, when the chart pins them (else the renderer auto-scales). */\n yMin?: number\n yMax?: number\n anchor: ChartAnchor\n}\n\nconst EMU_PER_PX = 9525 // 914400 EMU per inch / 96 px per inch\nconst emuToPx = (emu: number): number => Math.round(emu / EMU_PER_PX)\n\nfunction attrVal(el: Element | undefined): string | undefined {\n return el?.getAttribute('val') ?? undefined\n}\n\n// Pull the ordered category labels (or numbers) out of a <c:cat>'s cached points.\nfunction readCacheStrings(parent: Element | undefined): string[] {\n if (!parent) return []\n const cache = tag(parent, 'strCache') || tag(parent, 'numCache')\n if (!cache) return []\n const count = parseInt(attrVal(tag(cache, 'ptCount')) || '0', 10) || 0\n const out: string[] = Array.from({ length: count }, () => '')\n for (const pt of tags(cache, 'pt')) {\n const idx = parseInt(pt.getAttribute('idx') || '-1', 10)\n const v = tag(pt, 'v')?.textContent ?? ''\n if (idx >= 0) {\n if (idx >= out.length) out.length = idx + 1\n out[idx] = v\n }\n }\n return out\n}\n\n// Pull cached numeric values out of a <c:val>'s numCache (blank/non-numeric → null).\nfunction readCacheNumbers(parent: Element | undefined): (number | null)[] {\n if (!parent) return []\n const cache = tag(parent, 'numCache') || tag(parent, 'strCache')\n if (!cache) return []\n const count = parseInt(attrVal(tag(cache, 'ptCount')) || '0', 10) || 0\n const out: (number | null)[] = Array.from({ length: count }, () => null)\n for (const pt of tags(cache, 'pt')) {\n const idx = parseInt(pt.getAttribute('idx') || '-1', 10)\n const raw = tag(pt, 'v')?.textContent\n const n = raw == null || raw === '' ? null : Number(raw)\n if (idx >= 0) {\n if (idx >= out.length) out.length = idx + 1\n out[idx] = n != null && Number.isFinite(n) ? n : null\n }\n }\n return out\n}\n\nfunction chartTypeOf(plot: Element): ChartType {\n if (tag(plot, 'lineChart')) return 'line'\n if (tag(plot, 'barChart')) {\n const dir = attrVal(tag(tag(plot, 'barChart')!, 'barDir'))\n return dir === 'bar' ? 'barH' : 'bar'\n }\n if (tag(plot, 'pieChart') || tag(plot, 'doughnutChart')) return 'pie'\n if (tag(plot, 'areaChart')) return 'area'\n if (tag(plot, 'scatterChart')) return 'scatter'\n return 'unknown'\n}\n\n// First explicit series colour: prefer the line stroke, else any solid fill in the series' shape props.\nfunction seriesColor(ser: Element): string | undefined {\n const spPr = tag(ser, 'spPr')\n if (!spPr) return undefined\n const ln = tag(spPr, 'ln')\n const clr = (ln && tag(ln, 'srgbClr')) || tag(spPr, 'srgbClr')\n const val = clr?.getAttribute('val')\n return val && /^[0-9a-fA-F]{6}$/.test(val) ? `#${val}` : undefined\n}\n\nfunction parseChart(doc: Document): Omit<XlsxChart, 'anchor'> | null {\n const plot = tag(doc, 'plotArea')\n if (!plot) return null\n const type = chartTypeOf(plot)\n // Title: concatenate the rich-text runs under <c:title>.\n const titleEl = tag(doc, 'title')\n const title = titleEl\n ? tags(titleEl, 't')\n .map((t) => t.textContent ?? '')\n .join('')\n .trim()\n : ''\n\n let categories: string[] = []\n const series: ChartSeries[] = []\n for (const ser of tags(plot, 'ser')) {\n const cats = readCacheStrings(tag(ser, 'cat'))\n if (cats.length > categories.length) categories = cats\n const txV = tag(tag(ser, 'tx') || ser, 'v')?.textContent\n series.push({\n name: (txV || `系列 ${series.length + 1}`).trim(),\n color: seriesColor(ser),\n values: readCacheNumbers(tag(ser, 'val')),\n })\n }\n\n // Value-axis explicit bounds, if any.\n let yMin: number | undefined\n let yMax: number | undefined\n for (const ax of tags(plot, 'valAx')) {\n const sc = tag(ax, 'scaling')\n if (!sc) continue\n const mx = attrVal(tag(sc, 'max'))\n const mn = attrVal(tag(sc, 'min'))\n if (mx != null && Number.isFinite(Number(mx))) yMax = Number(mx)\n if (mn != null && Number.isFinite(Number(mn))) yMin = Number(mn)\n }\n return { type, title, categories, series, yMin, yMax }\n}\n\n// Read a drawing's anchors, resolving each graphicFrame's chart part via the drawing's own rels.\nasync function parseDrawing(\n drawing: WorksheetDrawing,\n load: (path: string) => Promise<Document | null>,\n): Promise<XlsxChart[]> {\n const { doc, rels } = drawing\n const out: XlsxChart[] = []\n for (const anchor of [...tags(doc, 'twoCellAnchor'), ...tags(doc, 'oneCellAnchor')]) {\n const frame = tag(anchor, 'graphicFrame')\n if (!frame) continue\n const chartRef = tag(frame, 'chart') // <c:chart r:id=\"rIdN\"/>\n const rId =\n chartRef?.getAttributeNS(\n 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',\n 'id',\n ) || chartRef?.getAttribute('r:id')\n const chartPath = rId ? rels.get(rId) : undefined\n if (!chartPath) continue\n const chartDoc = await load(chartPath)\n if (!chartDoc) continue\n const parsed = parseChart(chartDoc)\n if (!parsed || !parsed.series.length) continue\n\n const from = tag(anchor, 'from')\n const fromCol = parseInt(tag(from!, 'col')?.textContent || '0', 10)\n const fromRow = parseInt(tag(from!, 'row')?.textContent || '0', 10)\n const offX = emuToPx(parseInt(tag(from!, 'colOff')?.textContent || '0', 10))\n const offY = emuToPx(parseInt(tag(from!, 'rowOff')?.textContent || '0', 10))\n const ext = tag(frame, 'ext') // <a:ext cx cy> in EMU\n const wPx = ext ? emuToPx(parseInt(ext.getAttribute('cx') || '0', 10)) : 384\n const hPx = ext ? emuToPx(parseInt(ext.getAttribute('cy') || '0', 10)) : 230\n out.push({ ...parsed, anchor: { fromCol, fromRow, offX, offY, wPx, hPx } })\n }\n return out\n}\n\n/**\n * Parse every chart in the workbook, grouped by worksheet **name** (matching {@link XlsxSheet.name}). Returns\n * an empty map under SSR or if the bytes can't be unzipped — charts are a best-effort enhancement, never fatal.\n */\nexport async function parseXlsxCharts(buf: ArrayBuffer): Promise<Map<string, XlsxChart[]>> {\n const result = new Map<string, XlsxChart[]>()\n const parts = openXlsxParts(buf)\n if (!parts) return result\n for (const drawing of await worksheetDrawings(parts)) {\n const charts = await parseDrawing(drawing, parts.xml)\n if (charts.length)\n result.set(drawing.sheetName, [...(result.get(drawing.sheetName) ?? []), ...charts])\n }\n return result\n}\n"],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ interface ImageMarker {
2
+ col: number;
3
+ row: number;
4
+ offX: number;
5
+ offY: number;
6
+ }
7
+ export type XlsxImageAnchor = {
8
+ kind: 'oneCell';
9
+ from: ImageMarker;
10
+ width: number;
11
+ height: number;
12
+ } | {
13
+ kind: 'twoCell';
14
+ from: ImageMarker;
15
+ to: ImageMarker;
16
+ } | {
17
+ kind: 'absolute';
18
+ left: number;
19
+ top: number;
20
+ width: number;
21
+ height: number;
22
+ };
23
+ export interface XlsxImage {
24
+ id: string;
25
+ alt: string;
26
+ blob: Blob;
27
+ anchor: XlsxImageAnchor;
28
+ }
29
+ /** Read embedded images from original OOXML, independent of ExcelJS's prefix-sensitive drawing parser. */
30
+ export declare function parseXlsxImages(buf: ArrayBuffer): Promise<Map<string, XlsxImage[]>>;
31
+ export declare function xlsxImageBox(anchor: XlsxImageAnchor, cols: number[], rows: number[]): {
32
+ left: number;
33
+ top: number;
34
+ kind: "absolute";
35
+ width: number;
36
+ height: number;
37
+ } | {
38
+ left: number;
39
+ top: number;
40
+ width: number;
41
+ height: number;
42
+ };
43
+ export {};
@@ -0,0 +1,114 @@
1
+ import { openXlsxParts as e, relationshipId as t, tag as n, worksheetDrawings as r } from "./xlsxParts.js";
2
+ //#region src/lib/xlsxImages.ts
3
+ var i = 9525;
4
+ function a(e) {
5
+ return e == null || e.trim() === "" ? NaN : Number(e);
6
+ }
7
+ function o(e) {
8
+ if (!e) return null;
9
+ let t = a(n(e, "col")?.textContent), r = a(n(e, "row")?.textContent), o = a(n(e, "colOff")?.textContent) / i, s = a(n(e, "rowOff")?.textContent) / i;
10
+ return !Number.isInteger(t) || t < 0 || t >= 16384 || !Number.isInteger(r) || r < 0 || r >= 1048576 ? null : [o, s].every(Number.isFinite) ? {
11
+ col: t,
12
+ row: r,
13
+ offX: o,
14
+ offY: s
15
+ } : null;
16
+ }
17
+ function s(e) {
18
+ let t = o(n(e, "from"));
19
+ if (e.localName === "twoCellAnchor") {
20
+ let r = o(n(e, "to"));
21
+ return t && r ? {
22
+ kind: "twoCell",
23
+ from: t,
24
+ to: r
25
+ } : null;
26
+ }
27
+ let r = n(e, "ext"), s = a(r?.getAttribute("cx")) / i, c = a(r?.getAttribute("cy")) / i;
28
+ if (![s, c].every((e) => Number.isFinite(e) && e > 0)) return null;
29
+ if (e.localName === "oneCellAnchor") return t ? {
30
+ kind: "oneCell",
31
+ from: t,
32
+ width: s,
33
+ height: c
34
+ } : null;
35
+ let l = n(e, "pos"), u = a(l?.getAttribute("x")) / i, d = a(l?.getAttribute("y")) / i;
36
+ return [u, d].every(Number.isFinite) ? {
37
+ kind: "absolute",
38
+ left: u,
39
+ top: d,
40
+ width: s,
41
+ height: c
42
+ } : null;
43
+ }
44
+ var c = {
45
+ png: "image/png",
46
+ jpg: "image/jpeg",
47
+ jpeg: "image/jpeg",
48
+ gif: "image/gif",
49
+ bmp: "image/bmp",
50
+ webp: "image/webp",
51
+ svg: "image/svg+xml"
52
+ };
53
+ async function l(i) {
54
+ let a = /* @__PURE__ */ new Map(), o = e(i);
55
+ if (!o) return a;
56
+ let l = /* @__PURE__ */ new Map();
57
+ for (let e of await r(o)) {
58
+ let r = a.get(e.sheetName) ?? [];
59
+ for (let i of Array.from(e.doc.documentElement.children)) {
60
+ if (![
61
+ "oneCellAnchor",
62
+ "twoCellAnchor",
63
+ "absoluteAnchor"
64
+ ].includes(i.localName)) continue;
65
+ let a = n(i, "pic");
66
+ if (!a) continue;
67
+ let u = s(i), d = e.rels.get(t(n(a, "blip"), "embed") || ""), f = d ? c[d.split(".").pop().toLowerCase()] : void 0;
68
+ if (!u || !d || !f) continue;
69
+ let p = l.get(d);
70
+ if (!p) {
71
+ let e = await o.bytes(d);
72
+ if (!e?.length) continue;
73
+ p = new Blob([e], { type: f }), l.set(d, p);
74
+ }
75
+ let m = n(a, "cNvPr"), h = m?.getAttribute("descr") || m?.getAttribute("name") || "工作表图片";
76
+ r.push({
77
+ id: `${e.sheetName}:${r.length}`,
78
+ alt: h,
79
+ blob: p,
80
+ anchor: u
81
+ });
82
+ }
83
+ r.length && a.set(e.sheetName, r);
84
+ }
85
+ return a;
86
+ }
87
+ function u(e, t, n) {
88
+ let r = (e, t, n) => e[t] ?? (e.at(-1) ?? 0) + Math.max(0, t - e.length + 1) * n;
89
+ if (e.kind === "absolute") return {
90
+ ...e,
91
+ left: e.left + (t[0] ?? 0),
92
+ top: e.top + (n[0] ?? 0)
93
+ };
94
+ let i = r(t, e.from.col, 80) + e.from.offX, a = r(n, e.from.row, 20) + e.from.offY;
95
+ if (e.kind === "oneCell") {
96
+ let r = t[e.from.col] != null && t[e.from.col] === t[e.from.col + 1] || n[e.from.row] != null && n[e.from.row] === n[e.from.row + 1];
97
+ return {
98
+ left: i,
99
+ top: a,
100
+ width: r ? 0 : e.width,
101
+ height: r ? 0 : e.height
102
+ };
103
+ }
104
+ return {
105
+ left: i,
106
+ top: a,
107
+ width: Math.max(0, r(t, e.to.col, 80) + e.to.offX - i),
108
+ height: Math.max(0, r(n, e.to.row, 20) + e.to.offY - a)
109
+ };
110
+ }
111
+ //#endregion
112
+ export { l as parseXlsxImages, u as xlsxImageBox };
113
+
114
+ //# sourceMappingURL=xlsxImages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xlsxImages.js","names":[],"sources":["../../src/lib/xlsxImages.ts"],"sourcesContent":["import { openXlsxParts, worksheetDrawings, tag, relationshipId } from '@/lib/xlsxParts'\n\nconst EMU_PER_PX = 9525\ninterface ImageMarker {\n col: number\n row: number\n offX: number\n offY: number\n}\nexport type XlsxImageAnchor =\n | { kind: 'oneCell'; from: ImageMarker; width: number; height: number }\n | { kind: 'twoCell'; from: ImageMarker; to: ImageMarker }\n | { kind: 'absolute'; left: number; top: number; width: number; height: number }\n\nexport interface XlsxImage {\n id: string\n alt: string\n blob: Blob\n anchor: XlsxImageAnchor\n}\n\nfunction number(value: string | null | undefined): number {\n if (value == null || value.trim() === '') return NaN\n return Number(value)\n}\n\nfunction marker(el: Element | undefined): ImageMarker | null {\n if (!el) return null\n const col = number(tag(el, 'col')?.textContent)\n const row = number(tag(el, 'row')?.textContent)\n const offX = number(tag(el, 'colOff')?.textContent) / EMU_PER_PX\n const offY = number(tag(el, 'rowOff')?.textContent) / EMU_PER_PX\n if (!Number.isInteger(col) || col < 0 || col >= 16384) return null\n if (!Number.isInteger(row) || row < 0 || row >= 1048576) return null\n return [offX, offY].every(Number.isFinite) ? { col, row, offX, offY } : null\n}\n\nfunction imageAnchor(el: Element): XlsxImageAnchor | null {\n const from = marker(tag(el, 'from'))\n if (el.localName === 'twoCellAnchor') {\n const to = marker(tag(el, 'to'))\n return from && to ? { kind: 'twoCell', from, to } : null\n }\n const ext = tag(el, 'ext')\n const width = number(ext?.getAttribute('cx')) / EMU_PER_PX\n const height = number(ext?.getAttribute('cy')) / EMU_PER_PX\n if (![width, height].every((n) => Number.isFinite(n) && n > 0)) return null\n if (el.localName === 'oneCellAnchor')\n return from ? { kind: 'oneCell', from, width, height } : null\n const pos = tag(el, 'pos')\n const left = number(pos?.getAttribute('x')) / EMU_PER_PX\n const top = number(pos?.getAttribute('y')) / EMU_PER_PX\n return [left, top].every(Number.isFinite) ? { kind: 'absolute', left, top, width, height } : null\n}\n\nconst IMAGE_MIMES: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n bmp: 'image/bmp',\n webp: 'image/webp',\n svg: 'image/svg+xml',\n}\n\n/** Read embedded images from original OOXML, independent of ExcelJS's prefix-sensitive drawing parser. */\nexport async function parseXlsxImages(buf: ArrayBuffer): Promise<Map<string, XlsxImage[]>> {\n const result = new Map<string, XlsxImage[]>()\n const parts = openXlsxParts(buf)\n if (!parts) return result\n const blobs = new Map<string, Blob>()\n for (const drawing of await worksheetDrawings(parts)) {\n const images = result.get(drawing.sheetName) ?? []\n // Preserve document order when one-/two-cell and absolute anchors are interleaved.\n for (const el of Array.from(drawing.doc.documentElement.children)) {\n if (!['oneCellAnchor', 'twoCellAnchor', 'absoluteAnchor'].includes(el.localName)) continue\n const pic = tag(el, 'pic')\n if (!pic) continue\n const anchor = imageAnchor(el)\n const path = drawing.rels.get(relationshipId(tag(pic, 'blip'), 'embed') || '')\n const mime = path ? IMAGE_MIMES[path.split('.').pop()!.toLowerCase()] : undefined\n if (!anchor || !path || !mime) continue\n let blob = blobs.get(path)\n if (!blob) {\n const bytes = await parts.bytes(path)\n if (!bytes?.length) continue\n blob = new Blob([bytes as Uint8Array<ArrayBuffer>], { type: mime })\n blobs.set(path, blob)\n }\n const properties = tag(pic, 'cNvPr')\n const alt =\n properties?.getAttribute('descr') || properties?.getAttribute('name') || '工作表图片'\n images.push({ id: `${drawing.sheetName}:${images.length}`, alt, blob, anchor })\n }\n if (images.length) result.set(drawing.sheetName, images)\n }\n return result\n}\n\n// Edges use zero-based worksheet cells and include the row/column header offsets.\nexport function xlsxImageBox(anchor: XlsxImageAnchor, cols: number[], rows: number[]) {\n const edge = (values: number[], at: number, size: number): number =>\n values[at] ?? (values.at(-1) ?? 0) + Math.max(0, at - values.length + 1) * size\n if (anchor.kind === 'absolute') {\n return { ...anchor, left: anchor.left + (cols[0] ?? 0), top: anchor.top + (rows[0] ?? 0) }\n }\n const left = edge(cols, anchor.from.col, 80) + anchor.from.offX\n const top = edge(rows, anchor.from.row, 20) + anchor.from.offY\n if (anchor.kind === 'oneCell') {\n const hidden =\n (cols[anchor.from.col] != null && cols[anchor.from.col] === cols[anchor.from.col + 1]) ||\n (rows[anchor.from.row] != null && rows[anchor.from.row] === rows[anchor.from.row + 1])\n return { left, top, width: hidden ? 0 : anchor.width, height: hidden ? 0 : anchor.height }\n }\n return {\n left,\n top,\n width: Math.max(0, edge(cols, anchor.to.col, 80) + anchor.to.offX - left),\n height: Math.max(0, edge(rows, anchor.to.row, 20) + anchor.to.offY - top),\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export declare function tags(el: Element | Document, localName: string): Element[];
2
+ export declare function tag(el: Element | Document, localName: string): Element | undefined;
3
+ export declare const dirOf: (path: string) => string;
4
+ export declare const relationshipId: (el: Element | undefined, attr?: string) => string | null;
5
+ export declare function relsMap(doc: Document | null, baseDir: string): Map<string, string>;
6
+ export interface XlsxParts {
7
+ xml: (path: string) => Promise<Document | null>;
8
+ bytes: (path: string) => Promise<Uint8Array | null>;
9
+ }
10
+ /** Lazy, cached access to the original workbook. Never fetches external relationships. */
11
+ export declare function openXlsxParts(buf: ArrayBuffer): XlsxParts | null;
12
+ export interface WorksheetDrawing {
13
+ sheetName: string;
14
+ doc: Document;
15
+ rels: Map<string, string>;
16
+ }
17
+ export declare function worksheetDrawings(parts: XlsxParts): Promise<WorksheetDrawing[]>;
@@ -0,0 +1,86 @@
1
+ import { extractZipEntry as e, readZip as t, zipSupported as n } from "./zip.js";
2
+ //#region src/lib/xlsxParts.ts
3
+ var r = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
4
+ function i(e, t) {
5
+ return Array.from(e.getElementsByTagNameNS("*", t));
6
+ }
7
+ function a(e, t) {
8
+ return e.getElementsByTagNameNS("*", t)[0];
9
+ }
10
+ var o = (e) => e.split("/").slice(0, -1).join("/"), s = (e, t = "id") => e?.getAttributeNS(r, t) || e?.getAttribute(`r:${t}`) || null;
11
+ function c(e, t) {
12
+ if (/^(?:[a-z][a-z\d+.-]*:|\/\/)/i.test(t)) return null;
13
+ let n = (t.startsWith("/") ? [] : e.split("/")).concat(t.split("/")), r = [];
14
+ for (let e of n) if (!(e === "" || e === ".")) if (e === "..") {
15
+ if (!r.length) return null;
16
+ r.pop();
17
+ } else r.push(e);
18
+ return r.join("/");
19
+ }
20
+ function l(e, t) {
21
+ let n = /* @__PURE__ */ new Map();
22
+ for (let r of e ? i(e, "Relationship") : []) {
23
+ if (r.getAttribute("TargetMode")?.toLowerCase() === "external") continue;
24
+ let e = r.getAttribute("Id"), i = r.getAttribute("Target"), a = i ? c(t, i) : null;
25
+ e && a && n.set(e, a);
26
+ }
27
+ return n;
28
+ }
29
+ function u(r) {
30
+ if (!n() || typeof DOMParser > "u") return null;
31
+ let i;
32
+ try {
33
+ i = t(r);
34
+ } catch {
35
+ return null;
36
+ }
37
+ let o = new Map(i.map((e) => [e.path, e])), s = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map(), l = (t) => {
38
+ let n = s.get(t);
39
+ if (!n) {
40
+ let i = o.get(t);
41
+ n = i ? e(r, i).catch(() => null) : Promise.resolve(null), s.set(t, n);
42
+ }
43
+ return n;
44
+ };
45
+ return {
46
+ bytes: l,
47
+ xml: (e) => {
48
+ let t = c.get(e);
49
+ return t || (t = l(e).then((e) => {
50
+ if (!e) return null;
51
+ let t = new DOMParser().parseFromString(new TextDecoder().decode(e), "application/xml");
52
+ return a(t, "parsererror") ? null : t;
53
+ }), c.set(e, t)), t;
54
+ }
55
+ };
56
+ }
57
+ async function d(e) {
58
+ let t = await e.xml("xl/workbook.xml");
59
+ if (!t) return [];
60
+ let n = l(await e.xml("xl/_rels/workbook.xml.rels"), "xl"), r = [];
61
+ for (let a of i(t, "sheet")) {
62
+ if (["hidden", "veryHidden"].includes(a.getAttribute("state") || "")) continue;
63
+ let t = n.get(s(a) || "");
64
+ if (!t) continue;
65
+ let c = await e.xml(t);
66
+ if (!c) continue;
67
+ let u = l(await e.xml(`${o(t)}/_rels/${t.split("/").pop()}.rels`), o(t));
68
+ for (let t of i(c, "drawing")) {
69
+ let n = u.get(s(t) || "");
70
+ if (!n) continue;
71
+ let i = await e.xml(n);
72
+ if (!i) continue;
73
+ let c = l(await e.xml(`${o(n)}/_rels/${n.split("/").pop()}.rels`), o(n));
74
+ r.push({
75
+ sheetName: a.getAttribute("name") || "",
76
+ doc: i,
77
+ rels: c
78
+ });
79
+ }
80
+ }
81
+ return r;
82
+ }
83
+ //#endregion
84
+ export { u as openXlsxParts, s as relationshipId, a as tag, i as tags, d as worksheetDrawings };
85
+
86
+ //# sourceMappingURL=xlsxParts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xlsxParts.js","names":[],"sources":["../../src/lib/xlsxParts.ts"],"sourcesContent":["import { extractZipEntry, readZip, zipSupported } from '@/lib/zip'\n\nconst REL_NS = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'\n\nexport function tags(el: Element | Document, localName: string): Element[] {\n return Array.from(el.getElementsByTagNameNS('*', localName))\n}\n\nexport function tag(el: Element | Document, localName: string): Element | undefined {\n return el.getElementsByTagNameNS('*', localName)[0]\n}\n\nexport const dirOf = (path: string): string => path.split('/').slice(0, -1).join('/')\nexport const relationshipId = (el: Element | undefined, attr = 'id'): string | null =>\n el?.getAttributeNS(REL_NS, attr) || el?.getAttribute(`r:${attr}`) || null\n\n// Package-absolute targets start at the ZIP root, not at the referring part's directory.\nfunction resolvePath(baseDir: string, target: string): string | null {\n if (/^(?:[a-z][a-z\\d+.-]*:|\\/\\/)/i.test(target)) return null\n const parts = (target.startsWith('/') ? [] : baseDir.split('/')).concat(target.split('/'))\n const out: string[] = []\n for (const p of parts) {\n if (p === '' || p === '.') continue\n if (p === '..') {\n if (!out.length) return null\n out.pop()\n } else out.push(p)\n }\n return out.join('/')\n}\n\nexport function relsMap(doc: Document | null, baseDir: string): Map<string, string> {\n const result = new Map<string, string>()\n for (const rel of doc ? tags(doc, 'Relationship') : []) {\n if (rel.getAttribute('TargetMode')?.toLowerCase() === 'external') continue\n const id = rel.getAttribute('Id')\n const target = rel.getAttribute('Target')\n const path = target ? resolvePath(baseDir, target) : null\n if (id && path) result.set(id, path)\n }\n return result\n}\n\nexport interface XlsxParts {\n xml: (path: string) => Promise<Document | null>\n bytes: (path: string) => Promise<Uint8Array | null>\n}\n\n/** Lazy, cached access to the original workbook. Never fetches external relationships. */\nexport function openXlsxParts(buf: ArrayBuffer): XlsxParts | null {\n if (!zipSupported() || typeof DOMParser === 'undefined') return null\n let entries\n try {\n entries = readZip(buf)\n } catch {\n return null\n }\n const byPath = new Map(entries.map((entry) => [entry.path, entry]))\n const byteCache = new Map<string, Promise<Uint8Array | null>>()\n const xmlCache = new Map<string, Promise<Document | null>>()\n const bytes: XlsxParts['bytes'] = (path) => {\n let value = byteCache.get(path)\n if (!value) {\n const entry = byPath.get(path)\n value = entry ? extractZipEntry(buf, entry).catch(() => null) : Promise.resolve(null)\n byteCache.set(path, value)\n }\n return value\n }\n const xml: XlsxParts['xml'] = (path) => {\n let value = xmlCache.get(path)\n if (!value) {\n value = bytes(path).then((data) => {\n if (!data) return null\n const doc = new DOMParser().parseFromString(\n new TextDecoder().decode(data),\n 'application/xml',\n )\n return tag(doc, 'parsererror') ? null : doc\n })\n xmlCache.set(path, value)\n }\n return value\n }\n return { bytes, xml }\n}\n\nexport interface WorksheetDrawing {\n sheetName: string\n doc: Document\n rels: Map<string, string>\n}\n\nexport async function worksheetDrawings(parts: XlsxParts): Promise<WorksheetDrawing[]> {\n const workbook = await parts.xml('xl/workbook.xml')\n if (!workbook) return []\n const workbookRels = relsMap(await parts.xml('xl/_rels/workbook.xml.rels'), 'xl')\n const result: WorksheetDrawing[] = []\n for (const sheet of tags(workbook, 'sheet')) {\n if (['hidden', 'veryHidden'].includes(sheet.getAttribute('state') || '')) continue\n const sheetPath = workbookRels.get(relationshipId(sheet) || '')\n if (!sheetPath) continue\n const sheetDoc = await parts.xml(sheetPath)\n if (!sheetDoc) continue\n const sheetRels = relsMap(\n await parts.xml(`${dirOf(sheetPath)}/_rels/${sheetPath.split('/').pop()}.rels`),\n dirOf(sheetPath),\n )\n for (const drawing of tags(sheetDoc, 'drawing')) {\n const drawingPath = sheetRels.get(relationshipId(drawing) || '')\n if (!drawingPath) continue\n const doc = await parts.xml(drawingPath)\n if (!doc) continue\n const rels = relsMap(\n await parts.xml(`${dirOf(drawingPath)}/_rels/${drawingPath.split('/').pop()}.rels`),\n dirOf(drawingPath),\n )\n result.push({ sheetName: sheet.getAttribute('name') || '', doc, rels })\n }\n }\n return result\n}\n"],"mappings":"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"}