@lotics/cli 0.55.0 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app_commands.d.ts +1 -1
- package/dist/client.d.ts +8 -0
- package/dist/client.js +59 -1
- package/dist/client.test.d.ts +1 -0
- package/dist/client.test.js +47 -0
- package/dist/dev/wrapper_page.d.ts +5 -3
- package/dist/dev/wrapper_page.js +33 -27
- package/dist/src/cli.js +1673 -1419
- package/dist/starter_template.js +16 -13
- package/package.json +1 -1
package/dist/src/cli.js
CHANGED
|
@@ -29586,6 +29586,19 @@ import readline from "node:readline";
|
|
|
29586
29586
|
// src/client.ts
|
|
29587
29587
|
import fs from "node:fs";
|
|
29588
29588
|
import path from "node:path";
|
|
29589
|
+
function gatewayErrorMessage(status) {
|
|
29590
|
+
if (status === 524) {
|
|
29591
|
+
return "The request took too long to finish (gateway timeout). It may still be running \u2014 check back in a moment, or try again.";
|
|
29592
|
+
}
|
|
29593
|
+
if (status >= 500) {
|
|
29594
|
+
return "The service is temporarily unavailable. Please try again shortly.";
|
|
29595
|
+
}
|
|
29596
|
+
return "The service returned an unexpected response. Please try again.";
|
|
29597
|
+
}
|
|
29598
|
+
function transportErrorMessage(status, parsed) {
|
|
29599
|
+
const jsonMessage = parsed && typeof parsed.message === "string" ? parsed.message : null;
|
|
29600
|
+
return parsed === null || status >= 500 || jsonMessage === null ? gatewayErrorMessage(status) : jsonMessage;
|
|
29601
|
+
}
|
|
29589
29602
|
function findAvailableFilename(dir, filename, reserved) {
|
|
29590
29603
|
const isTaken = (name) => {
|
|
29591
29604
|
const full = path.join(dir, name);
|
|
@@ -29785,11 +29798,25 @@ var LoticsClient = class {
|
|
|
29785
29798
|
* Mirrors POST /v1/apps/{app_id}/workflows/{alias}/execute.
|
|
29786
29799
|
*/
|
|
29787
29800
|
async appWorkflow(app_id, alias, inputs) {
|
|
29788
|
-
|
|
29789
|
-
|
|
29790
|
-
|
|
29791
|
-
|
|
29792
|
-
|
|
29801
|
+
const url = `${this.baseUrl}/v1/apps/${encodeURIComponent(app_id)}/workflows/${encodeURIComponent(alias)}/execute`;
|
|
29802
|
+
const headers = this.buildHeaders();
|
|
29803
|
+
headers["Content-Type"] = "application/json";
|
|
29804
|
+
let response;
|
|
29805
|
+
try {
|
|
29806
|
+
response = await fetch(url, { method: "POST", headers, body: JSON.stringify({ inputs }) });
|
|
29807
|
+
} catch (err2) {
|
|
29808
|
+
return { status: "error", message: err2 instanceof Error ? err2.message : "The workflow request failed." };
|
|
29809
|
+
}
|
|
29810
|
+
const text = await response.text();
|
|
29811
|
+
let parsed = null;
|
|
29812
|
+
if (text) {
|
|
29813
|
+
try {
|
|
29814
|
+
parsed = JSON.parse(text);
|
|
29815
|
+
} catch {
|
|
29816
|
+
}
|
|
29817
|
+
}
|
|
29818
|
+
if (response.ok) return parsed ?? {};
|
|
29819
|
+
return { status: "error", message: transportErrorMessage(response.status, parsed) };
|
|
29793
29820
|
}
|
|
29794
29821
|
/**
|
|
29795
29822
|
* Open a streaming agent run and return the RAW streamed `Response` (the
|
|
@@ -30574,10 +30601,10 @@ mount(
|
|
|
30574
30601
|
path: "src/App.tsx",
|
|
30575
30602
|
// Default scaffold = a minimal in-app router example (a list screen and a
|
|
30576
30603
|
// detail screen), so a new app starts with the recommended routing shape:
|
|
30577
|
-
// - The app uses react-router via `AppRouter` (from @lotics/app-sdk/router)
|
|
30578
|
-
//
|
|
30579
|
-
// host
|
|
30580
|
-
//
|
|
30604
|
+
// - The app uses react-router via `AppRouter` (from @lotics/app-sdk/router).
|
|
30605
|
+
// The app owns its own url — embedded, that's the iframe's own url (the
|
|
30606
|
+
// host never sees it, so navigation never reloads the app); standalone,
|
|
30607
|
+
// real path URLs. Browser Back/Forward walk app screens in both.
|
|
30581
30608
|
// - The full-container layout pattern is preserved in `Screen`: an outer
|
|
30582
30609
|
// <View flex:1> claims the iframe height (index.html sets
|
|
30583
30610
|
// html/body/#root to 100% + #root is a flex column). Keep that chain
|
|
@@ -30592,11 +30619,13 @@ import { Card } from "@lotics/ui/card";
|
|
|
30592
30619
|
import { Text } from "@lotics/ui/text";
|
|
30593
30620
|
import { Button } from "@lotics/ui/button";
|
|
30594
30621
|
|
|
30595
|
-
// AppRouter makes the app's screens real
|
|
30596
|
-
//
|
|
30597
|
-
//
|
|
30598
|
-
//
|
|
30599
|
-
//
|
|
30622
|
+
// AppRouter makes the app's screens real URLs \u2014 write plain react-router
|
|
30623
|
+
// (useNavigate / useParams / <Link>) and it handles both modes. The app owns its
|
|
30624
|
+
// own url, so navigation never reloads the app:
|
|
30625
|
+
// - Embedded in the Lotics host: the app drives the iframe's OWN url (invisible
|
|
30626
|
+
// to the user, never seen by the host). Browser Back / Forward walk app
|
|
30627
|
+
// screens; the screen is also mirrored to the host url, so it's shareable and
|
|
30628
|
+
// survives a full refresh (handled by AppRouter \u2014 no extra code).
|
|
30600
30629
|
// - Standalone at <slug>.lotics.app: a normal browser router with real path URLs.
|
|
30601
30630
|
|
|
30602
30631
|
const ITEMS = [
|
|
@@ -30843,10 +30872,11 @@ the full export list at https://www.npmjs.com/package/@lotics/ui.
|
|
|
30843
30872
|
## Routing
|
|
30844
30873
|
|
|
30845
30874
|
\`src/App.tsx\` ships a minimal in-app router. Write plain react-router and wrap
|
|
30846
|
-
your routes in \`AppRouter\` from \`@lotics/app-sdk/router\` \u2014
|
|
30847
|
-
|
|
30848
|
-
|
|
30849
|
-
|
|
30875
|
+
your routes in \`AppRouter\` from \`@lotics/app-sdk/router\` \u2014 the app owns its own
|
|
30876
|
+
url, so navigation never reloads the app. Embedded in the Lotics host it drives
|
|
30877
|
+
the iframe's own url (invisible to the user, never seen by the host); browser
|
|
30878
|
+
Back/Forward walk app screens, and the screen is mirrored to the host url so it's
|
|
30879
|
+
shareable and survives a full refresh. Standalone (\`<slug>.lotics.app\`) it's a
|
|
30850
30880
|
normal browser router with real path URLs. A single-screen app can drop the
|
|
30851
30881
|
router and render one screen directly.
|
|
30852
30882
|
|
|
@@ -31056,9 +31086,28 @@ function buildWrapperPage(args) {
|
|
|
31056
31086
|
const iframe = document.getElementById("app");
|
|
31057
31087
|
|
|
31058
31088
|
// Pass the wrapper's own origin to the app via ?lotics_host= so the app
|
|
31059
|
-
// SDK can origin-lock its postMessage bridge
|
|
31060
|
-
|
|
31061
|
-
|
|
31089
|
+
// SDK can origin-lock its postMessage bridge, and bake the saved screen
|
|
31090
|
+
// (the wrapper url's _loc, kept current by AppRouter's mirror) into the src
|
|
31091
|
+
// path so a refresh boots the app at that screen \u2014 mirrors the production
|
|
31092
|
+
// host. _loc is honoured only when it resolves same-origin to the Vite
|
|
31093
|
+
// server (a url param flowing into an iframe src is a redirect vector);
|
|
31094
|
+
// anything else falls back to the app root.
|
|
31095
|
+
const appSrc = new URL(VITE_URL);
|
|
31096
|
+
const savedLoc = new URLSearchParams(window.location.search).get("_loc");
|
|
31097
|
+
if (savedLoc) {
|
|
31098
|
+
try {
|
|
31099
|
+
const resolved = new URL(savedLoc, VITE_ORIGIN);
|
|
31100
|
+
if (resolved.origin === VITE_ORIGIN) {
|
|
31101
|
+
appSrc.pathname = resolved.pathname;
|
|
31102
|
+
appSrc.search = resolved.search;
|
|
31103
|
+
appSrc.hash = resolved.hash;
|
|
31104
|
+
}
|
|
31105
|
+
} catch (e) {
|
|
31106
|
+
// malformed _loc -> app root
|
|
31107
|
+
}
|
|
31108
|
+
}
|
|
31109
|
+
appSrc.searchParams.set("lotics_host", window.location.origin);
|
|
31110
|
+
iframe.src = appSrc.toString();
|
|
31062
31111
|
|
|
31063
31112
|
async function rpc(op, payload) {
|
|
31064
31113
|
const res = await fetch("/_rpc", {
|
|
@@ -31163,7 +31212,6 @@ function buildWrapperPage(args) {
|
|
|
31163
31212
|
});
|
|
31164
31213
|
return out;
|
|
31165
31214
|
}
|
|
31166
|
-
var lastPushAt = 0;
|
|
31167
31215
|
function handleUrlStateSet(payload) {
|
|
31168
31216
|
const params = (payload && payload.params) || {};
|
|
31169
31217
|
const sp = new URLSearchParams(window.location.search);
|
|
@@ -31176,21 +31224,9 @@ function buildWrapperPage(args) {
|
|
|
31176
31224
|
});
|
|
31177
31225
|
const qs = sp.toString();
|
|
31178
31226
|
const url = window.location.pathname + (qs ? "?" + qs : "") + window.location.hash;
|
|
31179
|
-
//
|
|
31180
|
-
//
|
|
31181
|
-
|
|
31182
|
-
const now = Date.now();
|
|
31183
|
-
if (payload && payload.push && now - lastPushAt > 100) {
|
|
31184
|
-
lastPushAt = now;
|
|
31185
|
-
window.history.pushState(null, "", url);
|
|
31186
|
-
} else {
|
|
31187
|
-
window.history.replaceState(null, "", url);
|
|
31188
|
-
}
|
|
31189
|
-
return undefined;
|
|
31190
|
-
}
|
|
31191
|
-
function handleUrlStateGo(payload) {
|
|
31192
|
-
const delta = payload && payload.delta;
|
|
31193
|
-
if (typeof delta === "number") window.history.go(delta);
|
|
31227
|
+
// View-state writes in place \u2014 never a history entry. replaceState doesn't
|
|
31228
|
+
// fire popstate, so no echo. Mirrors the production host.
|
|
31229
|
+
window.history.replaceState(null, "", url);
|
|
31194
31230
|
return undefined;
|
|
31195
31231
|
}
|
|
31196
31232
|
|
|
@@ -31259,8 +31295,6 @@ function buildWrapperPage(args) {
|
|
|
31259
31295
|
? readUrlParams()
|
|
31260
31296
|
: msg.op === "urlState.set"
|
|
31261
31297
|
? handleUrlStateSet(msg.payload)
|
|
31262
|
-
: msg.op === "urlState.go"
|
|
31263
|
-
? handleUrlStateGo(msg.payload)
|
|
31264
31298
|
: await rpc(msg.op, msg.payload);
|
|
31265
31299
|
const ms = Math.round(performance.now() - startedAt);
|
|
31266
31300
|
console.debug("[lotics-dev] " + msg.op + " " + ms + "ms", data);
|
|
@@ -31278,9 +31312,9 @@ function buildWrapperPage(args) {
|
|
|
31278
31312
|
}
|
|
31279
31313
|
});
|
|
31280
31314
|
|
|
31281
|
-
// Browser
|
|
31282
|
-
//
|
|
31283
|
-
//
|
|
31315
|
+
// Browser back/forward \u2192 broadcast the new params so useUrlState re-hydrates
|
|
31316
|
+
// (the app's own set writes use replaceState \u2014 no popstate \u2014 so there's no
|
|
31317
|
+
// echo). Mirrors the production host.
|
|
31284
31318
|
window.addEventListener("popstate", function () {
|
|
31285
31319
|
iframe.contentWindow.postMessage(
|
|
31286
31320
|
{ type: "url-state", params: readUrlParams() },
|
|
@@ -38659,8 +38693,8 @@ function parseWorkbook(workbookXml) {
|
|
|
38659
38693
|
}
|
|
38660
38694
|
return { sheets, activeSheetIndex, date1904, namedRanges, printTitlesBySheet, fullCalcOnLoad };
|
|
38661
38695
|
}
|
|
38662
|
-
function parseWorkbookRels(
|
|
38663
|
-
const doc = xmlParser3.parse(
|
|
38696
|
+
function parseWorkbookRels(relsXml2) {
|
|
38697
|
+
const doc = xmlParser3.parse(relsXml2);
|
|
38664
38698
|
const rels = doc?.["Relationships"];
|
|
38665
38699
|
if (!rels) return /* @__PURE__ */ new Map();
|
|
38666
38700
|
const relArr = rels["Relationship"];
|
|
@@ -39696,6 +39730,9 @@ function refToRowCol(ref) {
|
|
|
39696
39730
|
function rowColToRef(row, col) {
|
|
39697
39731
|
return colNumToLetters(col) + String(row);
|
|
39698
39732
|
}
|
|
39733
|
+
function escapeXml(s) {
|
|
39734
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
39735
|
+
}
|
|
39699
39736
|
var PACK_COL_BITS = 14;
|
|
39700
39737
|
var PACK_COL_MULT = 1 << PACK_COL_BITS;
|
|
39701
39738
|
function packRowCol(row, col) {
|
|
@@ -39867,8 +39904,8 @@ function parseHeaderFooterElement(worksheet) {
|
|
|
39867
39904
|
if (hf["@_differentFirst"] === "1") out.differentFirst = true;
|
|
39868
39905
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
39869
39906
|
}
|
|
39870
|
-
function parseSheetRels(
|
|
39871
|
-
const doc = relsParser.parse(
|
|
39907
|
+
function parseSheetRels(relsXml2) {
|
|
39908
|
+
const doc = relsParser.parse(relsXml2);
|
|
39872
39909
|
const relationships = doc?.["Relationships"];
|
|
39873
39910
|
if (!relationships) return /* @__PURE__ */ new Map();
|
|
39874
39911
|
const relArr = relationships["Relationship"];
|
|
@@ -40172,8 +40209,8 @@ function parseImages(rels, zipEntries) {
|
|
|
40172
40209
|
}
|
|
40173
40210
|
return images;
|
|
40174
40211
|
}
|
|
40175
|
-
function parseDrawingRels(
|
|
40176
|
-
const doc = relsParser.parse(
|
|
40212
|
+
function parseDrawingRels(relsXml2) {
|
|
40213
|
+
const doc = relsParser.parse(relsXml2);
|
|
40177
40214
|
const relationships = doc?.["Relationships"];
|
|
40178
40215
|
if (!relationships) return /* @__PURE__ */ new Map();
|
|
40179
40216
|
const relArr = relationships["Relationship"];
|
|
@@ -41851,1505 +41888,1722 @@ function parsePrintTitlesRef(raw) {
|
|
|
41851
41888
|
return result.repeatRows || result.repeatCols ? result : void 0;
|
|
41852
41889
|
}
|
|
41853
41890
|
|
|
41854
|
-
// ../xlsx/src/
|
|
41855
|
-
|
|
41856
|
-
|
|
41857
|
-
|
|
41858
|
-
const
|
|
41859
|
-
const
|
|
41860
|
-
const
|
|
41861
|
-
|
|
41862
|
-
|
|
41863
|
-
|
|
41891
|
+
// ../xlsx/src/pivot_recompute.ts
|
|
41892
|
+
var TOTAL_LABEL = "Grand Total";
|
|
41893
|
+
function recomputePivot(table, cache, source) {
|
|
41894
|
+
const records = filterByPageAxis(table, cache, source.records);
|
|
41895
|
+
const rowTuples = distinctTuples(records, table.rowFieldIndices);
|
|
41896
|
+
const colTuples = distinctTuples(records, table.colFieldIndices);
|
|
41897
|
+
const groupKey = (rec) => JSON.stringify([
|
|
41898
|
+
tupleOf(rec, table.rowFieldIndices),
|
|
41899
|
+
tupleOf(rec, table.colFieldIndices)
|
|
41900
|
+
]);
|
|
41901
|
+
const groups = /* @__PURE__ */ new Map();
|
|
41902
|
+
for (const rec of records) {
|
|
41903
|
+
const key = groupKey(rec);
|
|
41904
|
+
let bucket = groups.get(key);
|
|
41905
|
+
if (!bucket) {
|
|
41906
|
+
bucket = [];
|
|
41907
|
+
groups.set(key, bucket);
|
|
41908
|
+
}
|
|
41909
|
+
bucket.push(rec);
|
|
41864
41910
|
}
|
|
41865
|
-
return
|
|
41911
|
+
return buildGrid(table, source, rowTuples, colTuples, groups, records);
|
|
41866
41912
|
}
|
|
41867
|
-
function
|
|
41868
|
-
const
|
|
41869
|
-
const
|
|
41870
|
-
|
|
41871
|
-
|
|
41872
|
-
|
|
41873
|
-
|
|
41874
|
-
|
|
41875
|
-
|
|
41876
|
-
const id = /\bId="([^"]+)"/.exec(attrs)?.[1];
|
|
41877
|
-
const type = /\bType="([^"]+)"/.exec(attrs)?.[1] ?? "";
|
|
41878
|
-
const target = /\bTarget="([^"]+)"/.exec(attrs)?.[1] ?? "";
|
|
41879
|
-
if (id) out.set(id, { type, target });
|
|
41913
|
+
function filterByPageAxis(table, cache, records) {
|
|
41914
|
+
const filters = [];
|
|
41915
|
+
for (const fi of table.pageFieldIndices) {
|
|
41916
|
+
const cfg = table.fields[fi];
|
|
41917
|
+
if (cfg?.selectedPageItem == null) continue;
|
|
41918
|
+
const cacheField = cache.fields[fi];
|
|
41919
|
+
if (!cacheField) continue;
|
|
41920
|
+
const allowed = cacheField.items[cfg.selectedPageItem];
|
|
41921
|
+
if (allowed) filters.push({ fieldIndex: fi, allowed });
|
|
41880
41922
|
}
|
|
41881
|
-
return
|
|
41923
|
+
if (filters.length === 0) return records;
|
|
41924
|
+
return records.filter(
|
|
41925
|
+
(rec) => filters.every(
|
|
41926
|
+
({ fieldIndex, allowed }) => cellMatchesItem(rec[fieldIndex], allowed)
|
|
41927
|
+
)
|
|
41928
|
+
);
|
|
41882
41929
|
}
|
|
41883
|
-
function
|
|
41884
|
-
|
|
41885
|
-
|
|
41886
|
-
|
|
41887
|
-
|
|
41888
|
-
|
|
41889
|
-
|
|
41890
|
-
|
|
41891
|
-
|
|
41892
|
-
|
|
41893
|
-
|
|
41894
|
-
|
|
41895
|
-
|
|
41896
|
-
|
|
41930
|
+
function cellMatchesItem(cell, item) {
|
|
41931
|
+
switch (item.kind) {
|
|
41932
|
+
case "string":
|
|
41933
|
+
return typeof cell === "string" && cell === item.value;
|
|
41934
|
+
case "number":
|
|
41935
|
+
return typeof cell === "number" && cell === item.value;
|
|
41936
|
+
case "boolean":
|
|
41937
|
+
return typeof cell === "boolean" && cell === item.value;
|
|
41938
|
+
case "date":
|
|
41939
|
+
return typeof cell === "string" && cell === item.value;
|
|
41940
|
+
case "missing":
|
|
41941
|
+
return cell === void 0 || cell === null || cell === "";
|
|
41942
|
+
case "error":
|
|
41943
|
+
return typeof cell === "string" && cell === item.value;
|
|
41897
41944
|
}
|
|
41898
|
-
return out;
|
|
41899
41945
|
}
|
|
41900
|
-
function
|
|
41901
|
-
|
|
41902
|
-
|
|
41903
|
-
|
|
41904
|
-
|
|
41905
|
-
const xml = decode(bytes);
|
|
41906
|
-
const re = /<Relationship\b([^/]*?)\/>/g;
|
|
41946
|
+
function tupleOf(rec, indices) {
|
|
41947
|
+
return indices.map((i2) => rec[i2] ?? null);
|
|
41948
|
+
}
|
|
41949
|
+
function distinctTuples(records, indices) {
|
|
41950
|
+
const seen = /* @__PURE__ */ new Set();
|
|
41907
41951
|
const out = [];
|
|
41908
|
-
|
|
41909
|
-
|
|
41910
|
-
const
|
|
41911
|
-
|
|
41912
|
-
|
|
41913
|
-
|
|
41914
|
-
if (target) out.push(target);
|
|
41952
|
+
for (const rec of records) {
|
|
41953
|
+
const t = tupleOf(rec, indices);
|
|
41954
|
+
const key = JSON.stringify(t);
|
|
41955
|
+
if (seen.has(key)) continue;
|
|
41956
|
+
seen.add(key);
|
|
41957
|
+
out.push(t);
|
|
41915
41958
|
}
|
|
41959
|
+
out.sort((a, b) => {
|
|
41960
|
+
for (let i2 = 0; i2 < Math.max(a.length, b.length); i2++) {
|
|
41961
|
+
const av = a[i2];
|
|
41962
|
+
const bv = b[i2];
|
|
41963
|
+
if (av === bv) continue;
|
|
41964
|
+
const as = av === null || av === void 0 ? "" : String(av);
|
|
41965
|
+
const bs = bv === null || bv === void 0 ? "" : String(bv);
|
|
41966
|
+
if (as < bs) return -1;
|
|
41967
|
+
if (as > bs) return 1;
|
|
41968
|
+
}
|
|
41969
|
+
return 0;
|
|
41970
|
+
});
|
|
41916
41971
|
return out;
|
|
41917
41972
|
}
|
|
41918
|
-
function
|
|
41919
|
-
const
|
|
41920
|
-
|
|
41921
|
-
|
|
41922
|
-
|
|
41923
|
-
|
|
41924
|
-
|
|
41925
|
-
|
|
41926
|
-
|
|
41927
|
-
|
|
41928
|
-
|
|
41929
|
-
|
|
41930
|
-
|
|
41931
|
-
|
|
41932
|
-
|
|
41973
|
+
function aggregate(values2, fn) {
|
|
41974
|
+
const numeric = values2.filter((v) => typeof v === "number");
|
|
41975
|
+
switch (fn) {
|
|
41976
|
+
case "count":
|
|
41977
|
+
return values2.filter((v) => v !== null && v !== void 0 && v !== "").length;
|
|
41978
|
+
case "countNums":
|
|
41979
|
+
return numeric.length;
|
|
41980
|
+
case "sum":
|
|
41981
|
+
return numeric.reduce((a, b) => a + b, 0);
|
|
41982
|
+
case "average":
|
|
41983
|
+
if (numeric.length === 0) return null;
|
|
41984
|
+
return numeric.reduce((a, b) => a + b, 0) / numeric.length;
|
|
41985
|
+
case "min":
|
|
41986
|
+
return numeric.length === 0 ? null : Math.min(...numeric);
|
|
41987
|
+
case "max":
|
|
41988
|
+
return numeric.length === 0 ? null : Math.max(...numeric);
|
|
41989
|
+
case "product":
|
|
41990
|
+
return numeric.length === 0 ? null : numeric.reduce((a, b) => a * b, 1);
|
|
41933
41991
|
}
|
|
41934
|
-
|
|
41935
|
-
|
|
41936
|
-
|
|
41937
|
-
|
|
41938
|
-
|
|
41939
|
-
|
|
41992
|
+
}
|
|
41993
|
+
function buildGrid(table, source, rowTuples, colTuples, groups, allRecords) {
|
|
41994
|
+
const numRowFields = table.rowFieldIndices.length;
|
|
41995
|
+
const numColFields = table.colFieldIndices.length;
|
|
41996
|
+
const numDataFields = Math.max(table.dataFields.length, 1);
|
|
41997
|
+
const showRowGrand = table.display.colGrandTotals;
|
|
41998
|
+
const showColGrand = table.display.rowGrandTotals;
|
|
41999
|
+
const rowLabelCols = Math.max(numRowFields, 1);
|
|
42000
|
+
const colHeaderRows = numColFields + (numDataFields > 0 ? 1 : 0);
|
|
42001
|
+
const headerRows = Math.max(colHeaderRows, 1);
|
|
42002
|
+
const dataCols = colTuples.length * numDataFields;
|
|
42003
|
+
const totalCols = rowLabelCols + dataCols + (showColGrand ? numDataFields : 0);
|
|
42004
|
+
const totalRows = headerRows + rowTuples.length + (showRowGrand ? 1 : 0);
|
|
42005
|
+
const cells = [];
|
|
42006
|
+
for (let r = 0; r < totalRows; r++) {
|
|
42007
|
+
cells.push(new Array(totalCols).fill({ kind: "blank" }));
|
|
41940
42008
|
}
|
|
41941
|
-
|
|
41942
|
-
|
|
41943
|
-
|
|
41944
|
-
|
|
41945
|
-
|
|
41946
|
-
|
|
41947
|
-
|
|
42009
|
+
for (let level = 0; level < numColFields; level++) {
|
|
42010
|
+
let col = rowLabelCols;
|
|
42011
|
+
for (const tuple of colTuples) {
|
|
42012
|
+
const text = formatCellLabel(tuple[level]);
|
|
42013
|
+
for (let i2 = 0; i2 < numDataFields; i2++) {
|
|
42014
|
+
cells[level][col + i2] = { kind: "colHeader", depth: level, text };
|
|
42015
|
+
}
|
|
42016
|
+
col += numDataFields;
|
|
41948
42017
|
}
|
|
41949
42018
|
}
|
|
41950
|
-
|
|
41951
|
-
|
|
41952
|
-
|
|
41953
|
-
|
|
41954
|
-
|
|
41955
|
-
|
|
41956
|
-
|
|
41957
|
-
|
|
41958
|
-
|
|
41959
|
-
|
|
41960
|
-
|
|
42019
|
+
if (numDataFields > 0) {
|
|
42020
|
+
const labelRow = colHeaderRows - 1;
|
|
42021
|
+
let col = rowLabelCols;
|
|
42022
|
+
for (let _t = 0; _t < colTuples.length; _t++) {
|
|
42023
|
+
for (let d = 0; d < table.dataFields.length; d++) {
|
|
42024
|
+
cells[labelRow][col + d] = {
|
|
42025
|
+
kind: "valueLabel",
|
|
42026
|
+
text: table.dataFields[d].name
|
|
42027
|
+
};
|
|
42028
|
+
}
|
|
42029
|
+
col += numDataFields;
|
|
42030
|
+
}
|
|
42031
|
+
if (showColGrand) {
|
|
42032
|
+
for (let d = 0; d < table.dataFields.length; d++) {
|
|
42033
|
+
cells[labelRow][rowLabelCols + dataCols + d] = {
|
|
42034
|
+
kind: "valueLabel",
|
|
42035
|
+
text: table.dataFields[d].name
|
|
42036
|
+
};
|
|
42037
|
+
}
|
|
42038
|
+
}
|
|
41961
42039
|
}
|
|
41962
|
-
|
|
41963
|
-
|
|
41964
|
-
|
|
41965
|
-
|
|
41966
|
-
|
|
41967
|
-
|
|
41968
|
-
|
|
41969
|
-
|
|
41970
|
-
|
|
41971
|
-
const regeneratedPaths = /* @__PURE__ */ new Set();
|
|
41972
|
-
regeneratedPaths.add("xl/sharedStrings.xml");
|
|
41973
|
-
if (!stylesPassthrough) regeneratedPaths.add("xl/styles.xml");
|
|
41974
|
-
regeneratedPaths.add("xl/workbook.xml");
|
|
41975
|
-
regeneratedPaths.add("xl/_rels/workbook.xml.rels");
|
|
41976
|
-
regeneratedPaths.add("[Content_Types].xml");
|
|
41977
|
-
regeneratedPaths.add("_rels/.rels");
|
|
41978
|
-
regeneratedPaths.add("docProps/core.xml");
|
|
41979
|
-
regeneratedPaths.add("docProps/app.xml");
|
|
41980
|
-
for (let i2 = 0; i2 < workbook.sheets.length + 10; i2++) {
|
|
41981
|
-
regeneratedPaths.add(`xl/worksheets/sheet${i2 + 1}.xml`);
|
|
41982
|
-
regeneratedPaths.add(`xl/worksheets/_rels/sheet${i2 + 1}.xml.rels`);
|
|
41983
|
-
}
|
|
41984
|
-
for (const path7 of Object.keys(originalZip)) {
|
|
41985
|
-
if (path7.startsWith("xl/drawings/") || path7.startsWith("xl/charts/") || path7.startsWith("xl/tables/") || path7.startsWith("xl/media/")) {
|
|
41986
|
-
regeneratedPaths.add(path7);
|
|
41987
|
-
}
|
|
41988
|
-
}
|
|
41989
|
-
for (const [path7, data] of Object.entries(originalZip)) {
|
|
41990
|
-
if (!regeneratedPaths.has(path7)) entries[path7] = data;
|
|
42040
|
+
for (let r = 0; r < rowTuples.length; r++) {
|
|
42041
|
+
const rowTuple = rowTuples[r];
|
|
42042
|
+
const gridRow = headerRows + r;
|
|
42043
|
+
for (let level = 0; level < numRowFields; level++) {
|
|
42044
|
+
cells[gridRow][level] = {
|
|
42045
|
+
kind: "rowHeader",
|
|
42046
|
+
depth: level,
|
|
42047
|
+
text: formatCellLabel(rowTuple[level])
|
|
42048
|
+
};
|
|
41991
42049
|
}
|
|
41992
|
-
|
|
41993
|
-
|
|
41994
|
-
|
|
41995
|
-
|
|
41996
|
-
|
|
41997
|
-
|
|
41998
|
-
|
|
41999
|
-
|
|
42000
|
-
|
|
42001
|
-
|
|
42002
|
-
|
|
42003
|
-
for (const path7 of pivotInfo.pivotXmlPaths) {
|
|
42004
|
-
const ct = pivotContentTypeFor(path7);
|
|
42005
|
-
if (ct) extraContentTypes.push(ct);
|
|
42006
|
-
}
|
|
42007
|
-
let globalChartIndex = 1;
|
|
42008
|
-
let globalImageIndex = 1;
|
|
42009
|
-
let globalTableIndex = 1;
|
|
42010
|
-
for (let i2 = 0; i2 < workbook.sheets.length; i2++) {
|
|
42011
|
-
const sheet = workbook.sheets[i2];
|
|
42012
|
-
const sheetRels = [];
|
|
42013
|
-
let nextRId = 1;
|
|
42014
|
-
const hasCharts = sheet.charts.length > 0;
|
|
42015
|
-
const hasImages = sheet.images.length > 0;
|
|
42016
|
-
const hasDrawings = sheet.drawings.length > 0;
|
|
42017
|
-
const hasTables = sheet.tables.length > 0;
|
|
42018
|
-
const hasHyperlinks = sheet.hyperlinks.size > 0;
|
|
42019
|
-
const needsDrawing = hasCharts || hasImages || hasDrawings;
|
|
42020
|
-
const hyperlinkRIds = /* @__PURE__ */ new Map();
|
|
42021
|
-
if (hasHyperlinks) {
|
|
42022
|
-
for (const [ref, url] of sheet.hyperlinks) {
|
|
42023
|
-
const rId = `rId${nextRId++}`;
|
|
42024
|
-
hyperlinkRIds.set(ref, rId);
|
|
42025
|
-
sheetRels.push(`<Relationship Id="${rId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="${escapeXml(url)}" TargetMode="External"/>`);
|
|
42050
|
+
for (let c = 0; c < colTuples.length; c++) {
|
|
42051
|
+
const colTuple = colTuples[c];
|
|
42052
|
+
const groupRecords = groups.get(JSON.stringify([rowTuple, colTuple])) ?? [];
|
|
42053
|
+
for (let d = 0; d < table.dataFields.length; d++) {
|
|
42054
|
+
const df = table.dataFields[d];
|
|
42055
|
+
const values2 = groupRecords.map((rec) => rec[df.fieldIndex]);
|
|
42056
|
+
cells[gridRow][rowLabelCols + c * numDataFields + d] = {
|
|
42057
|
+
kind: "value",
|
|
42058
|
+
value: aggregate(values2, df.subtotal),
|
|
42059
|
+
numFmt: df.numFmt
|
|
42060
|
+
};
|
|
42026
42061
|
}
|
|
42027
42062
|
}
|
|
42028
|
-
|
|
42029
|
-
|
|
42030
|
-
|
|
42031
|
-
sheetRels.push(`<Relationship Id="${drawingRId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing" Target="../drawings/drawing${i2 + 1}.xml"/>`);
|
|
42032
|
-
const drawingRels = [];
|
|
42033
|
-
let drawingRelId = 1;
|
|
42034
|
-
const drawingAnchors = [];
|
|
42035
|
-
for (const chart of sheet.charts) {
|
|
42036
|
-
const chartRId = `rId${drawingRelId++}`;
|
|
42037
|
-
const chartPath = `xl/charts/chart${globalChartIndex}.xml`;
|
|
42038
|
-
entries[chartPath] = strToU8(buildChartXml(chart));
|
|
42039
|
-
extraContentTypes.push(`<Override PartName="/${chartPath}" ContentType="application/vnd.openxmlformats-officedocument.drawingml.chart+xml"/>`);
|
|
42040
|
-
drawingRels.push(`<Relationship Id="${chartRId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart" Target="../charts/chart${globalChartIndex}.xml"/>`);
|
|
42041
|
-
drawingAnchors.push(buildChartAnchorXml(chart, chartRId));
|
|
42042
|
-
globalChartIndex++;
|
|
42043
|
-
}
|
|
42044
|
-
for (const image of sheet.images) {
|
|
42045
|
-
const imgRId = `rId${drawingRelId++}`;
|
|
42046
|
-
const ext = getImageExtension(image.dataUrl);
|
|
42047
|
-
const imgPath = `xl/media/image${globalImageIndex}.${ext}`;
|
|
42048
|
-
const imgBytes = dataUrlToBytes(image.dataUrl);
|
|
42049
|
-
if (imgBytes) {
|
|
42050
|
-
entries[imgPath] = imgBytes;
|
|
42051
|
-
drawingRels.push(`<Relationship Id="${imgRId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="../media/image${globalImageIndex}.${ext}"/>`);
|
|
42052
|
-
drawingAnchors.push(buildImageAnchorXml(image, imgRId));
|
|
42053
|
-
globalImageIndex++;
|
|
42054
|
-
}
|
|
42055
|
-
}
|
|
42056
|
-
for (const drawing of sheet.drawings) {
|
|
42057
|
-
drawingAnchors.push(buildShapeAnchorXml(drawing));
|
|
42058
|
-
}
|
|
42059
|
-
entries[`xl/drawings/drawing${i2 + 1}.xml`] = strToU8(
|
|
42060
|
-
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42061
|
-
<xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart">
|
|
42062
|
-
` + drawingAnchors.join("\n") + `
|
|
42063
|
-
</xdr:wsDr>`
|
|
42063
|
+
if (showColGrand) {
|
|
42064
|
+
const rowOnly = allRecords.filter(
|
|
42065
|
+
(rec) => sameTuple(tupleOf(rec, table.rowFieldIndices), rowTuple)
|
|
42064
42066
|
);
|
|
42065
|
-
|
|
42066
|
-
|
|
42067
|
-
|
|
42068
|
-
|
|
42069
|
-
|
|
42070
|
-
|
|
42071
|
-
|
|
42072
|
-
|
|
42067
|
+
for (let d = 0; d < table.dataFields.length; d++) {
|
|
42068
|
+
const df = table.dataFields[d];
|
|
42069
|
+
cells[gridRow][rowLabelCols + dataCols + d] = {
|
|
42070
|
+
kind: "rowTotal",
|
|
42071
|
+
value: aggregate(
|
|
42072
|
+
rowOnly.map((rec) => rec[df.fieldIndex]),
|
|
42073
|
+
df.subtotal
|
|
42074
|
+
)
|
|
42075
|
+
};
|
|
42073
42076
|
}
|
|
42074
42077
|
}
|
|
42075
|
-
|
|
42076
|
-
|
|
42077
|
-
|
|
42078
|
-
|
|
42079
|
-
|
|
42080
|
-
|
|
42081
|
-
|
|
42082
|
-
|
|
42083
|
-
|
|
42084
|
-
|
|
42078
|
+
}
|
|
42079
|
+
if (showRowGrand) {
|
|
42080
|
+
const gridRow = headerRows + rowTuples.length;
|
|
42081
|
+
cells[gridRow][0] = { kind: "totalLabel", text: TOTAL_LABEL };
|
|
42082
|
+
for (let c = 0; c < colTuples.length; c++) {
|
|
42083
|
+
const colTuple = colTuples[c];
|
|
42084
|
+
const colOnly = allRecords.filter(
|
|
42085
|
+
(rec) => sameTuple(tupleOf(rec, table.colFieldIndices), colTuple)
|
|
42086
|
+
);
|
|
42087
|
+
for (let d = 0; d < table.dataFields.length; d++) {
|
|
42088
|
+
const df = table.dataFields[d];
|
|
42089
|
+
cells[gridRow][rowLabelCols + c * numDataFields + d] = {
|
|
42090
|
+
kind: "colTotal",
|
|
42091
|
+
value: aggregate(
|
|
42092
|
+
colOnly.map((rec) => rec[df.fieldIndex]),
|
|
42093
|
+
df.subtotal
|
|
42094
|
+
)
|
|
42095
|
+
};
|
|
42085
42096
|
}
|
|
42086
42097
|
}
|
|
42087
|
-
|
|
42088
|
-
|
|
42089
|
-
|
|
42090
|
-
|
|
42091
|
-
|
|
42092
|
-
|
|
42093
|
-
|
|
42098
|
+
if (showColGrand) {
|
|
42099
|
+
for (let d = 0; d < table.dataFields.length; d++) {
|
|
42100
|
+
const df = table.dataFields[d];
|
|
42101
|
+
cells[gridRow][rowLabelCols + dataCols + d] = {
|
|
42102
|
+
kind: "grandTotal",
|
|
42103
|
+
value: aggregate(
|
|
42104
|
+
allRecords.map((rec) => rec[df.fieldIndex]),
|
|
42105
|
+
df.subtotal
|
|
42106
|
+
)
|
|
42107
|
+
};
|
|
42094
42108
|
}
|
|
42095
42109
|
}
|
|
42096
|
-
if (sheetRels.length > 0) {
|
|
42097
|
-
entries[`xl/worksheets/_rels/sheet${i2 + 1}.xml.rels`] = strToU8(
|
|
42098
|
-
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42099
|
-
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
42100
|
-
${sheetRels.join("\n")}
|
|
42101
|
-
</Relationships>`
|
|
42102
|
-
);
|
|
42103
|
-
}
|
|
42104
|
-
entries[`xl/worksheets/sheet${i2 + 1}.xml`] = strToU8(
|
|
42105
|
-
buildSheetXml(sheet, workbook.styles, sharedStrings.index, i2 === workbook.activeSheetIndex, stylesResult.xfMap, stylesResult.numFmtMap, stylesResult.dxfMap, drawingRId, tableRIds, hyperlinkRIds)
|
|
42106
|
-
);
|
|
42107
42110
|
}
|
|
42108
|
-
|
|
42109
|
-
|
|
42110
|
-
|
|
42111
|
-
|
|
42112
|
-
|
|
42111
|
+
void source;
|
|
42112
|
+
return {
|
|
42113
|
+
cells,
|
|
42114
|
+
headerRows,
|
|
42115
|
+
rowLabelCols,
|
|
42116
|
+
rows: totalRows,
|
|
42117
|
+
cols: totalCols
|
|
42118
|
+
};
|
|
42113
42119
|
}
|
|
42114
|
-
function
|
|
42115
|
-
|
|
42116
|
-
|
|
42117
|
-
|
|
42118
|
-
|
|
42119
|
-
|
|
42120
|
-
|
|
42121
|
-
if (cell.error) continue;
|
|
42122
|
-
if (cell.formula && typeof cell.value === "string") continue;
|
|
42123
|
-
if (typeof cell.value === "string") {
|
|
42124
|
-
totalCount++;
|
|
42125
|
-
if (!index.has(cell.value)) {
|
|
42126
|
-
index.set(cell.value, strings.length);
|
|
42127
|
-
strings.push(cell.value);
|
|
42128
|
-
if (cell.richText && cell.richText.length > 0) {
|
|
42129
|
-
richTextMap.set(cell.value, cell.richText);
|
|
42130
|
-
}
|
|
42131
|
-
}
|
|
42132
|
-
}
|
|
42133
|
-
}
|
|
42134
|
-
}
|
|
42135
|
-
const siEntries = strings.map((s) => {
|
|
42136
|
-
const richText = richTextMap.get(s);
|
|
42137
|
-
if (richText) {
|
|
42138
|
-
return `<si>${richText.map((part) => buildRichTextRun(part)).join("")}</si>`;
|
|
42120
|
+
function sameTuple(a, b) {
|
|
42121
|
+
if (a.length !== b.length) return false;
|
|
42122
|
+
for (let i2 = 0; i2 < a.length; i2++) {
|
|
42123
|
+
if (a[i2] !== b[i2]) {
|
|
42124
|
+
const an = a[i2] === void 0 || a[i2] === null || a[i2] === "";
|
|
42125
|
+
const bn = b[i2] === void 0 || b[i2] === null || b[i2] === "";
|
|
42126
|
+
if (!(an && bn)) return false;
|
|
42139
42127
|
}
|
|
42140
|
-
const needsPreserve = s.length === 0 || s !== s.trim();
|
|
42141
|
-
const spaceAttr = needsPreserve ? ' xml:space="preserve"' : "";
|
|
42142
|
-
return `<si><t${spaceAttr}>${escapeXml(s)}</t></si>`;
|
|
42143
|
-
});
|
|
42144
|
-
const xml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42145
|
-
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="${totalCount}" uniqueCount="${strings.length}">
|
|
42146
|
-
${siEntries.join("\n")}
|
|
42147
|
-
</sst>`;
|
|
42148
|
-
return { xml, index };
|
|
42149
|
-
}
|
|
42150
|
-
function buildRichTextRun(part) {
|
|
42151
|
-
const needsPreserve = part.text.length === 0 || part.text !== part.text.trim();
|
|
42152
|
-
const spaceAttr = needsPreserve ? ' xml:space="preserve"' : "";
|
|
42153
|
-
if (!part.font) {
|
|
42154
|
-
return `<r><t${spaceAttr}>${escapeXml(part.text)}</t></r>`;
|
|
42155
42128
|
}
|
|
42156
|
-
return
|
|
42129
|
+
return true;
|
|
42157
42130
|
}
|
|
42158
|
-
function
|
|
42159
|
-
|
|
42160
|
-
if (
|
|
42161
|
-
|
|
42162
|
-
if (font.strike) parts += "<strike/>";
|
|
42163
|
-
if (font.underline) parts += `<u val="${font.underline}"/>`;
|
|
42164
|
-
if (font.vertAlign) parts += `<vertAlign val="${font.vertAlign}"/>`;
|
|
42165
|
-
if (font.size) parts += `<sz val="${font.size}"/>`;
|
|
42166
|
-
if (font.color) parts += `<color rgb="${hexToArgb(font.color)}"/>`;
|
|
42167
|
-
if (font.name) parts += `<rFont val="${escapeXml(font.name)}"/>`;
|
|
42168
|
-
return `<rPr>${parts}</rPr>`;
|
|
42131
|
+
function formatCellLabel(v) {
|
|
42132
|
+
if (v === void 0 || v === null || v === "") return "(blank)";
|
|
42133
|
+
if (typeof v === "boolean") return v ? "TRUE" : "FALSE";
|
|
42134
|
+
return String(v);
|
|
42169
42135
|
}
|
|
42170
|
-
|
|
42171
|
-
|
|
42172
|
-
|
|
42173
|
-
|
|
42136
|
+
|
|
42137
|
+
// ../xlsx/src/pivot_model.ts
|
|
42138
|
+
var PivotTableModel = class {
|
|
42139
|
+
constructor(config, cache, authored = false) {
|
|
42140
|
+
this.config = config;
|
|
42141
|
+
this.cache = cache;
|
|
42142
|
+
this.authored = authored;
|
|
42174
42143
|
}
|
|
42175
|
-
|
|
42176
|
-
|
|
42177
|
-
|
|
42178
|
-
|
|
42179
|
-
|
|
42180
|
-
|
|
42181
|
-
|
|
42182
|
-
|
|
42183
|
-
|
|
42144
|
+
/**
|
|
42145
|
+
* Recompute the pivot result from the workbook's current source data.
|
|
42146
|
+
* Callers are responsible for triggering recomputation; the model does
|
|
42147
|
+
* not subscribe to workbook changes itself.
|
|
42148
|
+
*/
|
|
42149
|
+
recompute(workbook) {
|
|
42150
|
+
const source = readSourceData(workbook, this.cache);
|
|
42151
|
+
if (!source) {
|
|
42152
|
+
this.result = void 0;
|
|
42153
|
+
return;
|
|
42184
42154
|
}
|
|
42155
|
+
this.result = recomputePivot(this.config, this.cache, source);
|
|
42185
42156
|
}
|
|
42186
|
-
|
|
42187
|
-
|
|
42188
|
-
|
|
42189
|
-
|
|
42190
|
-
|
|
42191
|
-
|
|
42192
|
-
|
|
42193
|
-
|
|
42157
|
+
};
|
|
42158
|
+
function readSourceData(workbook, cache) {
|
|
42159
|
+
if (cache.source.type !== "worksheet") return void 0;
|
|
42160
|
+
const source = cache.source;
|
|
42161
|
+
const sheet = workbook.sheets.find((s) => s.name === source.sheetName);
|
|
42162
|
+
if (!sheet) return void 0;
|
|
42163
|
+
const range = parseRange(source.ref);
|
|
42164
|
+
if (!range) return void 0;
|
|
42165
|
+
const header = [];
|
|
42166
|
+
for (let col = range.startCol; col <= range.endCol; col++) {
|
|
42167
|
+
const cell = sheet.getCell(rowColToRef(range.startRow, col));
|
|
42168
|
+
header.push(formatHeader(cell?.value));
|
|
42194
42169
|
}
|
|
42195
|
-
const
|
|
42196
|
-
|
|
42197
|
-
|
|
42198
|
-
|
|
42199
|
-
|
|
42200
|
-
|
|
42201
|
-
if (!fonts.has(key)) {
|
|
42202
|
-
fonts.set(key, fontList.length);
|
|
42203
|
-
fontList.push(s);
|
|
42170
|
+
const records = [];
|
|
42171
|
+
for (let row = range.startRow + 1; row <= range.endRow; row++) {
|
|
42172
|
+
const rec = [];
|
|
42173
|
+
for (let col = range.startCol; col <= range.endCol; col++) {
|
|
42174
|
+
const cell = sheet.getCell(rowColToRef(row, col));
|
|
42175
|
+
rec.push(coerceValue(cell?.value));
|
|
42204
42176
|
}
|
|
42177
|
+
records.push(rec);
|
|
42205
42178
|
}
|
|
42206
|
-
|
|
42207
|
-
|
|
42208
|
-
|
|
42209
|
-
|
|
42210
|
-
|
|
42211
|
-
|
|
42212
|
-
|
|
42213
|
-
|
|
42214
|
-
|
|
42215
|
-
|
|
42216
|
-
}
|
|
42217
|
-
const borderEntries = [];
|
|
42218
|
-
const borderMap = /* @__PURE__ */ new Map();
|
|
42219
|
-
borderEntries.push("<border><left/><right/><top/><bottom/><diagonal/></border>");
|
|
42220
|
-
borderMap.set("", 0);
|
|
42221
|
-
for (const s of styles) {
|
|
42222
|
-
const bk = borderKey(s);
|
|
42223
|
-
if (bk === "" || borderMap.has(bk)) continue;
|
|
42224
|
-
borderMap.set(bk, borderEntries.length);
|
|
42225
|
-
borderEntries.push(buildBorderXml(s));
|
|
42226
|
-
}
|
|
42227
|
-
const fontsXml = fontList.map((f) => buildFontXml(f)).join("\n");
|
|
42228
|
-
const fillsXml = fillEntries.join("\n");
|
|
42229
|
-
const bordersXml = borderEntries.join("\n");
|
|
42230
|
-
let numFmtsXml = "";
|
|
42231
|
-
if (numFmtMap.size > 0) {
|
|
42232
|
-
const entries = Array.from(numFmtMap.entries()).map(([code, id]) => `<numFmt numFmtId="${id}" formatCode="${escapeXml(code)}"/>`).join("\n");
|
|
42233
|
-
numFmtsXml = `<numFmts count="${numFmtMap.size}">
|
|
42234
|
-
${entries}
|
|
42235
|
-
</numFmts>
|
|
42236
|
-
`;
|
|
42237
|
-
}
|
|
42238
|
-
const xfEntries = [];
|
|
42239
|
-
const xfMap = /* @__PURE__ */ new Map();
|
|
42240
|
-
for (let styleIdx = 0; styleIdx < styles.length; styleIdx++) {
|
|
42241
|
-
const s = styles[styleIdx];
|
|
42242
|
-
const fontId = fonts.get(fontKey(s)) ?? 0;
|
|
42243
|
-
const fillId = fillMap.get(fillKey(s)) ?? 0;
|
|
42244
|
-
const borderId = borderMap.get(borderKey(s)) ?? 0;
|
|
42245
|
-
const xfKey = `${styleIdx}:0`;
|
|
42246
|
-
xfMap.set(xfKey, xfEntries.length);
|
|
42247
|
-
xfEntries.push(buildXfXml(s, fontId, fillId, borderId, 0));
|
|
42179
|
+
return { header, records };
|
|
42180
|
+
}
|
|
42181
|
+
function formatHeader(v) {
|
|
42182
|
+
if (v === void 0 || v === null) return "";
|
|
42183
|
+
return String(v);
|
|
42184
|
+
}
|
|
42185
|
+
function coerceValue(v) {
|
|
42186
|
+
if (v === void 0 || v === null) return void 0;
|
|
42187
|
+
if (typeof v === "string" || typeof v === "number" || typeof v === "boolean") {
|
|
42188
|
+
return v;
|
|
42248
42189
|
}
|
|
42249
|
-
|
|
42250
|
-
|
|
42251
|
-
|
|
42252
|
-
|
|
42253
|
-
|
|
42254
|
-
|
|
42255
|
-
|
|
42256
|
-
|
|
42257
|
-
|
|
42258
|
-
|
|
42259
|
-
|
|
42260
|
-
|
|
42190
|
+
return String(v);
|
|
42191
|
+
}
|
|
42192
|
+
function parseRange(ref) {
|
|
42193
|
+
const range = ref.includes("!") ? ref.split("!")[1] : ref;
|
|
42194
|
+
const cleaned = range.replace(/\$/g, "");
|
|
42195
|
+
const m = cleaned.match(/^([A-Z]+\d+)(?::([A-Z]+\d+))?$/);
|
|
42196
|
+
if (!m) return void 0;
|
|
42197
|
+
const start = refToRowCol(m[1]);
|
|
42198
|
+
if (!start) return void 0;
|
|
42199
|
+
const endRef = m[2] ?? m[1];
|
|
42200
|
+
const end = refToRowCol(endRef);
|
|
42201
|
+
if (!end) return void 0;
|
|
42202
|
+
return {
|
|
42203
|
+
startRow: start.row,
|
|
42204
|
+
startCol: start.col,
|
|
42205
|
+
endRow: end.row,
|
|
42206
|
+
endCol: end.col
|
|
42207
|
+
};
|
|
42208
|
+
}
|
|
42209
|
+
|
|
42210
|
+
// ../xlsx/src/pivot_writer.ts
|
|
42211
|
+
var MAIN_NS = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
|
|
42212
|
+
var REL_NS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
42213
|
+
function sourceValueToItem(v) {
|
|
42214
|
+
if (v === void 0 || v === null || v === "") return { kind: "missing" };
|
|
42215
|
+
if (typeof v === "number") return { kind: "number", value: v };
|
|
42216
|
+
if (typeof v === "boolean") return { kind: "boolean", value: v };
|
|
42217
|
+
return { kind: "string", value: v };
|
|
42218
|
+
}
|
|
42219
|
+
function cacheItemKey(item) {
|
|
42220
|
+
switch (item.kind) {
|
|
42221
|
+
case "missing":
|
|
42222
|
+
return "m:";
|
|
42223
|
+
case "number":
|
|
42224
|
+
return `n:${item.value}`;
|
|
42225
|
+
case "boolean":
|
|
42226
|
+
return `b:${item.value}`;
|
|
42227
|
+
case "string":
|
|
42228
|
+
return `s:${item.value}`;
|
|
42229
|
+
case "date":
|
|
42230
|
+
return `d:${item.value}`;
|
|
42231
|
+
case "error":
|
|
42232
|
+
return `e:${item.value}`;
|
|
42261
42233
|
}
|
|
42262
|
-
|
|
42263
|
-
|
|
42264
|
-
|
|
42265
|
-
|
|
42266
|
-
|
|
42267
|
-
|
|
42268
|
-
|
|
42269
|
-
|
|
42270
|
-
|
|
42271
|
-
|
|
42272
|
-
|
|
42234
|
+
}
|
|
42235
|
+
function enumerateFlags(table, fieldCount) {
|
|
42236
|
+
const axis = /* @__PURE__ */ new Set([...table.rowFieldIndices, ...table.colFieldIndices, ...table.pageFieldIndices]);
|
|
42237
|
+
return Array.from({ length: fieldCount }, (_, i2) => axis.has(i2));
|
|
42238
|
+
}
|
|
42239
|
+
function buildPivotCacheRecordsXml(records, cache, enumerate) {
|
|
42240
|
+
const indexMaps = cache.fields.map((f, i2) => {
|
|
42241
|
+
if (!enumerate[i2]) return void 0;
|
|
42242
|
+
const m = /* @__PURE__ */ new Map();
|
|
42243
|
+
f.items.forEach((item, idx) => m.set(cacheItemKey(item), idx));
|
|
42244
|
+
return m;
|
|
42245
|
+
});
|
|
42246
|
+
const rows = records.map((rec) => {
|
|
42247
|
+
const cells = cache.fields.map((_f, i2) => {
|
|
42248
|
+
const item = sourceValueToItem(rec[i2]);
|
|
42249
|
+
const map2 = indexMaps[i2];
|
|
42250
|
+
if (map2) {
|
|
42251
|
+
const idx = map2.get(cacheItemKey(item));
|
|
42252
|
+
if (idx === void 0) {
|
|
42253
|
+
throw new Error(
|
|
42254
|
+
`buildPivotCacheRecordsXml: value ${JSON.stringify(rec[i2])} for field "${cache.fields[i2].name}" is missing from its cached shared items`
|
|
42255
|
+
);
|
|
42273
42256
|
}
|
|
42257
|
+
return `<x v="${idx}"/>`;
|
|
42274
42258
|
}
|
|
42275
|
-
|
|
42276
|
-
|
|
42277
|
-
|
|
42278
|
-
|
|
42279
|
-
|
|
42280
|
-
${
|
|
42281
|
-
</dxfs>`;
|
|
42282
|
-
}
|
|
42283
|
-
const xml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42284
|
-
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
|
|
42285
|
-
${numFmtsXml}<fonts count="${fontList.length}">
|
|
42286
|
-
${fontsXml}
|
|
42287
|
-
</fonts>
|
|
42288
|
-
<fills count="${fillEntries.length}">
|
|
42289
|
-
${fillsXml}
|
|
42290
|
-
</fills>
|
|
42291
|
-
<borders count="${borderEntries.length}">
|
|
42292
|
-
${bordersXml}
|
|
42293
|
-
</borders>
|
|
42294
|
-
<cellStyleXfs count="1">
|
|
42295
|
-
<xf numFmtId="0" fontId="0" fillId="0" borderId="0"/>
|
|
42296
|
-
</cellStyleXfs>
|
|
42297
|
-
<cellXfs count="${xfEntries.length}">
|
|
42298
|
-
${xfEntries.join("\n")}
|
|
42299
|
-
</cellXfs>
|
|
42300
|
-
<cellStyles count="1">
|
|
42301
|
-
<cellStyle name="Normal" xfId="0" builtinId="0"/>
|
|
42302
|
-
</cellStyles>
|
|
42303
|
-
${dxfsXml}
|
|
42304
|
-
</styleSheet>`;
|
|
42305
|
-
return { xml, xfMap, numFmtMap, dxfMap };
|
|
42259
|
+
return inlineRecordCell(item);
|
|
42260
|
+
});
|
|
42261
|
+
return `<r>${cells.join("")}</r>`;
|
|
42262
|
+
});
|
|
42263
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42264
|
+
<pivotCacheRecords xmlns="${MAIN_NS}" xmlns:r="${REL_NS}" count="${records.length}">` + rows.join("") + `</pivotCacheRecords>`;
|
|
42306
42265
|
}
|
|
42307
|
-
function
|
|
42308
|
-
|
|
42309
|
-
|
|
42310
|
-
|
|
42311
|
-
|
|
42312
|
-
|
|
42313
|
-
|
|
42314
|
-
|
|
42315
|
-
|
|
42316
|
-
|
|
42317
|
-
|
|
42318
|
-
|
|
42319
|
-
|
|
42320
|
-
|
|
42266
|
+
function inlineRecordCell(item) {
|
|
42267
|
+
switch (item.kind) {
|
|
42268
|
+
case "missing":
|
|
42269
|
+
return "<m/>";
|
|
42270
|
+
case "number":
|
|
42271
|
+
return `<n v="${item.value}"/>`;
|
|
42272
|
+
case "boolean":
|
|
42273
|
+
return `<b v="${item.value ? 1 : 0}"/>`;
|
|
42274
|
+
case "date":
|
|
42275
|
+
return `<d v="${escapeXml(item.value)}"/>`;
|
|
42276
|
+
case "error":
|
|
42277
|
+
return `<e v="${escapeXml(item.value)}"/>`;
|
|
42278
|
+
case "string":
|
|
42279
|
+
return `<s v="${escapeXml(item.value)}"/>`;
|
|
42321
42280
|
}
|
|
42322
|
-
return `<xf ${attrs}/>`;
|
|
42323
|
-
}
|
|
42324
|
-
function fontKey(s) {
|
|
42325
|
-
return `${s.fontName ?? ""}|${s.fontSize ?? 0}|${s.fontBold ? 1 : 0}|${s.fontItalic ? 1 : 0}|${s.fontColor ?? ""}|${s.fontUnderline ?? ""}|${s.fontStrike ? 1 : 0}`;
|
|
42326
42281
|
}
|
|
42327
|
-
function
|
|
42328
|
-
|
|
42329
|
-
|
|
42330
|
-
|
|
42331
|
-
|
|
42332
|
-
|
|
42333
|
-
|
|
42334
|
-
|
|
42335
|
-
|
|
42336
|
-
|
|
42337
|
-
|
|
42282
|
+
function buildPivotCacheDefinitionXml(cache, enumerate, recordCount, recordsRelId) {
|
|
42283
|
+
if (cache.source.type !== "worksheet") {
|
|
42284
|
+
throw new Error("buildPivotCacheDefinitionXml: only worksheet sources are supported");
|
|
42285
|
+
}
|
|
42286
|
+
const src = cache.source;
|
|
42287
|
+
const fields = cache.fields.map((f, i2) => cacheFieldXml(f, enumerate[i2])).join("");
|
|
42288
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42289
|
+
<pivotCacheDefinition xmlns="${MAIN_NS}" xmlns:r="${REL_NS}" r:id="${recordsRelId}" refreshOnLoad="1" refreshedBy="Lotics" createdVersion="6" refreshedVersion="6" minRefreshableVersion="3" recordCount="${recordCount}"><cacheSource type="worksheet"><worksheetSource ref="${escapeXml(src.ref)}" sheet="${escapeXml(src.sheetName)}"/></cacheSource><cacheFields count="${cache.fields.length}">${fields}</cacheFields></pivotCacheDefinition>`;
|
|
42290
|
+
}
|
|
42291
|
+
function cacheFieldXml(field, enumerate) {
|
|
42292
|
+
const name = `name="${escapeXml(field.name)}" numFmtId="0"`;
|
|
42293
|
+
if (!enumerate) {
|
|
42294
|
+
const flags = `containsBlank="${field.items.length === 0 ? 0 : 1}"` + (field.containsNumber ? ` containsString="0" containsNumber="1"` : "");
|
|
42295
|
+
return `<cacheField ${name}><sharedItems ${flags}/></cacheField>`;
|
|
42296
|
+
}
|
|
42297
|
+
const items = field.items.map(sharedItemXml).join("");
|
|
42298
|
+
const hasString = field.items.some((i2) => i2.kind === "string");
|
|
42299
|
+
const hasNumber = field.items.some((i2) => i2.kind === "number");
|
|
42300
|
+
const hasBlank = field.items.some((i2) => i2.kind === "missing");
|
|
42301
|
+
const attrs = `count="${field.items.length}"` + (hasBlank ? ` containsBlank="1"` : "") + (hasNumber && !hasString ? ` containsString="0" containsNumber="1"` : "");
|
|
42302
|
+
return `<cacheField ${name}><sharedItems ${attrs}>${items}</sharedItems></cacheField>`;
|
|
42303
|
+
}
|
|
42304
|
+
function sharedItemXml(item) {
|
|
42305
|
+
switch (item.kind) {
|
|
42306
|
+
case "missing":
|
|
42307
|
+
return `<m/>`;
|
|
42308
|
+
case "number":
|
|
42309
|
+
return `<n v="${item.value}"/>`;
|
|
42310
|
+
case "boolean":
|
|
42311
|
+
return `<b v="${item.value ? 1 : 0}"/>`;
|
|
42312
|
+
case "date":
|
|
42313
|
+
return `<d v="${escapeXml(item.value)}"/>`;
|
|
42314
|
+
case "error":
|
|
42315
|
+
return `<e v="${escapeXml(item.value)}"/>`;
|
|
42316
|
+
case "string":
|
|
42317
|
+
return `<s v="${escapeXml(item.value)}"/>`;
|
|
42338
42318
|
}
|
|
42339
|
-
parts += `<name val="${escapeXml(s.fontName ?? "Calibri")}"/>`;
|
|
42340
|
-
return `<font>${parts}</font>`;
|
|
42341
42319
|
}
|
|
42342
|
-
|
|
42343
|
-
|
|
42344
|
-
|
|
42345
|
-
|
|
42346
|
-
|
|
42347
|
-
|
|
42348
|
-
|
|
42349
|
-
|
|
42350
|
-
|
|
42351
|
-
|
|
42320
|
+
var SUBTOTAL_FN_TO_ENUM = {
|
|
42321
|
+
sum: "sum",
|
|
42322
|
+
count: "count",
|
|
42323
|
+
countNums: "countNums",
|
|
42324
|
+
average: "average",
|
|
42325
|
+
min: "min",
|
|
42326
|
+
max: "max",
|
|
42327
|
+
product: "product"
|
|
42328
|
+
};
|
|
42329
|
+
function buildPivotTableXml(table, cache) {
|
|
42330
|
+
const rowField = table.rowFieldIndices[0];
|
|
42331
|
+
const colField = table.colFieldIndices[0];
|
|
42332
|
+
if (rowField === void 0 || colField === void 0) {
|
|
42333
|
+
throw new Error("buildPivotTableXml: a row field and a column field are required");
|
|
42334
|
+
}
|
|
42335
|
+
const pageSet = new Set(table.pageFieldIndices);
|
|
42336
|
+
const pivotFields = cache.fields.map((f, i2) => {
|
|
42337
|
+
const onAxis = i2 === rowField ? "axisRow" : i2 === colField ? "axisCol" : pageSet.has(i2) ? "axisPage" : void 0;
|
|
42338
|
+
if (onAxis) return axisPivotFieldXml(onAxis, f.items.length);
|
|
42339
|
+
if (table.dataFields.some((d) => d.fieldIndex === i2)) {
|
|
42340
|
+
return `<pivotField dataField="1" showAll="0"/>`;
|
|
42341
|
+
}
|
|
42342
|
+
return `<pivotField showAll="0"/>`;
|
|
42343
|
+
}).join("");
|
|
42344
|
+
const rowCount = cache.fields[rowField].items.length;
|
|
42345
|
+
const colCount = cache.fields[colField].items.length;
|
|
42346
|
+
const rowItems = axisItemsXml("rowItems", rowCount, table.display.colGrandTotals);
|
|
42347
|
+
const colItems = axisItemsXml("colItems", colCount, table.display.rowGrandTotals);
|
|
42348
|
+
const pageFieldsXml = table.pageFieldIndices.length ? `<pageFields count="${table.pageFieldIndices.length}">` + table.pageFieldIndices.map((fld) => {
|
|
42349
|
+
const sel = table.fields[fld]?.selectedPageItem;
|
|
42350
|
+
const item = sel === null || sel === void 0 ? "" : ` item="${sel}"`;
|
|
42351
|
+
return `<pageField fld="${fld}"${item} hier="-1"/>`;
|
|
42352
|
+
}).join("") + `</pageFields>` : "";
|
|
42353
|
+
const dataFieldsXml = `<dataFields count="${table.dataFields.length}">` + table.dataFields.map((d) => {
|
|
42354
|
+
const fn = SUBTOTAL_FN_TO_ENUM[d.subtotal] ?? "sum";
|
|
42355
|
+
const sub = fn === "sum" ? "" : ` subtotal="${fn}"`;
|
|
42356
|
+
const numFmt = d.numFmt ? ` numFmtId="${escapeXml(d.numFmt)}"` : "";
|
|
42357
|
+
return `<dataField name="${escapeXml(d.name)}" fld="${d.fieldIndex}"${sub} baseField="0" baseItem="0"${numFmt}/>`;
|
|
42358
|
+
}).join("") + `</dataFields>`;
|
|
42359
|
+
const style = `<pivotTableStyleInfo name="${escapeXml(table.styleName ?? "PivotStyleLight16")}" showRowHeaders="1" showColHeaders="1" showRowStripes="${table.display.showRowStripes ? 1 : 0}" showColStripes="${table.display.showColStripes ? 1 : 0}" showLastColumn="1"/>`;
|
|
42360
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42361
|
+
<pivotTableDefinition xmlns="${MAIN_NS}" xmlns:r="${REL_NS}" name="${escapeXml(table.name)}" cacheId="${table.cacheId}" applyNumberFormats="0" applyBorderFormats="0" applyFontFormats="0" applyPatternFormats="0" applyAlignmentFormats="0" applyWidthHeightFormats="1" dataCaption="Values" updatedVersion="6" minRefreshableVersion="3" useAutoFormatting="1" itemPrintTitles="1" createdVersion="6" indent="0" outline="1" outlineData="1" multipleFieldFilters="0" rowGrandTotals="${table.display.rowGrandTotals ? 1 : 0}" colGrandTotals="${table.display.colGrandTotals ? 1 : 0}"><location ref="${escapeXml(table.ref)}" firstHeaderRow="${table.firstHeaderRow}" firstDataRow="${table.firstDataRow}" firstDataCol="${table.firstDataCol}"/><pivotFields count="${cache.fields.length}">${pivotFields}</pivotFields><rowFields count="1"><field x="${rowField}"/></rowFields>` + rowItems + `<colFields count="1"><field x="${colField}"/></colFields>` + colItems + pageFieldsXml + dataFieldsXml + style + `</pivotTableDefinition>`;
|
|
42352
42362
|
}
|
|
42353
|
-
function
|
|
42354
|
-
const
|
|
42355
|
-
|
|
42356
|
-
|
|
42357
|
-
|
|
42358
|
-
|
|
42359
|
-
|
|
42360
|
-
|
|
42361
|
-
|
|
42362
|
-
|
|
42363
|
-
|
|
42364
|
-
|
|
42365
|
-
|
|
42366
|
-
|
|
42367
|
-
|
|
42368
|
-
];
|
|
42369
|
-
if (
|
|
42370
|
-
|
|
42371
|
-
|
|
42372
|
-
|
|
42373
|
-
|
|
42363
|
+
function axisPivotFieldXml(axis, itemCount) {
|
|
42364
|
+
const items = [];
|
|
42365
|
+
for (let i2 = 0; i2 < itemCount; i2++) items.push(`<item x="${i2}"/>`);
|
|
42366
|
+
items.push(`<item t="default"/>`);
|
|
42367
|
+
return `<pivotField axis="${axis}" showAll="0"><items count="${items.length}">${items.join("")}</items></pivotField>`;
|
|
42368
|
+
}
|
|
42369
|
+
function axisItemsXml(element, itemCount, grandTotal) {
|
|
42370
|
+
const items = [];
|
|
42371
|
+
for (let i2 = 0; i2 < itemCount; i2++) items.push(`<i><x v="${i2}"/></i>`);
|
|
42372
|
+
if (grandTotal) items.push(`<i t="grand"><x/></i>`);
|
|
42373
|
+
return `<${element} count="${items.length}">${items.join("")}</${element}>`;
|
|
42374
|
+
}
|
|
42375
|
+
|
|
42376
|
+
// ../xlsx/src/xlsx_writer.ts
|
|
42377
|
+
function readWorkbookSheetOrder(originalZip) {
|
|
42378
|
+
const wbBytes = originalZip["xl/workbook.xml"];
|
|
42379
|
+
if (!wbBytes) return [];
|
|
42380
|
+
const xml = decode(wbBytes);
|
|
42381
|
+
const out = [];
|
|
42382
|
+
const re = /<sheet\b[^>]*?r:id="([^"]+)"/g;
|
|
42383
|
+
let m;
|
|
42384
|
+
while ((m = re.exec(xml)) !== null) {
|
|
42385
|
+
out.push(m[1]);
|
|
42374
42386
|
}
|
|
42375
|
-
|
|
42376
|
-
if (border2.style === "dotted") return "dotted";
|
|
42377
|
-
if (border2.style === "double") return "double";
|
|
42378
|
-
return "thin";
|
|
42387
|
+
return out;
|
|
42379
42388
|
}
|
|
42380
|
-
function
|
|
42381
|
-
|
|
42382
|
-
|
|
42383
|
-
if (
|
|
42384
|
-
const
|
|
42385
|
-
|
|
42386
|
-
|
|
42387
|
-
|
|
42388
|
-
|
|
42389
|
-
|
|
42390
|
-
|
|
42391
|
-
|
|
42392
|
-
if (
|
|
42393
|
-
|
|
42394
|
-
|
|
42395
|
-
|
|
42396
|
-
|
|
42389
|
+
function readWorkbookRels(originalZip) {
|
|
42390
|
+
const out = /* @__PURE__ */ new Map();
|
|
42391
|
+
const bytes = originalZip["xl/_rels/workbook.xml.rels"];
|
|
42392
|
+
if (!bytes) return out;
|
|
42393
|
+
const xml = decode(bytes);
|
|
42394
|
+
const re = /<Relationship\b([^/]*?)\/>/g;
|
|
42395
|
+
let m;
|
|
42396
|
+
while ((m = re.exec(xml)) !== null) {
|
|
42397
|
+
const attrs = m[1];
|
|
42398
|
+
const id = /\bId="([^"]+)"/.exec(attrs)?.[1];
|
|
42399
|
+
const type = /\bType="([^"]+)"/.exec(attrs)?.[1] ?? "";
|
|
42400
|
+
const target = /\bTarget="([^"]+)"/.exec(attrs)?.[1] ?? "";
|
|
42401
|
+
if (id) out.set(id, { type, target });
|
|
42402
|
+
}
|
|
42403
|
+
return out;
|
|
42404
|
+
}
|
|
42405
|
+
function readPivotCacheIdMap(originalZip) {
|
|
42406
|
+
const out = /* @__PURE__ */ new Map();
|
|
42407
|
+
const bytes = originalZip["xl/workbook.xml"];
|
|
42408
|
+
if (!bytes) return out;
|
|
42409
|
+
const xml = decode(bytes);
|
|
42410
|
+
const re = /<pivotCache\b([^/]*?)\/>/g;
|
|
42411
|
+
let m;
|
|
42412
|
+
while ((m = re.exec(xml)) !== null) {
|
|
42413
|
+
const attrs = m[1];
|
|
42414
|
+
const cacheIdMatch = /\bcacheId="(\d+)"/.exec(attrs);
|
|
42415
|
+
const ridMatch = /\br:id="([^"]+)"/.exec(attrs);
|
|
42416
|
+
if (cacheIdMatch && ridMatch) {
|
|
42417
|
+
out.set(parseInt(cacheIdMatch[1], 10), ridMatch[1]);
|
|
42397
42418
|
}
|
|
42398
|
-
|
|
42399
|
-
|
|
42400
|
-
return `<border${attrs}>${inner}</border>`;
|
|
42419
|
+
}
|
|
42420
|
+
return out;
|
|
42401
42421
|
}
|
|
42402
|
-
function
|
|
42403
|
-
|
|
42404
|
-
|
|
42405
|
-
|
|
42406
|
-
return
|
|
42422
|
+
function readSheetPivotPaths(originalZip, sheetTarget) {
|
|
42423
|
+
const sheetPath = `xl/${sheetTarget}`;
|
|
42424
|
+
const relsPath = sheetPath.replace(/([^/]+)$/, "_rels/$1.rels");
|
|
42425
|
+
const bytes = originalZip[relsPath];
|
|
42426
|
+
if (!bytes) return [];
|
|
42427
|
+
const xml = decode(bytes);
|
|
42428
|
+
const re = /<Relationship\b([^/]*?)\/>/g;
|
|
42429
|
+
const out = [];
|
|
42430
|
+
let m;
|
|
42431
|
+
while ((m = re.exec(xml)) !== null) {
|
|
42432
|
+
const attrs = m[1];
|
|
42433
|
+
const type = /\bType="([^"]+)"/.exec(attrs)?.[1] ?? "";
|
|
42434
|
+
if (!type.includes("/pivotTable")) continue;
|
|
42435
|
+
const target = /\bTarget="([^"]+)"/.exec(attrs)?.[1];
|
|
42436
|
+
if (target) out.push(target);
|
|
42437
|
+
}
|
|
42438
|
+
return out;
|
|
42407
42439
|
}
|
|
42408
|
-
function
|
|
42409
|
-
|
|
42410
|
-
|
|
42411
|
-
|
|
42412
|
-
|
|
42413
|
-
|
|
42414
|
-
|
|
42415
|
-
|
|
42416
|
-
|
|
42417
|
-
|
|
42418
|
-
|
|
42440
|
+
function extractPivotRoundTripInfo(originalZip) {
|
|
42441
|
+
const empty = {
|
|
42442
|
+
cachesByWorkbook: /* @__PURE__ */ new Map(),
|
|
42443
|
+
pivotTablesBySheetIndex: /* @__PURE__ */ new Map(),
|
|
42444
|
+
pivotXmlPaths: []
|
|
42445
|
+
};
|
|
42446
|
+
if (!originalZip) return empty;
|
|
42447
|
+
const sheetRIds = readWorkbookSheetOrder(originalZip);
|
|
42448
|
+
const wbRels = readWorkbookRels(originalZip);
|
|
42449
|
+
const cacheRIds = readPivotCacheIdMap(originalZip);
|
|
42450
|
+
const cachesByWorkbook = /* @__PURE__ */ new Map();
|
|
42451
|
+
for (const [cacheId, rid] of cacheRIds) {
|
|
42452
|
+
const rel = wbRels.get(rid);
|
|
42453
|
+
if (!rel) continue;
|
|
42454
|
+
cachesByWorkbook.set(cacheId, rel.target);
|
|
42419
42455
|
}
|
|
42420
|
-
|
|
42421
|
-
|
|
42422
|
-
|
|
42423
|
-
if (
|
|
42424
|
-
|
|
42425
|
-
|
|
42456
|
+
const pivotTablesBySheetIndex = /* @__PURE__ */ new Map();
|
|
42457
|
+
for (let i2 = 0; i2 < sheetRIds.length; i2++) {
|
|
42458
|
+
const sheetTarget = wbRels.get(sheetRIds[i2])?.target;
|
|
42459
|
+
if (!sheetTarget) continue;
|
|
42460
|
+
const paths = readSheetPivotPaths(originalZip, sheetTarget);
|
|
42461
|
+
if (paths.length > 0) pivotTablesBySheetIndex.set(i2, paths);
|
|
42426
42462
|
}
|
|
42427
|
-
|
|
42463
|
+
const pivotXmlPaths = [];
|
|
42464
|
+
for (const path7 of Object.keys(originalZip)) {
|
|
42465
|
+
if (path7.startsWith("xl/pivotTables/") && path7.endsWith(".xml")) {
|
|
42466
|
+
pivotXmlPaths.push(path7);
|
|
42467
|
+
}
|
|
42468
|
+
if (path7.startsWith("xl/pivotCache/") && path7.endsWith(".xml")) {
|
|
42469
|
+
pivotXmlPaths.push(path7);
|
|
42470
|
+
}
|
|
42471
|
+
}
|
|
42472
|
+
return { cachesByWorkbook, pivotTablesBySheetIndex, pivotXmlPaths };
|
|
42428
42473
|
}
|
|
42429
|
-
function
|
|
42430
|
-
|
|
42431
|
-
|
|
42432
|
-
|
|
42474
|
+
function decode(bytes) {
|
|
42475
|
+
return new TextDecoder().decode(bytes);
|
|
42476
|
+
}
|
|
42477
|
+
function pivotContentTypeFor(path7) {
|
|
42478
|
+
if (path7.startsWith("xl/pivotTables/") && path7.endsWith(".xml")) {
|
|
42479
|
+
return `<Override PartName="/${path7}" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml"/>`;
|
|
42433
42480
|
}
|
|
42434
|
-
|
|
42435
|
-
|
|
42436
|
-
return { fg: hexMatches[0], bg: hexMatches[1] };
|
|
42481
|
+
if (path7.includes("/pivotCacheDefinition") && path7.endsWith(".xml")) {
|
|
42482
|
+
return `<Override PartName="/${path7}" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml"/>`;
|
|
42437
42483
|
}
|
|
42438
|
-
|
|
42484
|
+
if (path7.includes("/pivotCacheRecords") && path7.endsWith(".xml")) {
|
|
42485
|
+
return `<Override PartName="/${path7}" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml"/>`;
|
|
42486
|
+
}
|
|
42487
|
+
return void 0;
|
|
42439
42488
|
}
|
|
42440
|
-
|
|
42441
|
-
|
|
42442
|
-
|
|
42443
|
-
|
|
42444
|
-
|
|
42445
|
-
|
|
42446
|
-
|
|
42447
|
-
|
|
42448
|
-
|
|
42449
|
-
|
|
42489
|
+
var REL_BASE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
42490
|
+
function relsXml(rels) {
|
|
42491
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42492
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
42493
|
+
` + rels.map((r) => `<Relationship Id="${r.id}" Type="${r.type}" Target="${escapeXml(r.target)}"/>`).join("\n") + `
|
|
42494
|
+
</Relationships>`;
|
|
42495
|
+
}
|
|
42496
|
+
function emitAuthoredPivots(workbook, entries, startFileIndex) {
|
|
42497
|
+
const info = {
|
|
42498
|
+
cachesByWorkbook: /* @__PURE__ */ new Map(),
|
|
42499
|
+
pivotTablesBySheetIndex: /* @__PURE__ */ new Map(),
|
|
42500
|
+
pivotXmlPaths: []
|
|
42501
|
+
};
|
|
42502
|
+
let n = startFileIndex;
|
|
42503
|
+
for (let i2 = 0; i2 < workbook.sheets.length; i2++) {
|
|
42504
|
+
for (const model of workbook.sheets[i2].pivotTables) {
|
|
42505
|
+
if (!model.authored) continue;
|
|
42506
|
+
const idx = n++;
|
|
42507
|
+
const enumerate = enumerateFlags(model.config, model.cache.fields.length);
|
|
42508
|
+
const records = readSourceData(workbook, model.cache)?.records ?? [];
|
|
42509
|
+
const cacheDefPath = `xl/pivotCache/pivotCacheDefinition${idx}.xml`;
|
|
42510
|
+
const recordsPath = `xl/pivotCache/pivotCacheRecords${idx}.xml`;
|
|
42511
|
+
const tablePath = `xl/pivotTables/pivotTable${idx}.xml`;
|
|
42512
|
+
entries[cacheDefPath] = strToU8(buildPivotCacheDefinitionXml(model.cache, enumerate, records.length, "rId1"));
|
|
42513
|
+
entries[`xl/pivotCache/_rels/pivotCacheDefinition${idx}.xml.rels`] = strToU8(
|
|
42514
|
+
relsXml([{ id: "rId1", type: `${REL_BASE}/pivotCacheRecords`, target: `pivotCacheRecords${idx}.xml` }])
|
|
42515
|
+
);
|
|
42516
|
+
entries[recordsPath] = strToU8(buildPivotCacheRecordsXml(records, model.cache, enumerate));
|
|
42517
|
+
entries[tablePath] = strToU8(buildPivotTableXml(model.config, model.cache));
|
|
42518
|
+
entries[`xl/pivotTables/_rels/pivotTable${idx}.xml.rels`] = strToU8(
|
|
42519
|
+
relsXml([{ id: "rId1", type: `${REL_BASE}/pivotCacheDefinition`, target: `../pivotCache/pivotCacheDefinition${idx}.xml` }])
|
|
42520
|
+
);
|
|
42521
|
+
info.cachesByWorkbook.set(model.cache.id, `pivotCache/pivotCacheDefinition${idx}.xml`);
|
|
42522
|
+
const list = info.pivotTablesBySheetIndex.get(i2) ?? [];
|
|
42523
|
+
list.push(`../pivotTables/pivotTable${idx}.xml`);
|
|
42524
|
+
info.pivotTablesBySheetIndex.set(i2, list);
|
|
42525
|
+
info.pivotXmlPaths.push(tablePath, cacheDefPath, recordsPath);
|
|
42450
42526
|
}
|
|
42451
|
-
arr.push({ col: rc.col, cell });
|
|
42452
42527
|
}
|
|
42453
|
-
|
|
42454
|
-
|
|
42455
|
-
|
|
42456
|
-
|
|
42457
|
-
|
|
42458
|
-
|
|
42459
|
-
|
|
42460
|
-
|
|
42461
|
-
|
|
42462
|
-
|
|
42463
|
-
|
|
42464
|
-
|
|
42465
|
-
|
|
42466
|
-
|
|
42467
|
-
|
|
42468
|
-
|
|
42469
|
-
|
|
42470
|
-
|
|
42471
|
-
|
|
42472
|
-
|
|
42473
|
-
|
|
42474
|
-
|
|
42475
|
-
|
|
42476
|
-
|
|
42477
|
-
|
|
42478
|
-
|
|
42479
|
-
|
|
42480
|
-
|
|
42528
|
+
return info;
|
|
42529
|
+
}
|
|
42530
|
+
function mergePivotInfo(a, b) {
|
|
42531
|
+
const cachesByWorkbook = new Map(a.cachesByWorkbook);
|
|
42532
|
+
for (const [k, v] of b.cachesByWorkbook) cachesByWorkbook.set(k, v);
|
|
42533
|
+
const pivotTablesBySheetIndex = /* @__PURE__ */ new Map();
|
|
42534
|
+
for (const [k, v] of a.pivotTablesBySheetIndex) pivotTablesBySheetIndex.set(k, [...v]);
|
|
42535
|
+
for (const [k, v] of b.pivotTablesBySheetIndex) {
|
|
42536
|
+
pivotTablesBySheetIndex.set(k, [...pivotTablesBySheetIndex.get(k) ?? [], ...v]);
|
|
42537
|
+
}
|
|
42538
|
+
return { cachesByWorkbook, pivotTablesBySheetIndex, pivotXmlPaths: [...a.pivotXmlPaths, ...b.pivotXmlPaths] };
|
|
42539
|
+
}
|
|
42540
|
+
function exportWorkbook(workbook, originalZip) {
|
|
42541
|
+
const entries = {};
|
|
42542
|
+
const stylesPassthrough = !!originalZip && !workbook.styles.dirty && !!originalZip["xl/styles.xml"];
|
|
42543
|
+
if (originalZip) {
|
|
42544
|
+
const regeneratedPaths = /* @__PURE__ */ new Set();
|
|
42545
|
+
regeneratedPaths.add("xl/sharedStrings.xml");
|
|
42546
|
+
if (!stylesPassthrough) regeneratedPaths.add("xl/styles.xml");
|
|
42547
|
+
regeneratedPaths.add("xl/workbook.xml");
|
|
42548
|
+
regeneratedPaths.add("xl/_rels/workbook.xml.rels");
|
|
42549
|
+
regeneratedPaths.add("[Content_Types].xml");
|
|
42550
|
+
regeneratedPaths.add("_rels/.rels");
|
|
42551
|
+
regeneratedPaths.add("docProps/core.xml");
|
|
42552
|
+
regeneratedPaths.add("docProps/app.xml");
|
|
42553
|
+
for (let i2 = 0; i2 < workbook.sheets.length + 10; i2++) {
|
|
42554
|
+
regeneratedPaths.add(`xl/worksheets/sheet${i2 + 1}.xml`);
|
|
42555
|
+
regeneratedPaths.add(`xl/worksheets/_rels/sheet${i2 + 1}.xml.rels`);
|
|
42556
|
+
}
|
|
42557
|
+
for (const path7 of Object.keys(originalZip)) {
|
|
42558
|
+
if (path7.startsWith("xl/drawings/") || path7.startsWith("xl/charts/") || path7.startsWith("xl/tables/") || path7.startsWith("xl/media/")) {
|
|
42559
|
+
regeneratedPaths.add(path7);
|
|
42560
|
+
}
|
|
42561
|
+
}
|
|
42562
|
+
for (const [path7, data] of Object.entries(originalZip)) {
|
|
42563
|
+
if (!regeneratedPaths.has(path7)) entries[path7] = data;
|
|
42564
|
+
}
|
|
42565
|
+
}
|
|
42566
|
+
const sharedStrings = buildSharedStrings(workbook);
|
|
42567
|
+
entries["xl/sharedStrings.xml"] = strToU8(sharedStrings.xml);
|
|
42568
|
+
const stylesResult = stylesPassthrough ? { xml: "", xfMap: /* @__PURE__ */ new Map(), numFmtMap: /* @__PURE__ */ new Map(), dxfMap: /* @__PURE__ */ new Map() } : buildStylesXml(workbook);
|
|
42569
|
+
if (!stylesPassthrough) entries["xl/styles.xml"] = strToU8(stylesResult.xml);
|
|
42570
|
+
const roundTripInfo = extractPivotRoundTripInfo(originalZip);
|
|
42571
|
+
const authoredStartIndex = roundTripInfo.pivotXmlPaths.filter((p) => p.startsWith("xl/pivotTables/")).length + 1;
|
|
42572
|
+
const pivotInfo = mergePivotInfo(roundTripInfo, emitAuthoredPivots(workbook, entries, authoredStartIndex));
|
|
42573
|
+
entries["xl/workbook.xml"] = strToU8(buildWorkbookXml(workbook, pivotInfo));
|
|
42574
|
+
entries["xl/_rels/workbook.xml.rels"] = strToU8(
|
|
42575
|
+
buildWorkbookRels(workbook, pivotInfo)
|
|
42576
|
+
);
|
|
42577
|
+
const extraContentTypes = [];
|
|
42578
|
+
for (const path7 of pivotInfo.pivotXmlPaths) {
|
|
42579
|
+
const ct = pivotContentTypeFor(path7);
|
|
42580
|
+
if (ct) extraContentTypes.push(ct);
|
|
42581
|
+
}
|
|
42582
|
+
let globalChartIndex = 1;
|
|
42583
|
+
let globalImageIndex = 1;
|
|
42584
|
+
let globalTableIndex = 1;
|
|
42585
|
+
for (let i2 = 0; i2 < workbook.sheets.length; i2++) {
|
|
42586
|
+
const sheet = workbook.sheets[i2];
|
|
42587
|
+
const sheetRels = [];
|
|
42588
|
+
let nextRId = 1;
|
|
42589
|
+
const hasCharts = sheet.charts.length > 0;
|
|
42590
|
+
const hasImages = sheet.images.length > 0;
|
|
42591
|
+
const hasDrawings = sheet.drawings.length > 0;
|
|
42592
|
+
const hasTables = sheet.tables.length > 0;
|
|
42593
|
+
const hasHyperlinks = sheet.hyperlinks.size > 0;
|
|
42594
|
+
const needsDrawing = hasCharts || hasImages || hasDrawings;
|
|
42595
|
+
const hyperlinkRIds = /* @__PURE__ */ new Map();
|
|
42596
|
+
if (hasHyperlinks) {
|
|
42597
|
+
for (const [ref, url] of sheet.hyperlinks) {
|
|
42598
|
+
const rId = `rId${nextRId++}`;
|
|
42599
|
+
hyperlinkRIds.set(ref, rId);
|
|
42600
|
+
sheetRels.push(`<Relationship Id="${rId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="${escapeXml(url)}" TargetMode="External"/>`);
|
|
42601
|
+
}
|
|
42602
|
+
}
|
|
42603
|
+
let drawingRId = "";
|
|
42604
|
+
if (needsDrawing) {
|
|
42605
|
+
drawingRId = `rId${nextRId++}`;
|
|
42606
|
+
sheetRels.push(`<Relationship Id="${drawingRId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing" Target="../drawings/drawing${i2 + 1}.xml"/>`);
|
|
42607
|
+
const drawingRels = [];
|
|
42608
|
+
let drawingRelId = 1;
|
|
42609
|
+
const drawingAnchors = [];
|
|
42610
|
+
for (const chart of sheet.charts) {
|
|
42611
|
+
const chartRId = `rId${drawingRelId++}`;
|
|
42612
|
+
const chartPath = `xl/charts/chart${globalChartIndex}.xml`;
|
|
42613
|
+
entries[chartPath] = strToU8(buildChartXml(chart));
|
|
42614
|
+
extraContentTypes.push(`<Override PartName="/${chartPath}" ContentType="application/vnd.openxmlformats-officedocument.drawingml.chart+xml"/>`);
|
|
42615
|
+
drawingRels.push(`<Relationship Id="${chartRId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart" Target="../charts/chart${globalChartIndex}.xml"/>`);
|
|
42616
|
+
drawingAnchors.push(buildChartAnchorXml(chart, chartRId));
|
|
42617
|
+
globalChartIndex++;
|
|
42618
|
+
}
|
|
42619
|
+
for (const image of sheet.images) {
|
|
42620
|
+
const imgRId = `rId${drawingRelId++}`;
|
|
42621
|
+
const ext = getImageExtension(image.dataUrl);
|
|
42622
|
+
const imgPath = `xl/media/image${globalImageIndex}.${ext}`;
|
|
42623
|
+
const imgBytes = dataUrlToBytes(image.dataUrl);
|
|
42624
|
+
if (imgBytes) {
|
|
42625
|
+
entries[imgPath] = imgBytes;
|
|
42626
|
+
drawingRels.push(`<Relationship Id="${imgRId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="../media/image${globalImageIndex}.${ext}"/>`);
|
|
42627
|
+
drawingAnchors.push(buildImageAnchorXml(image, imgRId));
|
|
42628
|
+
globalImageIndex++;
|
|
42481
42629
|
}
|
|
42482
42630
|
}
|
|
42483
|
-
|
|
42484
|
-
|
|
42485
|
-
|
|
42486
|
-
|
|
42631
|
+
for (const drawing of sheet.drawings) {
|
|
42632
|
+
drawingAnchors.push(buildShapeAnchorXml(drawing));
|
|
42633
|
+
}
|
|
42634
|
+
entries[`xl/drawings/drawing${i2 + 1}.xml`] = strToU8(
|
|
42635
|
+
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42636
|
+
<xdr:wsDr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart">
|
|
42637
|
+
` + drawingAnchors.join("\n") + `
|
|
42638
|
+
</xdr:wsDr>`
|
|
42639
|
+
);
|
|
42640
|
+
extraContentTypes.push(`<Override PartName="/xl/drawings/drawing${i2 + 1}.xml" ContentType="application/vnd.openxmlformats-officedocument.drawing+xml"/>`);
|
|
42641
|
+
if (drawingRels.length > 0) {
|
|
42642
|
+
entries[`xl/drawings/_rels/drawing${i2 + 1}.xml.rels`] = strToU8(
|
|
42643
|
+
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42644
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
42645
|
+
${drawingRels.join("\n")}
|
|
42646
|
+
</Relationships>`
|
|
42647
|
+
);
|
|
42648
|
+
}
|
|
42649
|
+
}
|
|
42650
|
+
const tableRIds = [];
|
|
42651
|
+
if (hasTables) {
|
|
42652
|
+
for (const table of sheet.tables) {
|
|
42653
|
+
const tableRId = `rId${nextRId++}`;
|
|
42654
|
+
tableRIds.push(tableRId);
|
|
42655
|
+
const tablePath = `xl/tables/table${globalTableIndex}.xml`;
|
|
42656
|
+
entries[tablePath] = strToU8(buildTableXml(table, globalTableIndex));
|
|
42657
|
+
extraContentTypes.push(`<Override PartName="/${tablePath}" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml"/>`);
|
|
42658
|
+
sheetRels.push(`<Relationship Id="${tableRId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/table" Target="../tables/table${globalTableIndex}.xml"/>`);
|
|
42659
|
+
globalTableIndex++;
|
|
42660
|
+
}
|
|
42661
|
+
}
|
|
42662
|
+
const pivotTargets = pivotInfo.pivotTablesBySheetIndex.get(i2);
|
|
42663
|
+
if (pivotTargets && pivotTargets.length > 0) {
|
|
42664
|
+
for (const target of pivotTargets) {
|
|
42665
|
+
const rId = `rId${nextRId++}`;
|
|
42666
|
+
sheetRels.push(
|
|
42667
|
+
`<Relationship Id="${rId}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable" Target="${escapeXml(target)}"/>`
|
|
42668
|
+
);
|
|
42669
|
+
}
|
|
42670
|
+
}
|
|
42671
|
+
if (sheetRels.length > 0) {
|
|
42672
|
+
entries[`xl/worksheets/_rels/sheet${i2 + 1}.xml.rels`] = strToU8(
|
|
42673
|
+
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42674
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
42675
|
+
${sheetRels.join("\n")}
|
|
42676
|
+
</Relationships>`
|
|
42677
|
+
);
|
|
42678
|
+
}
|
|
42679
|
+
entries[`xl/worksheets/sheet${i2 + 1}.xml`] = strToU8(
|
|
42680
|
+
buildSheetXml(sheet, workbook.styles, sharedStrings.index, i2 === workbook.activeSheetIndex, stylesResult.xfMap, stylesResult.numFmtMap, stylesResult.dxfMap, drawingRId, tableRIds, hyperlinkRIds)
|
|
42681
|
+
);
|
|
42487
42682
|
}
|
|
42488
|
-
|
|
42489
|
-
|
|
42490
|
-
|
|
42491
|
-
|
|
42492
|
-
|
|
42493
|
-
|
|
42683
|
+
entries["docProps/core.xml"] = strToU8(buildCoreProps());
|
|
42684
|
+
entries["docProps/app.xml"] = strToU8(buildAppProps());
|
|
42685
|
+
entries["[Content_Types].xml"] = strToU8(buildContentTypes(workbook.sheets.length, extraContentTypes));
|
|
42686
|
+
entries["_rels/.rels"] = strToU8(buildRootRels());
|
|
42687
|
+
return zipSync(entries, { level: 6 });
|
|
42688
|
+
}
|
|
42689
|
+
function buildSharedStrings(workbook) {
|
|
42690
|
+
const strings = [];
|
|
42691
|
+
const index = /* @__PURE__ */ new Map();
|
|
42692
|
+
const richTextMap = /* @__PURE__ */ new Map();
|
|
42693
|
+
let totalCount = 0;
|
|
42694
|
+
for (const sheet of workbook.sheets) {
|
|
42695
|
+
for (const cell of sheet.cells.values()) {
|
|
42696
|
+
if (cell.error) continue;
|
|
42697
|
+
if (cell.formula && typeof cell.value === "string") continue;
|
|
42698
|
+
if (typeof cell.value === "string") {
|
|
42699
|
+
totalCount++;
|
|
42700
|
+
if (!index.has(cell.value)) {
|
|
42701
|
+
index.set(cell.value, strings.length);
|
|
42702
|
+
strings.push(cell.value);
|
|
42703
|
+
if (cell.richText && cell.richText.length > 0) {
|
|
42704
|
+
richTextMap.set(cell.value, cell.richText);
|
|
42705
|
+
}
|
|
42706
|
+
}
|
|
42707
|
+
}
|
|
42708
|
+
}
|
|
42709
|
+
}
|
|
42710
|
+
const siEntries = strings.map((s) => {
|
|
42711
|
+
const richText = richTextMap.get(s);
|
|
42712
|
+
if (richText) {
|
|
42713
|
+
return `<si>${richText.map((part) => buildRichTextRun(part)).join("")}</si>`;
|
|
42714
|
+
}
|
|
42715
|
+
const needsPreserve = s.length === 0 || s !== s.trim();
|
|
42716
|
+
const spaceAttr = needsPreserve ? ' xml:space="preserve"' : "";
|
|
42717
|
+
return `<si><t${spaceAttr}>${escapeXml(s)}</t></si>`;
|
|
42718
|
+
});
|
|
42719
|
+
const xml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42720
|
+
<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="${totalCount}" uniqueCount="${strings.length}">
|
|
42721
|
+
${siEntries.join("\n")}
|
|
42722
|
+
</sst>`;
|
|
42723
|
+
return { xml, index };
|
|
42724
|
+
}
|
|
42725
|
+
function buildRichTextRun(part) {
|
|
42726
|
+
const needsPreserve = part.text.length === 0 || part.text !== part.text.trim();
|
|
42727
|
+
const spaceAttr = needsPreserve ? ' xml:space="preserve"' : "";
|
|
42728
|
+
if (!part.font) {
|
|
42729
|
+
return `<r><t${spaceAttr}>${escapeXml(part.text)}</t></r>`;
|
|
42730
|
+
}
|
|
42731
|
+
return `<r>${buildRichTextRunProps(part.font)}<t${spaceAttr}>${escapeXml(part.text)}</t></r>`;
|
|
42732
|
+
}
|
|
42733
|
+
function buildRichTextRunProps(font) {
|
|
42734
|
+
let parts = "";
|
|
42735
|
+
if (font.bold) parts += "<b/>";
|
|
42736
|
+
if (font.italic) parts += "<i/>";
|
|
42737
|
+
if (font.strike) parts += "<strike/>";
|
|
42738
|
+
if (font.underline) parts += `<u val="${font.underline}"/>`;
|
|
42739
|
+
if (font.vertAlign) parts += `<vertAlign val="${font.vertAlign}"/>`;
|
|
42740
|
+
if (font.size) parts += `<sz val="${font.size}"/>`;
|
|
42741
|
+
if (font.color) parts += `<color rgb="${hexToArgb(font.color)}"/>`;
|
|
42742
|
+
if (font.name) parts += `<rFont val="${escapeXml(font.name)}"/>`;
|
|
42743
|
+
return `<rPr>${parts}</rPr>`;
|
|
42744
|
+
}
|
|
42745
|
+
function buildStylesXml(workbook) {
|
|
42746
|
+
const styles = [];
|
|
42747
|
+
for (let i2 = 0; i2 < workbook.styles.size; i2++) {
|
|
42748
|
+
styles.push(workbook.styles.get(i2));
|
|
42749
|
+
}
|
|
42750
|
+
const numFmtMap = /* @__PURE__ */ new Map();
|
|
42751
|
+
let nextNumFmtId = 164;
|
|
42752
|
+
for (const sheet of workbook.sheets) {
|
|
42753
|
+
for (const cell of sheet.cells.values()) {
|
|
42754
|
+
if (cell.numFmtCode && cell.numFmtCode !== "General" && cell.numFmtCode !== "") {
|
|
42755
|
+
if (!numFmtMap.has(cell.numFmtCode)) {
|
|
42756
|
+
numFmtMap.set(cell.numFmtCode, nextNumFmtId++);
|
|
42757
|
+
}
|
|
42758
|
+
}
|
|
42759
|
+
}
|
|
42760
|
+
}
|
|
42761
|
+
const cellNumFmtIds = /* @__PURE__ */ new Map();
|
|
42762
|
+
for (let si = 0; si < workbook.sheets.length; si++) {
|
|
42763
|
+
for (const [ref, cell] of workbook.sheets[si].cells) {
|
|
42764
|
+
if (cell.numFmtCode && cell.numFmtCode !== "General" && cell.numFmtCode !== "") {
|
|
42765
|
+
const id = numFmtMap.get(cell.numFmtCode);
|
|
42766
|
+
if (id !== void 0) cellNumFmtIds.set(`${si}:${ref}`, id);
|
|
42767
|
+
}
|
|
42768
|
+
}
|
|
42769
|
+
}
|
|
42770
|
+
const fonts = /* @__PURE__ */ new Map();
|
|
42771
|
+
const fontList = [];
|
|
42772
|
+
fonts.set("default", 0);
|
|
42773
|
+
fontList.push({});
|
|
42774
|
+
for (const s of styles) {
|
|
42775
|
+
const key = fontKey(s);
|
|
42776
|
+
if (!fonts.has(key)) {
|
|
42777
|
+
fonts.set(key, fontList.length);
|
|
42778
|
+
fontList.push(s);
|
|
42779
|
+
}
|
|
42780
|
+
}
|
|
42781
|
+
const fillEntries = [];
|
|
42782
|
+
const fillMap = /* @__PURE__ */ new Map();
|
|
42783
|
+
fillEntries.push('<fill><patternFill patternType="none"/></fill>');
|
|
42784
|
+
fillEntries.push('<fill><patternFill patternType="gray125"/></fill>');
|
|
42785
|
+
fillMap.set("", 0);
|
|
42786
|
+
for (const s of styles) {
|
|
42787
|
+
const fk = fillKey(s);
|
|
42788
|
+
if (fk === "" || fillMap.has(fk)) continue;
|
|
42789
|
+
fillMap.set(fk, fillEntries.length);
|
|
42790
|
+
fillEntries.push(buildFillXml(s));
|
|
42791
|
+
}
|
|
42792
|
+
const borderEntries = [];
|
|
42793
|
+
const borderMap = /* @__PURE__ */ new Map();
|
|
42794
|
+
borderEntries.push("<border><left/><right/><top/><bottom/><diagonal/></border>");
|
|
42795
|
+
borderMap.set("", 0);
|
|
42796
|
+
for (const s of styles) {
|
|
42797
|
+
const bk = borderKey(s);
|
|
42798
|
+
if (bk === "" || borderMap.has(bk)) continue;
|
|
42799
|
+
borderMap.set(bk, borderEntries.length);
|
|
42800
|
+
borderEntries.push(buildBorderXml(s));
|
|
42494
42801
|
}
|
|
42495
|
-
|
|
42496
|
-
|
|
42497
|
-
|
|
42498
|
-
|
|
42802
|
+
const fontsXml = fontList.map((f) => buildFontXml(f)).join("\n");
|
|
42803
|
+
const fillsXml = fillEntries.join("\n");
|
|
42804
|
+
const bordersXml = borderEntries.join("\n");
|
|
42805
|
+
let numFmtsXml = "";
|
|
42806
|
+
if (numFmtMap.size > 0) {
|
|
42807
|
+
const entries = Array.from(numFmtMap.entries()).map(([code, id]) => `<numFmt numFmtId="${id}" formatCode="${escapeXml(code)}"/>`).join("\n");
|
|
42808
|
+
numFmtsXml = `<numFmts count="${numFmtMap.size}">
|
|
42809
|
+
${entries}
|
|
42810
|
+
</numFmts>
|
|
42811
|
+
`;
|
|
42499
42812
|
}
|
|
42500
|
-
|
|
42501
|
-
|
|
42502
|
-
|
|
42503
|
-
const
|
|
42504
|
-
const
|
|
42505
|
-
|
|
42506
|
-
|
|
42813
|
+
const xfEntries = [];
|
|
42814
|
+
const xfMap = /* @__PURE__ */ new Map();
|
|
42815
|
+
for (let styleIdx = 0; styleIdx < styles.length; styleIdx++) {
|
|
42816
|
+
const s = styles[styleIdx];
|
|
42817
|
+
const fontId = fonts.get(fontKey(s)) ?? 0;
|
|
42818
|
+
const fillId = fillMap.get(fillKey(s)) ?? 0;
|
|
42819
|
+
const borderId = borderMap.get(borderKey(s)) ?? 0;
|
|
42820
|
+
const xfKey = `${styleIdx}:0`;
|
|
42821
|
+
xfMap.set(xfKey, xfEntries.length);
|
|
42822
|
+
xfEntries.push(buildXfXml(s, fontId, fillId, borderId, 0));
|
|
42507
42823
|
}
|
|
42508
|
-
const
|
|
42509
|
-
|
|
42510
|
-
|
|
42511
|
-
|
|
42512
|
-
|
|
42513
|
-
|
|
42514
|
-
|
|
42515
|
-
|
|
42516
|
-
|
|
42824
|
+
for (const [cellKey2, numFmtId] of cellNumFmtIds) {
|
|
42825
|
+
const [siStr, ref] = cellKey2.split(":");
|
|
42826
|
+
const cell = workbook.sheets[parseInt(siStr)].cells.get(ref);
|
|
42827
|
+
if (!cell) continue;
|
|
42828
|
+
const xfKey = `${cell.styleIndex}:${numFmtId}`;
|
|
42829
|
+
if (xfMap.has(xfKey)) continue;
|
|
42830
|
+
const s = styles[cell.styleIndex] ?? {};
|
|
42831
|
+
const fontId = fonts.get(fontKey(s)) ?? 0;
|
|
42832
|
+
const fillId = fillMap.get(fillKey(s)) ?? 0;
|
|
42833
|
+
const borderId = borderMap.get(borderKey(s)) ?? 0;
|
|
42834
|
+
xfMap.set(xfKey, xfEntries.length);
|
|
42835
|
+
xfEntries.push(buildXfXml(s, fontId, fillId, borderId, numFmtId));
|
|
42836
|
+
}
|
|
42837
|
+
const dxfEntries = [];
|
|
42838
|
+
const dxfMap = /* @__PURE__ */ new Map();
|
|
42839
|
+
for (const sheet of workbook.sheets) {
|
|
42840
|
+
for (const cf of sheet.conditionalFormats) {
|
|
42841
|
+
for (const rule of cf.rules) {
|
|
42842
|
+
if (rule.ruleType === "style" && rule.style) {
|
|
42843
|
+
const key = JSON.stringify(rule.style);
|
|
42844
|
+
if (!dxfMap.has(key)) {
|
|
42845
|
+
dxfMap.set(key, dxfEntries.length);
|
|
42846
|
+
dxfEntries.push(buildDxfXml(rule.style));
|
|
42847
|
+
}
|
|
42848
|
+
}
|
|
42517
42849
|
}
|
|
42518
42850
|
}
|
|
42519
|
-
autoFilterXml = `<autoFilter ref="${sheet.autoFilter.ref}">${filterCols}</autoFilter>`;
|
|
42520
|
-
}
|
|
42521
|
-
let dvXml = "";
|
|
42522
|
-
if (sheet.dataValidations.length > 0) {
|
|
42523
|
-
const dvEntries = sheet.dataValidations.map((dv) => {
|
|
42524
|
-
let attrs = `sqref="${dv.ref}" type="${dv.type}"`;
|
|
42525
|
-
if (dv.operator) attrs += ` operator="${dv.operator}"`;
|
|
42526
|
-
if (!dv.showDropdown) attrs += ' showDropDown="1"';
|
|
42527
|
-
if (dv.errorStyle) attrs += ` errorStyle="${dv.errorStyle}"`;
|
|
42528
|
-
if (dv.errorTitle) attrs += ` errorTitle="${escapeXml(dv.errorTitle)}"`;
|
|
42529
|
-
if (dv.errorMessage) attrs += ` error="${escapeXml(dv.errorMessage)}"`;
|
|
42530
|
-
if (dv.promptTitle) attrs += ` promptTitle="${escapeXml(dv.promptTitle)}"`;
|
|
42531
|
-
if (dv.promptMessage) attrs += ` prompt="${escapeXml(dv.promptMessage)}"`;
|
|
42532
|
-
let inner = "";
|
|
42533
|
-
if (dv.formula1) inner += `<formula1>${escapeXml(dv.formula1)}</formula1>`;
|
|
42534
|
-
if (dv.formula2) inner += `<formula2>${escapeXml(dv.formula2)}</formula2>`;
|
|
42535
|
-
return `<dataValidation ${attrs}>${inner}</dataValidation>`;
|
|
42536
|
-
}).join("");
|
|
42537
|
-
dvXml = `<dataValidations count="${sheet.dataValidations.length}">${dvEntries}</dataValidations>`;
|
|
42538
|
-
}
|
|
42539
|
-
let cfXml = "";
|
|
42540
|
-
if (sheet.conditionalFormats.length > 0) {
|
|
42541
|
-
cfXml = sheet.conditionalFormats.map((cf) => buildConditionalFormattingXml(cf, dxfMap)).join("");
|
|
42542
42851
|
}
|
|
42543
|
-
let
|
|
42544
|
-
if (
|
|
42545
|
-
|
|
42546
|
-
|
|
42852
|
+
let dxfsXml = '<dxfs count="0"/>';
|
|
42853
|
+
if (dxfEntries.length > 0) {
|
|
42854
|
+
dxfsXml = `<dxfs count="${dxfEntries.length}">
|
|
42855
|
+
${dxfEntries.join("\n")}
|
|
42856
|
+
</dxfs>`;
|
|
42547
42857
|
}
|
|
42548
|
-
const
|
|
42549
|
-
|
|
42550
|
-
|
|
42551
|
-
|
|
42552
|
-
|
|
42858
|
+
const xml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42859
|
+
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
|
|
42860
|
+
${numFmtsXml}<fonts count="${fontList.length}">
|
|
42861
|
+
${fontsXml}
|
|
42862
|
+
</fonts>
|
|
42863
|
+
<fills count="${fillEntries.length}">
|
|
42864
|
+
${fillsXml}
|
|
42865
|
+
</fills>
|
|
42866
|
+
<borders count="${borderEntries.length}">
|
|
42867
|
+
${bordersXml}
|
|
42868
|
+
</borders>
|
|
42869
|
+
<cellStyleXfs count="1">
|
|
42870
|
+
<xf numFmtId="0" fontId="0" fillId="0" borderId="0"/>
|
|
42871
|
+
</cellStyleXfs>
|
|
42872
|
+
<cellXfs count="${xfEntries.length}">
|
|
42873
|
+
${xfEntries.join("\n")}
|
|
42874
|
+
</cellXfs>
|
|
42875
|
+
<cellStyles count="1">
|
|
42876
|
+
<cellStyle name="Normal" xfId="0" builtinId="0"/>
|
|
42877
|
+
</cellStyles>
|
|
42878
|
+
${dxfsXml}
|
|
42879
|
+
</styleSheet>`;
|
|
42880
|
+
return { xml, xfMap, numFmtMap, dxfMap };
|
|
42881
|
+
}
|
|
42882
|
+
function buildXfXml(s, fontId, fillId, borderId, numFmtId) {
|
|
42883
|
+
let attrs = `numFmtId="${numFmtId}" fontId="${fontId}" fillId="${fillId}" borderId="${borderId}" xfId="0"`;
|
|
42884
|
+
if (numFmtId > 0) attrs += ' applyNumberFormat="1"';
|
|
42885
|
+
if (fontId > 0) attrs += ' applyFont="1"';
|
|
42886
|
+
if (fillId > 0) attrs += ' applyFill="1"';
|
|
42887
|
+
if (borderId > 0) attrs += ' applyBorder="1"';
|
|
42888
|
+
if (s.horizontalAlign || s.verticalAlign || s.wrapText || s.indent || s.textRotation || s.shrinkToFit) {
|
|
42889
|
+
const hAlign = s.horizontalAlign ? ` horizontal="${s.horizontalAlign}"` : "";
|
|
42890
|
+
const vAlign = s.verticalAlign ? ` vertical="${s.verticalAlign}"` : "";
|
|
42891
|
+
const wrap = s.wrapText ? ' wrapText="1"' : "";
|
|
42892
|
+
const indent = s.indent ? ` indent="${s.indent}"` : "";
|
|
42893
|
+
const rotation = s.textRotation !== void 0 ? ` textRotation="${s.textRotation === "vertical" ? 255 : s.textRotation}"` : "";
|
|
42894
|
+
const shrink = s.shrinkToFit ? ' shrinkToFit="1"' : "";
|
|
42895
|
+
return `<xf ${attrs} applyAlignment="1"><alignment${hAlign}${vAlign}${wrap}${indent}${rotation}${shrink}/></xf>`;
|
|
42553
42896
|
}
|
|
42554
|
-
|
|
42555
|
-
|
|
42556
|
-
|
|
42557
|
-
|
|
42558
|
-
|
|
42559
|
-
|
|
42560
|
-
|
|
42561
|
-
|
|
42562
|
-
|
|
42563
|
-
|
|
42564
|
-
|
|
42565
|
-
|
|
42566
|
-
|
|
42567
|
-
|
|
42568
|
-
|
|
42569
|
-
|
|
42570
|
-
const attrs = [];
|
|
42571
|
-
if (ps.paperSize !== void 0) attrs.push(`paperSize="${ps.paperSize}"`);
|
|
42572
|
-
if (ps.scale !== void 0) attrs.push(`scale="${ps.scale}"`);
|
|
42573
|
-
if (ps.fitToWidth !== void 0) attrs.push(`fitToWidth="${ps.fitToWidth}"`);
|
|
42574
|
-
if (ps.fitToHeight !== void 0) attrs.push(`fitToHeight="${ps.fitToHeight}"`);
|
|
42575
|
-
if (ps.orientation) attrs.push(`orientation="${ps.orientation}"`);
|
|
42576
|
-
if (attrs.length > 0) pageSetupXml = `<pageSetup ${attrs.join(" ")}/>`;
|
|
42897
|
+
return `<xf ${attrs}/>`;
|
|
42898
|
+
}
|
|
42899
|
+
function fontKey(s) {
|
|
42900
|
+
return `${s.fontName ?? ""}|${s.fontSize ?? 0}|${s.fontBold ? 1 : 0}|${s.fontItalic ? 1 : 0}|${s.fontColor ?? ""}|${s.fontUnderline ?? ""}|${s.fontStrike ? 1 : 0}`;
|
|
42901
|
+
}
|
|
42902
|
+
function buildFontXml(s) {
|
|
42903
|
+
let parts = "";
|
|
42904
|
+
if (s.fontBold) parts += "<b/>";
|
|
42905
|
+
if (s.fontItalic) parts += "<i/>";
|
|
42906
|
+
if (s.fontStrike) parts += "<strike/>";
|
|
42907
|
+
if (s.fontUnderline) parts += `<u val="${s.fontUnderline}"/>`;
|
|
42908
|
+
parts += `<sz val="${s.fontSize ?? 11}"/>`;
|
|
42909
|
+
if (s.fontColor) {
|
|
42910
|
+
parts += `<color rgb="${hexToArgb(s.fontColor)}"/>`;
|
|
42911
|
+
} else {
|
|
42912
|
+
parts += '<color theme="1"/>';
|
|
42577
42913
|
}
|
|
42578
|
-
|
|
42579
|
-
|
|
42580
|
-
|
|
42581
|
-
|
|
42582
|
-
|
|
42583
|
-
|
|
42584
|
-
|
|
42585
|
-
|
|
42586
|
-
|
|
42587
|
-
|
|
42588
|
-
|
|
42589
|
-
|
|
42590
|
-
|
|
42591
|
-
|
|
42592
|
-
|
|
42593
|
-
|
|
42914
|
+
parts += `<name val="${escapeXml(s.fontName ?? "Calibri")}"/>`;
|
|
42915
|
+
return `<font>${parts}</font>`;
|
|
42916
|
+
}
|
|
42917
|
+
function borderKey(s) {
|
|
42918
|
+
const parts = [];
|
|
42919
|
+
if (s.borderTop) parts.push(`t:${s.borderTop.style}:${s.borderTop.width}:${s.borderTop.color ?? ""}`);
|
|
42920
|
+
if (s.borderRight) parts.push(`r:${s.borderRight.style}:${s.borderRight.width}:${s.borderRight.color ?? ""}`);
|
|
42921
|
+
if (s.borderBottom) parts.push(`b:${s.borderBottom.style}:${s.borderBottom.width}:${s.borderBottom.color ?? ""}`);
|
|
42922
|
+
if (s.borderLeft) parts.push(`l:${s.borderLeft.style}:${s.borderLeft.width}:${s.borderLeft.color ?? ""}`);
|
|
42923
|
+
if (s.borderDiagonal) parts.push(`d:${s.borderDiagonal.style}:${s.borderDiagonal.width}:${s.borderDiagonal.color ?? ""}`);
|
|
42924
|
+
if (s.diagonalUp) parts.push("du");
|
|
42925
|
+
if (s.diagonalDown) parts.push("dd");
|
|
42926
|
+
return parts.join("|");
|
|
42927
|
+
}
|
|
42928
|
+
function toOoxmlBorderStyle(border2) {
|
|
42929
|
+
const ooxmlStyles = [
|
|
42930
|
+
"thin",
|
|
42931
|
+
"medium",
|
|
42932
|
+
"thick",
|
|
42933
|
+
"dotted",
|
|
42934
|
+
"dashed",
|
|
42935
|
+
"double",
|
|
42936
|
+
"hair",
|
|
42937
|
+
"mediumDashed",
|
|
42938
|
+
"dashDot",
|
|
42939
|
+
"mediumDashDot",
|
|
42940
|
+
"dashDotDot",
|
|
42941
|
+
"mediumDashDotDot",
|
|
42942
|
+
"slantDashDot"
|
|
42943
|
+
];
|
|
42944
|
+
if (ooxmlStyles.includes(border2.style)) return border2.style;
|
|
42945
|
+
if (border2.style === "solid") {
|
|
42946
|
+
if (border2.width <= 1) return "thin";
|
|
42947
|
+
if (border2.width <= 2) return "medium";
|
|
42948
|
+
return "thick";
|
|
42594
42949
|
}
|
|
42595
|
-
|
|
42596
|
-
if (
|
|
42597
|
-
|
|
42598
|
-
|
|
42599
|
-
|
|
42600
|
-
|
|
42601
|
-
|
|
42602
|
-
|
|
42603
|
-
|
|
42604
|
-
|
|
42605
|
-
|
|
42950
|
+
if (border2.style === "dashed") return "dashed";
|
|
42951
|
+
if (border2.style === "dotted") return "dotted";
|
|
42952
|
+
if (border2.style === "double") return "double";
|
|
42953
|
+
return "thin";
|
|
42954
|
+
}
|
|
42955
|
+
function buildBorderXml(s) {
|
|
42956
|
+
let attrs = "";
|
|
42957
|
+
if (s.diagonalUp) attrs += ' diagonalUp="1"';
|
|
42958
|
+
if (s.diagonalDown) attrs += ' diagonalDown="1"';
|
|
42959
|
+
const sides = [
|
|
42960
|
+
{ tag: "left", border: s.borderLeft },
|
|
42961
|
+
{ tag: "right", border: s.borderRight },
|
|
42962
|
+
{ tag: "top", border: s.borderTop },
|
|
42963
|
+
{ tag: "bottom", border: s.borderBottom },
|
|
42964
|
+
{ tag: "diagonal", border: s.borderDiagonal }
|
|
42965
|
+
];
|
|
42966
|
+
const inner = sides.map(({ tag, border: border2 }) => {
|
|
42967
|
+
if (!border2) return `<${tag}/>`;
|
|
42968
|
+
const ooxmlStyle = toOoxmlBorderStyle(border2);
|
|
42969
|
+
let colorXml = "";
|
|
42970
|
+
if (border2.color) {
|
|
42971
|
+
colorXml = `<color rgb="${hexToArgb(border2.color)}"/>`;
|
|
42606
42972
|
}
|
|
42607
|
-
|
|
42608
|
-
}
|
|
42609
|
-
return
|
|
42610
|
-
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
|
42611
|
-
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
|
42612
|
-
${sheetPrXml}<dimension ref="${dimensionRef}"/>
|
|
42613
|
-
<sheetViews>${sheetView}</sheetViews>
|
|
42614
|
-
<sheetFormatPr defaultRowHeight="${sheet.defaultRowHeight}" defaultColWidth="${sheet.defaultColWidth}"/>
|
|
42615
|
-
${cols.length > 0 ? `<cols>${cols.join("")}</cols>` : ""}
|
|
42616
|
-
<sheetData>
|
|
42617
|
-
${rows.join("\n")}
|
|
42618
|
-
</sheetData>
|
|
42619
|
-
${autoFilterXml}${mergeXml}${cfXml}${dvXml}${hyperlinksXml}${marginsXml}${pageSetupXml}${headerFooterXml}${drawingXml}${tablePartsXml}
|
|
42620
|
-
</worksheet>`;
|
|
42973
|
+
return `<${tag} style="${ooxmlStyle}">${colorXml}</${tag}>`;
|
|
42974
|
+
}).join("");
|
|
42975
|
+
return `<border${attrs}>${inner}</border>`;
|
|
42621
42976
|
}
|
|
42622
|
-
function
|
|
42623
|
-
if (
|
|
42624
|
-
if (
|
|
42625
|
-
if (
|
|
42626
|
-
|
|
42627
|
-
return void 0;
|
|
42977
|
+
function fillKey(s) {
|
|
42978
|
+
if (s.gradientData) return `gradient:${JSON.stringify(s.gradientData)}`;
|
|
42979
|
+
if (s.patternType && s.backgroundPattern) return `pattern:${s.patternType}|${s.backgroundPattern}`;
|
|
42980
|
+
if (s.backgroundColor) return `solid:${s.backgroundColor}`;
|
|
42981
|
+
return "";
|
|
42628
42982
|
}
|
|
42629
|
-
function
|
|
42630
|
-
if (
|
|
42631
|
-
|
|
42632
|
-
|
|
42633
|
-
|
|
42634
|
-
|
|
42635
|
-
|
|
42983
|
+
function buildFillXml(s) {
|
|
42984
|
+
if (s.gradientData) {
|
|
42985
|
+
const g = s.gradientData;
|
|
42986
|
+
const stops = g.stops.map((stop) => {
|
|
42987
|
+
const hex = hexToArgb(stop.color);
|
|
42988
|
+
return `<stop position="${stop.position}"><color rgb="${hex}"/></stop>`;
|
|
42989
|
+
}).join("");
|
|
42990
|
+
if (g.type === "radial") {
|
|
42991
|
+
return `<fill><gradientFill type="path" left="0.5" right="0.5" top="0.5" bottom="0.5">${stops}</gradientFill></fill>`;
|
|
42992
|
+
}
|
|
42993
|
+
return `<fill><gradientFill degree="${g.degree}">${stops}</gradientFill></fill>`;
|
|
42636
42994
|
}
|
|
42637
|
-
if (
|
|
42638
|
-
|
|
42639
|
-
|
|
42640
|
-
|
|
42641
|
-
|
|
42995
|
+
if (s.patternType && s.backgroundPattern) {
|
|
42996
|
+
const colors = extractFillColors(s.backgroundPattern);
|
|
42997
|
+
let colorAttrs = "";
|
|
42998
|
+
if (colors.fg) colorAttrs += `<fgColor rgb="${hexToArgb(colors.fg)}"/>`;
|
|
42999
|
+
if (colors.bg) colorAttrs += `<bgColor rgb="${hexToArgb(colors.bg)}"/>`;
|
|
43000
|
+
return `<fill><patternFill patternType="${escapeXml(s.patternType)}">${colorAttrs}</patternFill></fill>`;
|
|
43001
|
+
}
|
|
43002
|
+
return `<fill><patternFill patternType="solid"><fgColor rgb="${hexToArgb(s.backgroundColor)}"/></patternFill></fill>`;
|
|
42642
43003
|
}
|
|
42643
|
-
function
|
|
42644
|
-
const
|
|
42645
|
-
|
|
42646
|
-
|
|
42647
|
-
const nameEntries = [];
|
|
42648
|
-
for (const [name, value] of workbook.namedRanges) {
|
|
42649
|
-
nameEntries.push(`<definedName name="${escapeXml(name)}">${escapeXml(value)}</definedName>`);
|
|
43004
|
+
function extractFillColors(css) {
|
|
43005
|
+
const colorMatches = css.match(/rgba?\([^)]+\)/g);
|
|
43006
|
+
if (colorMatches) {
|
|
43007
|
+
return { fg: colorMatches[0], bg: colorMatches[1] };
|
|
42650
43008
|
}
|
|
42651
|
-
|
|
42652
|
-
|
|
42653
|
-
|
|
42654
|
-
const parts = [];
|
|
42655
|
-
const sheetName = quoteSheetName(s.name);
|
|
42656
|
-
if (pt.repeatCols) {
|
|
42657
|
-
const [start, end] = pt.repeatCols;
|
|
42658
|
-
parts.push(`${sheetName}!$${colNumToLetters(start)}:$${colNumToLetters(end)}`);
|
|
42659
|
-
}
|
|
42660
|
-
if (pt.repeatRows) {
|
|
42661
|
-
const [start, end] = pt.repeatRows;
|
|
42662
|
-
parts.push(`${sheetName}!$${start}:$${end}`);
|
|
42663
|
-
}
|
|
42664
|
-
nameEntries.push(
|
|
42665
|
-
`<definedName name="_xlnm.Print_Titles" localSheetId="${i2}">${escapeXml(parts.join(","))}</definedName>`
|
|
42666
|
-
);
|
|
42667
|
-
});
|
|
42668
|
-
const definedNames = nameEntries.length > 0 ? `
|
|
42669
|
-
<definedNames>
|
|
42670
|
-
${nameEntries.join("\n")}
|
|
42671
|
-
</definedNames>` : "";
|
|
42672
|
-
let pivotCachesBlock = "";
|
|
42673
|
-
if (pivotInfo && pivotInfo.cachesByWorkbook.size > 0) {
|
|
42674
|
-
const baseRId = workbook.sheets.length + 3;
|
|
42675
|
-
const cacheIds = [...pivotInfo.cachesByWorkbook.keys()].sort((a, b) => a - b);
|
|
42676
|
-
const items = cacheIds.map((cacheId, i2) => `<pivotCache cacheId="${cacheId}" r:id="rId${baseRId + i2}"/>`).join("\n");
|
|
42677
|
-
pivotCachesBlock = `
|
|
42678
|
-
<pivotCaches>
|
|
42679
|
-
${items}
|
|
42680
|
-
</pivotCaches>`;
|
|
43009
|
+
const hexMatches = css.match(/#[0-9a-fA-F]{6}/g);
|
|
43010
|
+
if (hexMatches) {
|
|
43011
|
+
return { fg: hexMatches[0], bg: hexMatches[1] };
|
|
42681
43012
|
}
|
|
42682
|
-
return
|
|
42683
|
-
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
|
42684
|
-
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
|
42685
|
-
<bookViews>
|
|
42686
|
-
<workbookView activeTab="${workbook.activeSheetIndex}"/>
|
|
42687
|
-
</bookViews>
|
|
42688
|
-
<sheets>
|
|
42689
|
-
${sheets}
|
|
42690
|
-
</sheets>${definedNames}${pivotCachesBlock}
|
|
42691
|
-
<calcPr fullCalcOnLoad="1"/>
|
|
42692
|
-
</workbook>`;
|
|
43013
|
+
return { fg: void 0, bg: void 0 };
|
|
42693
43014
|
}
|
|
42694
|
-
function
|
|
42695
|
-
const
|
|
42696
|
-
|
|
42697
|
-
)
|
|
42698
|
-
|
|
42699
|
-
|
|
42700
|
-
|
|
42701
|
-
|
|
42702
|
-
|
|
42703
|
-
|
|
42704
|
-
|
|
42705
|
-
|
|
42706
|
-
rels.push(
|
|
42707
|
-
`<Relationship Id="rId${baseRId + i2}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition" Target="${escapeXml(target)}"/>`
|
|
42708
|
-
);
|
|
42709
|
-
});
|
|
43015
|
+
function buildSheetXml(sheet, styles, ssIndex, isActive, xfMap, numFmtMap, dxfMap, drawingRId, tableRIds, hyperlinkRIds) {
|
|
43016
|
+
const rows = [];
|
|
43017
|
+
const rowMap = /* @__PURE__ */ new Map();
|
|
43018
|
+
for (const [ref, cell] of sheet.cells) {
|
|
43019
|
+
const rc = refToRowCol(ref);
|
|
43020
|
+
if (!rc) continue;
|
|
43021
|
+
let arr = rowMap.get(rc.row);
|
|
43022
|
+
if (!arr) {
|
|
43023
|
+
arr = [];
|
|
43024
|
+
rowMap.set(rc.row, arr);
|
|
43025
|
+
}
|
|
43026
|
+
arr.push({ col: rc.col, cell });
|
|
42710
43027
|
}
|
|
42711
|
-
|
|
42712
|
-
|
|
42713
|
-
|
|
42714
|
-
|
|
42715
|
-
|
|
42716
|
-
|
|
42717
|
-
|
|
42718
|
-
{
|
|
42719
|
-
|
|
42720
|
-
|
|
42721
|
-
|
|
42722
|
-
|
|
42723
|
-
|
|
42724
|
-
|
|
42725
|
-
|
|
42726
|
-
|
|
42727
|
-
|
|
42728
|
-
|
|
42729
|
-
|
|
42730
|
-
|
|
42731
|
-
|
|
42732
|
-
|
|
42733
|
-
|
|
42734
|
-
|
|
42735
|
-
|
|
42736
|
-
</
|
|
42737
|
-
}
|
|
42738
|
-
|
|
42739
|
-
|
|
42740
|
-
|
|
42741
|
-
|
|
42742
|
-
|
|
42743
|
-
|
|
42744
|
-
</
|
|
42745
|
-
}
|
|
42746
|
-
function buildCoreProps() {
|
|
42747
|
-
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
42748
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42749
|
-
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
|
|
42750
|
-
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
42751
|
-
xmlns:dcterms="http://purl.org/dc/terms/"
|
|
42752
|
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
42753
|
-
<dcterms:created xsi:type="dcterms:W3CDTF">${now}</dcterms:created>
|
|
42754
|
-
<dcterms:modified xsi:type="dcterms:W3CDTF">${now}</dcterms:modified>
|
|
42755
|
-
</cp:coreProperties>`;
|
|
42756
|
-
}
|
|
42757
|
-
function buildAppProps() {
|
|
42758
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
42759
|
-
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties">
|
|
42760
|
-
<Application>Microsoft Excel</Application>
|
|
42761
|
-
</Properties>`;
|
|
42762
|
-
}
|
|
42763
|
-
var CHART_TYPE_MAP2 = {
|
|
42764
|
-
bar: "c:barChart",
|
|
42765
|
-
col: "c:barChart",
|
|
42766
|
-
line: "c:lineChart",
|
|
42767
|
-
pie: "c:pieChart",
|
|
42768
|
-
doughnut: "c:doughnutChart",
|
|
42769
|
-
area: "c:areaChart",
|
|
42770
|
-
scatter: "c:scatterChart",
|
|
42771
|
-
bubble: "c:bubbleChart",
|
|
42772
|
-
radar: "c:radarChart",
|
|
42773
|
-
stock: "c:stockChart",
|
|
42774
|
-
surface: "c:surfaceChart"
|
|
42775
|
-
};
|
|
42776
|
-
function buildSeriesXml(s, idx, chartType, categories) {
|
|
42777
|
-
let nameXml = "";
|
|
42778
|
-
if (s.name) nameXml = `<c:tx><c:strRef><c:strCache><c:ptCount val="1"/><c:pt idx="0"><c:v>${escapeXml(s.name)}</c:v></c:pt></c:strCache></c:strRef></c:tx>`;
|
|
42779
|
-
let colorXml = "";
|
|
42780
|
-
if (s.color) colorXml = `<c:spPr><a:solidFill><a:srgbClr val="${hexToOoxmlRgb(s.color)}"/></a:solidFill></c:spPr>`;
|
|
42781
|
-
const valTag = chartType === "scatter" || chartType === "bubble" ? "c:yVal" : "c:val";
|
|
42782
|
-
const valPts = s.values.map((v, i2) => `<c:pt idx="${i2}"><c:v>${v}</c:v></c:pt>`).join("");
|
|
42783
|
-
const valXml = `<${valTag}><c:numRef><c:numCache><c:ptCount val="${s.values.length}"/>${valPts}</c:numCache></c:numRef></${valTag}>`;
|
|
42784
|
-
let catXml = "";
|
|
42785
|
-
if (categories && categories.length > 0) {
|
|
42786
|
-
const catTag = chartType === "scatter" || chartType === "bubble" ? "c:xVal" : "c:cat";
|
|
42787
|
-
const catPts = categories.map((c, i2) => `<c:pt idx="${i2}"><c:v>${escapeXml(c)}</c:v></c:pt>`).join("");
|
|
42788
|
-
catXml = `<${catTag}><c:strRef><c:strCache><c:ptCount val="${categories.length}"/>${catPts}</c:strCache></c:strRef></${catTag}>`;
|
|
43028
|
+
const sortedRows = Array.from(rowMap.keys()).sort((a, b) => a - b);
|
|
43029
|
+
for (const rowNum of sortedRows) {
|
|
43030
|
+
const cells = rowMap.get(rowNum);
|
|
43031
|
+
cells.sort((a, b) => a.col - b.col);
|
|
43032
|
+
const h = sheet.rowHeights.get(rowNum);
|
|
43033
|
+
const rowAttrs = h ? ` ht="${h}" customHeight="1"` : "";
|
|
43034
|
+
const hidden = sheet.hiddenRows.has(rowNum) ? ' hidden="1"' : "";
|
|
43035
|
+
const cellsXml = cells.map(({ col, cell }) => {
|
|
43036
|
+
const ref = rowColToRef(rowNum, col);
|
|
43037
|
+
const type = getCellType(cell, ssIndex);
|
|
43038
|
+
const value = getCellValue(cell, ssIndex);
|
|
43039
|
+
let attrs = `r="${ref}"`;
|
|
43040
|
+
let xfIndex = 0;
|
|
43041
|
+
if (xfMap.size === 0 && cell.originalXfIndex !== void 0) {
|
|
43042
|
+
xfIndex = cell.originalXfIndex;
|
|
43043
|
+
} else {
|
|
43044
|
+
const numFmtId = cell.numFmtCode && cell.numFmtCode !== "General" && cell.numFmtCode !== "" ? numFmtMap.get(cell.numFmtCode) ?? 0 : 0;
|
|
43045
|
+
const xfKey = `${cell.styleIndex}:${numFmtId}`;
|
|
43046
|
+
xfIndex = xfMap.get(xfKey) ?? 0;
|
|
43047
|
+
}
|
|
43048
|
+
if (xfIndex > 0) attrs += ` s="${xfIndex}"`;
|
|
43049
|
+
if (type) attrs += ` t="${type}"`;
|
|
43050
|
+
let inner = "";
|
|
43051
|
+
if (cell.formula) {
|
|
43052
|
+
if (cell.isArrayFormula && cell.arrayRange) {
|
|
43053
|
+
inner += `<f t="array" ref="${cell.arrayRange}">${escapeXml(cell.formula)}</f>`;
|
|
43054
|
+
} else {
|
|
43055
|
+
inner += `<f>${escapeXml(cell.formula)}</f>`;
|
|
43056
|
+
}
|
|
43057
|
+
}
|
|
43058
|
+
if (value !== void 0) inner += `<v>${escapeXml(String(value))}</v>`;
|
|
43059
|
+
return `<c ${attrs}>${inner}</c>`;
|
|
43060
|
+
}).join("");
|
|
43061
|
+
rows.push(`<row r="${rowNum}"${rowAttrs}${hidden}>${cellsXml}</row>`);
|
|
42789
43062
|
}
|
|
42790
|
-
|
|
42791
|
-
|
|
42792
|
-
|
|
42793
|
-
|
|
43063
|
+
const cols = [];
|
|
43064
|
+
const allCols = /* @__PURE__ */ new Set([...sheet.colWidths.keys(), ...sheet.hiddenCols]);
|
|
43065
|
+
for (const c of Array.from(allCols).sort((a, b) => a - b)) {
|
|
43066
|
+
const w = sheet.colWidths.get(c) ?? sheet.defaultColWidth;
|
|
43067
|
+
const hidden = sheet.hiddenCols.has(c) ? ' hidden="1"' : "";
|
|
43068
|
+
cols.push(`<col min="${c}" max="${c}" width="${w}" customWidth="1"${hidden}/>`);
|
|
42794
43069
|
}
|
|
42795
|
-
|
|
42796
|
-
|
|
42797
|
-
|
|
42798
|
-
|
|
42799
|
-
const isBar = chartType === "bar";
|
|
42800
|
-
let barDir = "";
|
|
42801
|
-
if (chartTag === "c:barChart") {
|
|
42802
|
-
barDir = isBar ? '<c:barDir val="bar"/>' : '<c:barDir val="col"/>';
|
|
43070
|
+
let mergeXml = "";
|
|
43071
|
+
if (sheet.mergedCells.length > 0) {
|
|
43072
|
+
const merges = sheet.mergedCells.map((r) => `<mergeCell ref="${r}"/>`).join("");
|
|
43073
|
+
mergeXml = `<mergeCells count="${sheet.mergedCells.length}">${merges}</mergeCells>`;
|
|
42803
43074
|
}
|
|
42804
|
-
let
|
|
42805
|
-
|
|
42806
|
-
|
|
42807
|
-
|
|
42808
|
-
|
|
43075
|
+
let paneXml = "";
|
|
43076
|
+
let selectionXml = `<selection activeCell="A1" sqref="A1"/>`;
|
|
43077
|
+
if (sheet.freeze) {
|
|
43078
|
+
const activePane = sheet.freeze.col > 0 && sheet.freeze.row > 0 ? "bottomRight" : sheet.freeze.row > 0 ? "bottomLeft" : "topRight";
|
|
43079
|
+
const topLeft = rowColToRef(sheet.freeze.row + 1, sheet.freeze.col + 1);
|
|
43080
|
+
paneXml = `<pane xSplit="${sheet.freeze.col}" ySplit="${sheet.freeze.row}" topLeftCell="${topLeft}" activePane="${activePane}" state="frozen"/>`;
|
|
43081
|
+
selectionXml = `<selection pane="${activePane}" activeCell="${topLeft}" sqref="${topLeft}"/>`;
|
|
42809
43082
|
}
|
|
42810
|
-
const
|
|
42811
|
-
|
|
42812
|
-
|
|
42813
|
-
|
|
42814
|
-
|
|
42815
|
-
|
|
42816
|
-
|
|
42817
|
-
|
|
42818
|
-
|
|
42819
|
-
const sType = s.seriesChartType ?? "col";
|
|
42820
|
-
let group = groups.get(sType);
|
|
42821
|
-
if (!group) {
|
|
42822
|
-
group = [];
|
|
42823
|
-
groups.set(sType, group);
|
|
43083
|
+
const tabSelected = isActive ? ' tabSelected="1"' : "";
|
|
43084
|
+
const sheetView = `<sheetView${tabSelected} workbookViewId="0"${!sheet.view.showGridLines ? ' showGridLines="0"' : ""}>${paneXml}${selectionXml}</sheetView>`;
|
|
43085
|
+
let autoFilterXml = "";
|
|
43086
|
+
if (sheet.autoFilter) {
|
|
43087
|
+
let filterCols = "";
|
|
43088
|
+
for (const col of sheet.autoFilter.columns) {
|
|
43089
|
+
if (col.filterValues && col.filterValues.length > 0) {
|
|
43090
|
+
const filters = col.filterValues.map((v) => `<filter val="${escapeXml(v)}"/>`).join("");
|
|
43091
|
+
filterCols += `<filterColumn colId="${col.colIndex}"><filters>${filters}</filters></filterColumn>`;
|
|
42824
43092
|
}
|
|
42825
|
-
group.push({ series: s, idx });
|
|
42826
|
-
});
|
|
42827
|
-
let chartElements = "";
|
|
42828
|
-
for (const [groupType, groupSeries] of groups) {
|
|
42829
|
-
const groupSeriesXml = groupSeries.map(
|
|
42830
|
-
({ series, idx }) => buildSeriesXml(series, idx, groupType, chart.categories)
|
|
42831
|
-
).join("");
|
|
42832
|
-
chartElements += buildChartTypeElement(groupType, groupSeriesXml, true);
|
|
42833
43093
|
}
|
|
42834
|
-
|
|
42835
|
-
} else {
|
|
42836
|
-
const seriesXml = chart.series.map(
|
|
42837
|
-
(s, idx) => buildSeriesXml(s, idx, chart.chartType, chart.categories)
|
|
42838
|
-
).join("");
|
|
42839
|
-
plotArea = `<c:plotArea><c:layout/>${buildChartTypeElement(chart.chartType, seriesXml, needsAxIds)}`;
|
|
43094
|
+
autoFilterXml = `<autoFilter ref="${sheet.autoFilter.ref}">${filterCols}</autoFilter>`;
|
|
42840
43095
|
}
|
|
42841
|
-
|
|
42842
|
-
|
|
42843
|
-
|
|
42844
|
-
|
|
42845
|
-
|
|
42846
|
-
|
|
42847
|
-
|
|
42848
|
-
|
|
42849
|
-
|
|
42850
|
-
|
|
42851
|
-
|
|
42852
|
-
|
|
42853
|
-
|
|
42854
|
-
|
|
42855
|
-
|
|
42856
|
-
|
|
42857
|
-
|
|
42858
|
-
default:
|
|
42859
|
-
axTag = "c:catAx";
|
|
42860
|
-
break;
|
|
42861
|
-
}
|
|
42862
|
-
let titleXml2 = "";
|
|
42863
|
-
if (ax.title) titleXml2 = `<c:title><c:tx><c:rich><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${escapeXml(ax.title)}</a:t></a:r></a:p></c:rich></c:tx></c:title>`;
|
|
42864
|
-
let scalingXml = '<c:scaling><c:orientation val="minMax"/>';
|
|
42865
|
-
if (ax.min !== void 0) scalingXml += `<c:min val="${ax.min}"/>`;
|
|
42866
|
-
if (ax.max !== void 0) scalingXml += `<c:max val="${ax.max}"/>`;
|
|
42867
|
-
scalingXml += "</c:scaling>";
|
|
42868
|
-
const numFmt = ax.numFmt ? `<c:numFmt formatCode="${escapeXml(ax.numFmt)}" sourceLinked="0"/>` : "";
|
|
42869
|
-
plotArea += `<${axTag}><c:axId val="${axId}"/>${scalingXml}${titleXml2}${numFmt}<c:crossAx val="${crossId}"/></${axTag}>`;
|
|
42870
|
-
}
|
|
43096
|
+
let dvXml = "";
|
|
43097
|
+
if (sheet.dataValidations.length > 0) {
|
|
43098
|
+
const dvEntries = sheet.dataValidations.map((dv) => {
|
|
43099
|
+
let attrs = `sqref="${dv.ref}" type="${dv.type}"`;
|
|
43100
|
+
if (dv.operator) attrs += ` operator="${dv.operator}"`;
|
|
43101
|
+
if (!dv.showDropdown) attrs += ' showDropDown="1"';
|
|
43102
|
+
if (dv.errorStyle) attrs += ` errorStyle="${dv.errorStyle}"`;
|
|
43103
|
+
if (dv.errorTitle) attrs += ` errorTitle="${escapeXml(dv.errorTitle)}"`;
|
|
43104
|
+
if (dv.errorMessage) attrs += ` error="${escapeXml(dv.errorMessage)}"`;
|
|
43105
|
+
if (dv.promptTitle) attrs += ` promptTitle="${escapeXml(dv.promptTitle)}"`;
|
|
43106
|
+
if (dv.promptMessage) attrs += ` prompt="${escapeXml(dv.promptMessage)}"`;
|
|
43107
|
+
let inner = "";
|
|
43108
|
+
if (dv.formula1) inner += `<formula1>${escapeXml(dv.formula1)}</formula1>`;
|
|
43109
|
+
if (dv.formula2) inner += `<formula2>${escapeXml(dv.formula2)}</formula2>`;
|
|
43110
|
+
return `<dataValidation ${attrs}>${inner}</dataValidation>`;
|
|
43111
|
+
}).join("");
|
|
43112
|
+
dvXml = `<dataValidations count="${sheet.dataValidations.length}">${dvEntries}</dataValidations>`;
|
|
42871
43113
|
}
|
|
42872
|
-
|
|
42873
|
-
|
|
42874
|
-
|
|
42875
|
-
titleXml = `<c:title><c:tx><c:rich><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${escapeXml(chart.title)}</a:t></a:r></a:p></c:rich></c:tx></c:title>`;
|
|
43114
|
+
let cfXml = "";
|
|
43115
|
+
if (sheet.conditionalFormats.length > 0) {
|
|
43116
|
+
cfXml = sheet.conditionalFormats.map((cf) => buildConditionalFormattingXml(cf, dxfMap)).join("");
|
|
42876
43117
|
}
|
|
42877
|
-
let
|
|
42878
|
-
if (
|
|
42879
|
-
const
|
|
42880
|
-
|
|
43118
|
+
let hyperlinksXml = "";
|
|
43119
|
+
if (hyperlinkRIds && hyperlinkRIds.size > 0) {
|
|
43120
|
+
const hlEntries = Array.from(hyperlinkRIds.entries()).map(([ref, rId]) => `<hyperlink ref="${ref}" r:id="${rId}"/>`).join("");
|
|
43121
|
+
hyperlinksXml = `<hyperlinks>${hlEntries}</hyperlinks>`;
|
|
42881
43122
|
}
|
|
42882
|
-
|
|
42883
|
-
|
|
42884
|
-
|
|
42885
|
-
|
|
42886
|
-
}
|
|
42887
|
-
function buildAnchorPosition(pos) {
|
|
42888
|
-
return `<xdr:col>${pos.col}</xdr:col><xdr:colOff>${pos.colOffset ?? 0}</xdr:colOff><xdr:row>${pos.row}</xdr:row><xdr:rowOff>${pos.rowOffset ?? 0}</xdr:rowOff>`;
|
|
42889
|
-
}
|
|
42890
|
-
function buildChartAnchorXml(chart, rId) {
|
|
42891
|
-
return `<xdr:twoCellAnchor>
|
|
42892
|
-
<xdr:from>${buildAnchorPosition(chart.anchor.from)}</xdr:from>
|
|
42893
|
-
<xdr:to>${buildAnchorPosition(chart.anchor.to)}</xdr:to>
|
|
42894
|
-
<xdr:graphicFrame macro="">
|
|
42895
|
-
<xdr:nvGraphicFramePr><xdr:cNvPr id="0" name="Chart"/><xdr:cNvGraphicFramePr/></xdr:nvGraphicFramePr>
|
|
42896
|
-
<xdr:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/></xdr:xfrm>
|
|
42897
|
-
<a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart"><c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" r:id="${rId}"/></a:graphicData></a:graphic>
|
|
42898
|
-
</xdr:graphicFrame>
|
|
42899
|
-
<xdr:clientData/>
|
|
42900
|
-
</xdr:twoCellAnchor>`;
|
|
42901
|
-
}
|
|
42902
|
-
function buildImageAnchorXml(image, rId) {
|
|
42903
|
-
return `<xdr:twoCellAnchor editAs="oneCell">
|
|
42904
|
-
<xdr:from>${buildAnchorPosition(image.tl)}</xdr:from>
|
|
42905
|
-
<xdr:to>${buildAnchorPosition(image.br)}</xdr:to>
|
|
42906
|
-
<xdr:pic>
|
|
42907
|
-
<xdr:nvPicPr><xdr:cNvPr id="0" name="Image"/><xdr:cNvPicPr/></xdr:nvPicPr>
|
|
42908
|
-
<xdr:blipFill><a:blip xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:embed="${rId}"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill>
|
|
42909
|
-
<xdr:spPr><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></xdr:spPr>
|
|
42910
|
-
</xdr:pic>
|
|
42911
|
-
<xdr:clientData/>
|
|
42912
|
-
</xdr:twoCellAnchor>`;
|
|
42913
|
-
}
|
|
42914
|
-
function buildShapeAnchorXml(drawing) {
|
|
42915
|
-
let fillXml = "";
|
|
42916
|
-
if (drawing.fillColor) fillXml = `<a:solidFill><a:srgbClr val="${hexToOoxmlRgb(drawing.fillColor)}"/></a:solidFill>`;
|
|
42917
|
-
let outlineXml = "";
|
|
42918
|
-
if (drawing.outlineColor) {
|
|
42919
|
-
const w = Math.round((drawing.outlineWidth ?? 1) * 12700);
|
|
42920
|
-
outlineXml = `<a:ln w="${w}"><a:solidFill><a:srgbClr val="${hexToOoxmlRgb(drawing.outlineColor)}"/></a:solidFill></a:ln>`;
|
|
43123
|
+
const drawingXml = drawingRId ? `<drawing r:id="${drawingRId}"/>` : "";
|
|
43124
|
+
let tablePartsXml = "";
|
|
43125
|
+
if (tableRIds && tableRIds.length > 0) {
|
|
43126
|
+
const parts = tableRIds.map((rId) => `<tablePart r:id="${rId}"/>`).join("");
|
|
43127
|
+
tablePartsXml = `<tableParts count="${tableRIds.length}">${parts}</tableParts>`;
|
|
42921
43128
|
}
|
|
42922
|
-
const
|
|
42923
|
-
|
|
42924
|
-
|
|
42925
|
-
|
|
42926
|
-
|
|
42927
|
-
|
|
42928
|
-
|
|
42929
|
-
|
|
42930
|
-
|
|
42931
|
-
|
|
42932
|
-
|
|
42933
|
-
|
|
42934
|
-
|
|
42935
|
-
|
|
42936
|
-
|
|
42937
|
-
|
|
42938
|
-
|
|
42939
|
-
|
|
42940
|
-
|
|
42941
|
-
|
|
42942
|
-
|
|
42943
|
-
|
|
42944
|
-
|
|
42945
|
-
|
|
42946
|
-
|
|
42947
|
-
|
|
42948
|
-
|
|
42949
|
-
|
|
42950
|
-
|
|
42951
|
-
|
|
42952
|
-
|
|
42953
|
-
|
|
42954
|
-
|
|
42955
|
-
|
|
42956
|
-
|
|
42957
|
-
|
|
42958
|
-
|
|
42959
|
-
|
|
42960
|
-
|
|
42961
|
-
return `<cfRule type="dataBar" priority="${rule.priority}"><dataBar minLength="${rule.minLength}" maxLength="${rule.maxLength}" showValue="${showVal}"><cfvo type="min"/><cfvo type="max"/><color rgb="${hexToArgb(rule.color)}"/></dataBar></cfRule>`;
|
|
42962
|
-
}
|
|
42963
|
-
case "iconSet": {
|
|
42964
|
-
const thresholds = rule.thresholds.map((t) => {
|
|
42965
|
-
if (t.type === "min" || t.type === "autoMin") return '<cfvo type="min"/>';
|
|
42966
|
-
if (t.type === "max" || t.type === "autoMax") return '<cfvo type="max"/>';
|
|
42967
|
-
return `<cfvo type="${t.type}" val="${t.value ?? 0}"/>`;
|
|
42968
|
-
}).join("");
|
|
42969
|
-
const showVal = rule.showValue ? "" : ' showValue="0"';
|
|
42970
|
-
const reverse = rule.reverse ? ' reverse="1"' : "";
|
|
42971
|
-
return `<cfRule type="iconSet" priority="${rule.priority}"><iconSet iconSet="${rule.iconSet}"${showVal}${reverse}>${thresholds}</iconSet></cfRule>`;
|
|
42972
|
-
}
|
|
42973
|
-
case "style": {
|
|
42974
|
-
let attrs = `type="${rule.type}" priority="${rule.priority}"`;
|
|
42975
|
-
if (rule.style) {
|
|
42976
|
-
const dxfId = dxfMap.get(JSON.stringify(rule.style));
|
|
42977
|
-
if (dxfId !== void 0) attrs += ` dxfId="${dxfId}"`;
|
|
42978
|
-
}
|
|
42979
|
-
if (rule.operator) attrs += ` operator="${rule.operator}"`;
|
|
42980
|
-
if (rule.text) attrs += ` text="${escapeXml(rule.text)}"`;
|
|
42981
|
-
if (rule.rank !== void 0) attrs += ` rank="${rule.rank}"`;
|
|
42982
|
-
if (rule.percent) attrs += ' percent="1"';
|
|
42983
|
-
if (rule.bottom) attrs += ' bottom="1"';
|
|
42984
|
-
if (rule.aboveAverage === false) attrs += ' aboveAverage="0"';
|
|
42985
|
-
if (rule.timePeriod) attrs += ` timePeriod="${rule.timePeriod}"`;
|
|
42986
|
-
let inner = "";
|
|
42987
|
-
if (rule.formulae) {
|
|
42988
|
-
inner = rule.formulae.map((f) => `<formula>${escapeXml(String(f))}</formula>`).join("");
|
|
42989
|
-
}
|
|
42990
|
-
return `<cfRule ${attrs}>${inner}</cfRule>`;
|
|
42991
|
-
}
|
|
43129
|
+
const ps = sheet.pageSetup;
|
|
43130
|
+
const hf = sheet.headerFooter;
|
|
43131
|
+
const fitToPage = ps && (ps.fitToWidth !== void 0 || ps.fitToHeight !== void 0);
|
|
43132
|
+
const sheetPrXml = fitToPage ? `<sheetPr><pageSetUpPr fitToPage="1"/></sheetPr>` : "";
|
|
43133
|
+
const marginsXml = (() => {
|
|
43134
|
+
const m = ps?.margins;
|
|
43135
|
+
const left = m?.left ?? 0.7;
|
|
43136
|
+
const right = m?.right ?? 0.7;
|
|
43137
|
+
const top = m?.top ?? 0.75;
|
|
43138
|
+
const bottom = m?.bottom ?? 0.75;
|
|
43139
|
+
const header = m?.header ?? 0.3;
|
|
43140
|
+
const footer = m?.footer ?? 0.3;
|
|
43141
|
+
return `<pageMargins left="${left}" right="${right}" top="${top}" bottom="${bottom}" header="${header}" footer="${footer}"/>`;
|
|
43142
|
+
})();
|
|
43143
|
+
let pageSetupXml = "";
|
|
43144
|
+
if (ps) {
|
|
43145
|
+
const attrs = [];
|
|
43146
|
+
if (ps.paperSize !== void 0) attrs.push(`paperSize="${ps.paperSize}"`);
|
|
43147
|
+
if (ps.scale !== void 0) attrs.push(`scale="${ps.scale}"`);
|
|
43148
|
+
if (ps.fitToWidth !== void 0) attrs.push(`fitToWidth="${ps.fitToWidth}"`);
|
|
43149
|
+
if (ps.fitToHeight !== void 0) attrs.push(`fitToHeight="${ps.fitToHeight}"`);
|
|
43150
|
+
if (ps.orientation) attrs.push(`orientation="${ps.orientation}"`);
|
|
43151
|
+
if (attrs.length > 0) pageSetupXml = `<pageSetup ${attrs.join(" ")}/>`;
|
|
43152
|
+
}
|
|
43153
|
+
let headerFooterXml = "";
|
|
43154
|
+
if (hf) {
|
|
43155
|
+
const rootAttrs = [];
|
|
43156
|
+
if (hf.differentOddEven) rootAttrs.push(`differentOddEven="1"`);
|
|
43157
|
+
if (hf.differentFirst) rootAttrs.push(`differentFirst="1"`);
|
|
43158
|
+
const inner = [];
|
|
43159
|
+
if (hf.oddHeader) inner.push(`<oddHeader>${escapeXml(hf.oddHeader)}</oddHeader>`);
|
|
43160
|
+
if (hf.oddFooter) inner.push(`<oddFooter>${escapeXml(hf.oddFooter)}</oddFooter>`);
|
|
43161
|
+
if (hf.evenHeader) inner.push(`<evenHeader>${escapeXml(hf.evenHeader)}</evenHeader>`);
|
|
43162
|
+
if (hf.evenFooter) inner.push(`<evenFooter>${escapeXml(hf.evenFooter)}</evenFooter>`);
|
|
43163
|
+
if (hf.firstHeader) inner.push(`<firstHeader>${escapeXml(hf.firstHeader)}</firstHeader>`);
|
|
43164
|
+
if (hf.firstFooter) inner.push(`<firstFooter>${escapeXml(hf.firstFooter)}</firstFooter>`);
|
|
43165
|
+
if (inner.length > 0) {
|
|
43166
|
+
const attrStr = rootAttrs.length > 0 ? ` ${rootAttrs.join(" ")}` : "";
|
|
43167
|
+
headerFooterXml = `<headerFooter${attrStr}>${inner.join("")}</headerFooter>`;
|
|
42992
43168
|
}
|
|
42993
|
-
}).join("");
|
|
42994
|
-
return `<conditionalFormatting sqref="${cf.ref}">${rules}</conditionalFormatting>`;
|
|
42995
|
-
}
|
|
42996
|
-
function buildDxfXml(style) {
|
|
42997
|
-
let inner = "";
|
|
42998
|
-
if (style.fontBold || style.fontItalic || style.fontColor) {
|
|
42999
|
-
let fontParts = "";
|
|
43000
|
-
if (style.fontBold) fontParts += "<b/>";
|
|
43001
|
-
if (style.fontItalic) fontParts += "<i/>";
|
|
43002
|
-
if (style.fontColor) fontParts += `<color rgb="${hexToArgb(style.fontColor)}"/>`;
|
|
43003
|
-
inner += `<font>${fontParts}</font>`;
|
|
43004
43169
|
}
|
|
43005
|
-
|
|
43006
|
-
|
|
43170
|
+
let dimensionRef = "A1";
|
|
43171
|
+
if (sortedRows.length > 0) {
|
|
43172
|
+
let minCol = Infinity, maxCol = 0;
|
|
43173
|
+
const minRow = sortedRows[0];
|
|
43174
|
+
const maxRow = sortedRows[sortedRows.length - 1];
|
|
43175
|
+
for (const rowNum of sortedRows) {
|
|
43176
|
+
const cells = rowMap.get(rowNum);
|
|
43177
|
+
for (const { col } of cells) {
|
|
43178
|
+
if (col < minCol) minCol = col;
|
|
43179
|
+
if (col > maxCol) maxCol = col;
|
|
43180
|
+
}
|
|
43181
|
+
}
|
|
43182
|
+
dimensionRef = `${rowColToRef(minRow, minCol)}:${rowColToRef(maxRow, maxCol)}`;
|
|
43007
43183
|
}
|
|
43008
|
-
return
|
|
43009
|
-
|
|
43010
|
-
|
|
43011
|
-
|
|
43012
|
-
|
|
43013
|
-
|
|
43014
|
-
|
|
43015
|
-
|
|
43016
|
-
|
|
43017
|
-
|
|
43018
|
-
|
|
43019
|
-
|
|
43020
|
-
const bytes = new Uint8Array(binary.length);
|
|
43021
|
-
for (let i2 = 0; i2 < binary.length; i2++) bytes[i2] = binary.charCodeAt(i2);
|
|
43022
|
-
return bytes;
|
|
43184
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
43185
|
+
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
|
43186
|
+
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
|
43187
|
+
${sheetPrXml}<dimension ref="${dimensionRef}"/>
|
|
43188
|
+
<sheetViews>${sheetView}</sheetViews>
|
|
43189
|
+
<sheetFormatPr defaultRowHeight="${sheet.defaultRowHeight}" defaultColWidth="${sheet.defaultColWidth}"/>
|
|
43190
|
+
${cols.length > 0 ? `<cols>${cols.join("")}</cols>` : ""}
|
|
43191
|
+
<sheetData>
|
|
43192
|
+
${rows.join("\n")}
|
|
43193
|
+
</sheetData>
|
|
43194
|
+
${autoFilterXml}${mergeXml}${cfXml}${dvXml}${hyperlinksXml}${marginsXml}${pageSetupXml}${headerFooterXml}${drawingXml}${tablePartsXml}
|
|
43195
|
+
</worksheet>`;
|
|
43023
43196
|
}
|
|
43024
|
-
function
|
|
43025
|
-
|
|
43197
|
+
function getCellType(cell, ssIndex) {
|
|
43198
|
+
if (cell.error) return "e";
|
|
43199
|
+
if (cell.formula && typeof cell.value === "string") return "str";
|
|
43200
|
+
if (typeof cell.value === "string" && ssIndex.has(cell.value)) return "s";
|
|
43201
|
+
if (typeof cell.value === "boolean") return "b";
|
|
43202
|
+
return void 0;
|
|
43026
43203
|
}
|
|
43027
|
-
|
|
43028
|
-
|
|
43029
|
-
|
|
43030
|
-
|
|
43204
|
+
function getCellValue(cell, ssIndex) {
|
|
43205
|
+
if (cell.value === null) return void 0;
|
|
43206
|
+
if (cell.error) return cell.error;
|
|
43207
|
+
if (cell.formula && typeof cell.value === "string") return cell.value;
|
|
43208
|
+
if (typeof cell.value === "string") {
|
|
43209
|
+
const idx = ssIndex.get(cell.value);
|
|
43210
|
+
return idx !== void 0 ? idx : cell.value;
|
|
43211
|
+
}
|
|
43212
|
+
if (typeof cell.value === "boolean") return cell.value ? 1 : 0;
|
|
43213
|
+
return cell.value;
|
|
43031
43214
|
}
|
|
43032
|
-
function
|
|
43033
|
-
|
|
43034
|
-
return { borderTop: b, borderRight: b, borderBottom: b, borderLeft: b };
|
|
43215
|
+
function quoteSheetName(name) {
|
|
43216
|
+
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(name) ? name : `'${name.replace(/'/g, "''")}'`;
|
|
43035
43217
|
}
|
|
43036
|
-
|
|
43037
|
-
|
|
43038
|
-
|
|
43039
|
-
|
|
43040
|
-
const
|
|
43041
|
-
const
|
|
43042
|
-
|
|
43043
|
-
|
|
43044
|
-
|
|
43045
|
-
|
|
43046
|
-
|
|
43047
|
-
|
|
43048
|
-
|
|
43049
|
-
|
|
43050
|
-
|
|
43051
|
-
|
|
43052
|
-
bucket = [];
|
|
43053
|
-
groups.set(key, bucket);
|
|
43218
|
+
function buildWorkbookXml(workbook, pivotInfo) {
|
|
43219
|
+
const sheets = workbook.sheets.map(
|
|
43220
|
+
(s, i2) => `<sheet name="${escapeXml(s.name)}" sheetId="${i2 + 1}" r:id="rId${i2 + 1}"/>`
|
|
43221
|
+
).join("\n");
|
|
43222
|
+
const nameEntries = [];
|
|
43223
|
+
for (const [name, value] of workbook.namedRanges) {
|
|
43224
|
+
nameEntries.push(`<definedName name="${escapeXml(name)}">${escapeXml(value)}</definedName>`);
|
|
43225
|
+
}
|
|
43226
|
+
workbook.sheets.forEach((s, i2) => {
|
|
43227
|
+
const pt = s.printTitles;
|
|
43228
|
+
if (!pt || !pt.repeatRows && !pt.repeatCols) return;
|
|
43229
|
+
const parts = [];
|
|
43230
|
+
const sheetName = quoteSheetName(s.name);
|
|
43231
|
+
if (pt.repeatCols) {
|
|
43232
|
+
const [start, end] = pt.repeatCols;
|
|
43233
|
+
parts.push(`${sheetName}!$${colNumToLetters(start)}:$${colNumToLetters(end)}`);
|
|
43054
43234
|
}
|
|
43055
|
-
|
|
43235
|
+
if (pt.repeatRows) {
|
|
43236
|
+
const [start, end] = pt.repeatRows;
|
|
43237
|
+
parts.push(`${sheetName}!$${start}:$${end}`);
|
|
43238
|
+
}
|
|
43239
|
+
nameEntries.push(
|
|
43240
|
+
`<definedName name="_xlnm.Print_Titles" localSheetId="${i2}">${escapeXml(parts.join(","))}</definedName>`
|
|
43241
|
+
);
|
|
43242
|
+
});
|
|
43243
|
+
const definedNames = nameEntries.length > 0 ? `
|
|
43244
|
+
<definedNames>
|
|
43245
|
+
${nameEntries.join("\n")}
|
|
43246
|
+
</definedNames>` : "";
|
|
43247
|
+
let pivotCachesBlock = "";
|
|
43248
|
+
if (pivotInfo && pivotInfo.cachesByWorkbook.size > 0) {
|
|
43249
|
+
const baseRId = workbook.sheets.length + 3;
|
|
43250
|
+
const cacheIds = [...pivotInfo.cachesByWorkbook.keys()].sort((a, b) => a - b);
|
|
43251
|
+
const items = cacheIds.map((cacheId, i2) => `<pivotCache cacheId="${cacheId}" r:id="rId${baseRId + i2}"/>`).join("\n");
|
|
43252
|
+
pivotCachesBlock = `
|
|
43253
|
+
<pivotCaches>
|
|
43254
|
+
${items}
|
|
43255
|
+
</pivotCaches>`;
|
|
43056
43256
|
}
|
|
43057
|
-
return
|
|
43257
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
43258
|
+
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"
|
|
43259
|
+
xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
|
43260
|
+
<bookViews>
|
|
43261
|
+
<workbookView activeTab="${workbook.activeSheetIndex}"/>
|
|
43262
|
+
</bookViews>
|
|
43263
|
+
<sheets>
|
|
43264
|
+
${sheets}
|
|
43265
|
+
</sheets>${definedNames}${pivotCachesBlock}
|
|
43266
|
+
<calcPr fullCalcOnLoad="1"/>
|
|
43267
|
+
</workbook>`;
|
|
43058
43268
|
}
|
|
43059
|
-
function
|
|
43060
|
-
const
|
|
43061
|
-
|
|
43062
|
-
const cfg = table.fields[fi];
|
|
43063
|
-
if (cfg?.selectedPageItem == null) continue;
|
|
43064
|
-
const cacheField = cache.fields[fi];
|
|
43065
|
-
if (!cacheField) continue;
|
|
43066
|
-
const allowed = cacheField.items[cfg.selectedPageItem];
|
|
43067
|
-
if (allowed) filters.push({ fieldIndex: fi, allowed });
|
|
43068
|
-
}
|
|
43069
|
-
if (filters.length === 0) return records;
|
|
43070
|
-
return records.filter(
|
|
43071
|
-
(rec) => filters.every(
|
|
43072
|
-
({ fieldIndex, allowed }) => cellMatchesItem(rec[fieldIndex], allowed)
|
|
43073
|
-
)
|
|
43269
|
+
function buildWorkbookRels(workbook, pivotInfo) {
|
|
43270
|
+
const rels = workbook.sheets.map(
|
|
43271
|
+
(_, i2) => `<Relationship Id="rId${i2 + 1}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet${i2 + 1}.xml"/>`
|
|
43074
43272
|
);
|
|
43075
|
-
}
|
|
43076
|
-
|
|
43077
|
-
|
|
43078
|
-
|
|
43079
|
-
|
|
43080
|
-
|
|
43081
|
-
|
|
43082
|
-
|
|
43083
|
-
|
|
43084
|
-
|
|
43085
|
-
|
|
43086
|
-
|
|
43087
|
-
return cell === void 0 || cell === null || cell === "";
|
|
43088
|
-
case "error":
|
|
43089
|
-
return typeof cell === "string" && cell === item.value;
|
|
43273
|
+
rels.push(`<Relationship Id="rId${workbook.sheets.length + 1}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>`);
|
|
43274
|
+
rels.push(`<Relationship Id="rId${workbook.sheets.length + 2}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings" Target="sharedStrings.xml"/>`);
|
|
43275
|
+
if (pivotInfo && pivotInfo.cachesByWorkbook.size > 0) {
|
|
43276
|
+
const baseRId = workbook.sheets.length + 3;
|
|
43277
|
+
const cacheIds = [...pivotInfo.cachesByWorkbook.keys()].sort((a, b) => a - b);
|
|
43278
|
+
cacheIds.forEach((cacheId, i2) => {
|
|
43279
|
+
const target = pivotInfo.cachesByWorkbook.get(cacheId);
|
|
43280
|
+
if (!target) return;
|
|
43281
|
+
rels.push(
|
|
43282
|
+
`<Relationship Id="rId${baseRId + i2}" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheDefinition" Target="${escapeXml(target)}"/>`
|
|
43283
|
+
);
|
|
43284
|
+
});
|
|
43090
43285
|
}
|
|
43286
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
43287
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
43288
|
+
${rels.join("\n")}
|
|
43289
|
+
</Relationships>`;
|
|
43290
|
+
}
|
|
43291
|
+
function buildContentTypes(sheetCount, extraTypes = []) {
|
|
43292
|
+
const sheetTypes = Array.from(
|
|
43293
|
+
{ length: sheetCount },
|
|
43294
|
+
(_, i2) => `<Override PartName="/xl/worksheets/sheet${i2 + 1}.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>`
|
|
43295
|
+
).join("\n");
|
|
43296
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
43297
|
+
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
|
|
43298
|
+
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
|
|
43299
|
+
<Default Extension="xml" ContentType="application/xml"/>
|
|
43300
|
+
<Default Extension="png" ContentType="image/png"/>
|
|
43301
|
+
<Default Extension="jpeg" ContentType="image/jpeg"/>
|
|
43302
|
+
<Default Extension="jpg" ContentType="image/jpeg"/>
|
|
43303
|
+
<Default Extension="gif" ContentType="image/gif"/>
|
|
43304
|
+
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
|
|
43305
|
+
${sheetTypes}
|
|
43306
|
+
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
|
|
43307
|
+
<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
|
|
43308
|
+
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
|
|
43309
|
+
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
|
|
43310
|
+
${extraTypes.join("\n")}
|
|
43311
|
+
</Types>`;
|
|
43091
43312
|
}
|
|
43092
|
-
function
|
|
43093
|
-
return
|
|
43313
|
+
function buildRootRels() {
|
|
43314
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
43315
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
|
|
43316
|
+
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>
|
|
43317
|
+
<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/>
|
|
43318
|
+
<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/>
|
|
43319
|
+
</Relationships>`;
|
|
43094
43320
|
}
|
|
43095
|
-
function
|
|
43096
|
-
const
|
|
43097
|
-
|
|
43098
|
-
|
|
43099
|
-
|
|
43100
|
-
|
|
43101
|
-
|
|
43102
|
-
|
|
43103
|
-
|
|
43104
|
-
|
|
43105
|
-
out.sort((a, b) => {
|
|
43106
|
-
for (let i2 = 0; i2 < Math.max(a.length, b.length); i2++) {
|
|
43107
|
-
const av = a[i2];
|
|
43108
|
-
const bv = b[i2];
|
|
43109
|
-
if (av === bv) continue;
|
|
43110
|
-
const as = av === null || av === void 0 ? "" : String(av);
|
|
43111
|
-
const bs = bv === null || bv === void 0 ? "" : String(bv);
|
|
43112
|
-
if (as < bs) return -1;
|
|
43113
|
-
if (as > bs) return 1;
|
|
43114
|
-
}
|
|
43115
|
-
return 0;
|
|
43116
|
-
});
|
|
43117
|
-
return out;
|
|
43321
|
+
function buildCoreProps() {
|
|
43322
|
+
const now = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
43323
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
43324
|
+
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties"
|
|
43325
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
43326
|
+
xmlns:dcterms="http://purl.org/dc/terms/"
|
|
43327
|
+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
43328
|
+
<dcterms:created xsi:type="dcterms:W3CDTF">${now}</dcterms:created>
|
|
43329
|
+
<dcterms:modified xsi:type="dcterms:W3CDTF">${now}</dcterms:modified>
|
|
43330
|
+
</cp:coreProperties>`;
|
|
43118
43331
|
}
|
|
43119
|
-
function
|
|
43120
|
-
|
|
43121
|
-
|
|
43122
|
-
|
|
43123
|
-
|
|
43124
|
-
case "countNums":
|
|
43125
|
-
return numeric.length;
|
|
43126
|
-
case "sum":
|
|
43127
|
-
return numeric.reduce((a, b) => a + b, 0);
|
|
43128
|
-
case "average":
|
|
43129
|
-
if (numeric.length === 0) return null;
|
|
43130
|
-
return numeric.reduce((a, b) => a + b, 0) / numeric.length;
|
|
43131
|
-
case "min":
|
|
43132
|
-
return numeric.length === 0 ? null : Math.min(...numeric);
|
|
43133
|
-
case "max":
|
|
43134
|
-
return numeric.length === 0 ? null : Math.max(...numeric);
|
|
43135
|
-
case "product":
|
|
43136
|
-
return numeric.length === 0 ? null : numeric.reduce((a, b) => a * b, 1);
|
|
43137
|
-
}
|
|
43332
|
+
function buildAppProps() {
|
|
43333
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
43334
|
+
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties">
|
|
43335
|
+
<Application>Microsoft Excel</Application>
|
|
43336
|
+
</Properties>`;
|
|
43138
43337
|
}
|
|
43139
|
-
|
|
43140
|
-
|
|
43141
|
-
|
|
43142
|
-
|
|
43143
|
-
|
|
43144
|
-
|
|
43145
|
-
|
|
43146
|
-
|
|
43147
|
-
|
|
43148
|
-
|
|
43149
|
-
|
|
43150
|
-
|
|
43151
|
-
|
|
43152
|
-
|
|
43153
|
-
|
|
43338
|
+
var CHART_TYPE_MAP2 = {
|
|
43339
|
+
bar: "c:barChart",
|
|
43340
|
+
col: "c:barChart",
|
|
43341
|
+
line: "c:lineChart",
|
|
43342
|
+
pie: "c:pieChart",
|
|
43343
|
+
doughnut: "c:doughnutChart",
|
|
43344
|
+
area: "c:areaChart",
|
|
43345
|
+
scatter: "c:scatterChart",
|
|
43346
|
+
bubble: "c:bubbleChart",
|
|
43347
|
+
radar: "c:radarChart",
|
|
43348
|
+
stock: "c:stockChart",
|
|
43349
|
+
surface: "c:surfaceChart"
|
|
43350
|
+
};
|
|
43351
|
+
function buildSeriesXml(s, idx, chartType, categories) {
|
|
43352
|
+
let nameXml = "";
|
|
43353
|
+
if (s.name) nameXml = `<c:tx><c:strRef><c:strCache><c:ptCount val="1"/><c:pt idx="0"><c:v>${escapeXml(s.name)}</c:v></c:pt></c:strCache></c:strRef></c:tx>`;
|
|
43354
|
+
let colorXml = "";
|
|
43355
|
+
if (s.color) colorXml = `<c:spPr><a:solidFill><a:srgbClr val="${hexToOoxmlRgb(s.color)}"/></a:solidFill></c:spPr>`;
|
|
43356
|
+
const valTag = chartType === "scatter" || chartType === "bubble" ? "c:yVal" : "c:val";
|
|
43357
|
+
const valPts = s.values.map((v, i2) => `<c:pt idx="${i2}"><c:v>${v}</c:v></c:pt>`).join("");
|
|
43358
|
+
const valXml = `<${valTag}><c:numRef><c:numCache><c:ptCount val="${s.values.length}"/>${valPts}</c:numCache></c:numRef></${valTag}>`;
|
|
43359
|
+
let catXml = "";
|
|
43360
|
+
if (categories && categories.length > 0) {
|
|
43361
|
+
const catTag = chartType === "scatter" || chartType === "bubble" ? "c:xVal" : "c:cat";
|
|
43362
|
+
const catPts = categories.map((c, i2) => `<c:pt idx="${i2}"><c:v>${escapeXml(c)}</c:v></c:pt>`).join("");
|
|
43363
|
+
catXml = `<${catTag}><c:strRef><c:strCache><c:ptCount val="${categories.length}"/>${catPts}</c:strCache></c:strRef></${catTag}>`;
|
|
43154
43364
|
}
|
|
43155
|
-
|
|
43156
|
-
|
|
43157
|
-
|
|
43158
|
-
|
|
43159
|
-
for (let i2 = 0; i2 < numDataFields; i2++) {
|
|
43160
|
-
cells[level][col + i2] = { kind: "colHeader", depth: level, text };
|
|
43161
|
-
}
|
|
43162
|
-
col += numDataFields;
|
|
43163
|
-
}
|
|
43365
|
+
let bubbleXml = "";
|
|
43366
|
+
if (s.bubbleSizes) {
|
|
43367
|
+
const bPts = s.bubbleSizes.map((v, i2) => `<c:pt idx="${i2}"><c:v>${v}</c:v></c:pt>`).join("");
|
|
43368
|
+
bubbleXml = `<c:bubbleSize><c:numRef><c:numCache><c:ptCount val="${s.bubbleSizes.length}"/>${bPts}</c:numCache></c:numRef></c:bubbleSize>`;
|
|
43164
43369
|
}
|
|
43165
|
-
|
|
43166
|
-
|
|
43167
|
-
|
|
43168
|
-
|
|
43169
|
-
|
|
43170
|
-
|
|
43171
|
-
|
|
43172
|
-
|
|
43173
|
-
};
|
|
43174
|
-
}
|
|
43175
|
-
col += numDataFields;
|
|
43176
|
-
}
|
|
43177
|
-
if (showColGrand) {
|
|
43178
|
-
for (let d = 0; d < table.dataFields.length; d++) {
|
|
43179
|
-
cells[labelRow][rowLabelCols + dataCols + d] = {
|
|
43180
|
-
kind: "valueLabel",
|
|
43181
|
-
text: table.dataFields[d].name
|
|
43182
|
-
};
|
|
43183
|
-
}
|
|
43184
|
-
}
|
|
43370
|
+
return `<c:ser><c:idx val="${idx}"/><c:order val="${idx}"/>${nameXml}${colorXml}${catXml}${valXml}${bubbleXml}</c:ser>`;
|
|
43371
|
+
}
|
|
43372
|
+
function buildChartTypeElement(chartType, seriesXml, needsAxIds) {
|
|
43373
|
+
const chartTag = CHART_TYPE_MAP2[chartType] ?? "c:barChart";
|
|
43374
|
+
const isBar = chartType === "bar";
|
|
43375
|
+
let barDir = "";
|
|
43376
|
+
if (chartTag === "c:barChart") {
|
|
43377
|
+
barDir = isBar ? '<c:barDir val="bar"/>' : '<c:barDir val="col"/>';
|
|
43185
43378
|
}
|
|
43186
|
-
|
|
43187
|
-
|
|
43188
|
-
|
|
43189
|
-
|
|
43190
|
-
|
|
43191
|
-
kind: "rowHeader",
|
|
43192
|
-
depth: level,
|
|
43193
|
-
text: formatCellLabel(rowTuple[level])
|
|
43194
|
-
};
|
|
43195
|
-
}
|
|
43196
|
-
for (let c = 0; c < colTuples.length; c++) {
|
|
43197
|
-
const colTuple = colTuples[c];
|
|
43198
|
-
const groupRecords = groups.get(JSON.stringify([rowTuple, colTuple])) ?? [];
|
|
43199
|
-
for (let d = 0; d < table.dataFields.length; d++) {
|
|
43200
|
-
const df = table.dataFields[d];
|
|
43201
|
-
const values2 = groupRecords.map((rec) => rec[df.fieldIndex]);
|
|
43202
|
-
cells[gridRow][rowLabelCols + c * numDataFields + d] = {
|
|
43203
|
-
kind: "value",
|
|
43204
|
-
value: aggregate(values2, df.subtotal),
|
|
43205
|
-
numFmt: df.numFmt
|
|
43206
|
-
};
|
|
43207
|
-
}
|
|
43208
|
-
}
|
|
43209
|
-
if (showColGrand) {
|
|
43210
|
-
const rowOnly = allRecords.filter(
|
|
43211
|
-
(rec) => sameTuple(tupleOf(rec, table.rowFieldIndices), rowTuple)
|
|
43212
|
-
);
|
|
43213
|
-
for (let d = 0; d < table.dataFields.length; d++) {
|
|
43214
|
-
const df = table.dataFields[d];
|
|
43215
|
-
cells[gridRow][rowLabelCols + dataCols + d] = {
|
|
43216
|
-
kind: "rowTotal",
|
|
43217
|
-
value: aggregate(
|
|
43218
|
-
rowOnly.map((rec) => rec[df.fieldIndex]),
|
|
43219
|
-
df.subtotal
|
|
43220
|
-
)
|
|
43221
|
-
};
|
|
43222
|
-
}
|
|
43223
|
-
}
|
|
43379
|
+
let grouping = "";
|
|
43380
|
+
if (chartTag === "c:barChart") {
|
|
43381
|
+
grouping = '<c:grouping val="clustered"/>';
|
|
43382
|
+
} else if (chartTag === "c:lineChart" || chartTag === "c:areaChart") {
|
|
43383
|
+
grouping = '<c:grouping val="clustered"/>';
|
|
43224
43384
|
}
|
|
43225
|
-
|
|
43226
|
-
|
|
43227
|
-
|
|
43228
|
-
|
|
43229
|
-
|
|
43230
|
-
|
|
43231
|
-
|
|
43232
|
-
|
|
43233
|
-
|
|
43234
|
-
|
|
43235
|
-
|
|
43236
|
-
|
|
43237
|
-
|
|
43238
|
-
|
|
43239
|
-
df.subtotal
|
|
43240
|
-
)
|
|
43241
|
-
};
|
|
43385
|
+
const axIds = needsAxIds ? '<c:axId val="1"/><c:axId val="2"/>' : "";
|
|
43386
|
+
return `<${chartTag}>${barDir}${grouping}${seriesXml}${axIds}</${chartTag}>`;
|
|
43387
|
+
}
|
|
43388
|
+
function buildChartXml(chart) {
|
|
43389
|
+
const needsAxIds = chart.chartType !== "pie" && chart.chartType !== "doughnut";
|
|
43390
|
+
let plotArea;
|
|
43391
|
+
if (chart.chartType === "combo") {
|
|
43392
|
+
const groups = /* @__PURE__ */ new Map();
|
|
43393
|
+
chart.series.forEach((s, idx) => {
|
|
43394
|
+
const sType = s.seriesChartType ?? "col";
|
|
43395
|
+
let group = groups.get(sType);
|
|
43396
|
+
if (!group) {
|
|
43397
|
+
group = [];
|
|
43398
|
+
groups.set(sType, group);
|
|
43242
43399
|
}
|
|
43400
|
+
group.push({ series: s, idx });
|
|
43401
|
+
});
|
|
43402
|
+
let chartElements = "";
|
|
43403
|
+
for (const [groupType, groupSeries] of groups) {
|
|
43404
|
+
const groupSeriesXml = groupSeries.map(
|
|
43405
|
+
({ series, idx }) => buildSeriesXml(series, idx, groupType, chart.categories)
|
|
43406
|
+
).join("");
|
|
43407
|
+
chartElements += buildChartTypeElement(groupType, groupSeriesXml, true);
|
|
43243
43408
|
}
|
|
43244
|
-
|
|
43245
|
-
|
|
43246
|
-
|
|
43247
|
-
|
|
43248
|
-
|
|
43249
|
-
|
|
43250
|
-
|
|
43251
|
-
|
|
43252
|
-
|
|
43253
|
-
|
|
43409
|
+
plotArea = `<c:plotArea><c:layout/>${chartElements}`;
|
|
43410
|
+
} else {
|
|
43411
|
+
const seriesXml = chart.series.map(
|
|
43412
|
+
(s, idx) => buildSeriesXml(s, idx, chart.chartType, chart.categories)
|
|
43413
|
+
).join("");
|
|
43414
|
+
plotArea = `<c:plotArea><c:layout/>${buildChartTypeElement(chart.chartType, seriesXml, needsAxIds)}`;
|
|
43415
|
+
}
|
|
43416
|
+
if (chart.chartType !== "pie" && chart.chartType !== "doughnut") {
|
|
43417
|
+
const axes = chart.axes ?? [{ type: "category" }, { type: "value" }];
|
|
43418
|
+
for (let i2 = 0; i2 < axes.length; i2++) {
|
|
43419
|
+
const ax = axes[i2];
|
|
43420
|
+
const axId = i2 + 1;
|
|
43421
|
+
const crossId = i2 === 0 ? 2 : 1;
|
|
43422
|
+
let axTag;
|
|
43423
|
+
switch (ax.type) {
|
|
43424
|
+
case "value":
|
|
43425
|
+
axTag = "c:valAx";
|
|
43426
|
+
break;
|
|
43427
|
+
case "date":
|
|
43428
|
+
axTag = "c:dateAx";
|
|
43429
|
+
break;
|
|
43430
|
+
case "series":
|
|
43431
|
+
axTag = "c:serAx";
|
|
43432
|
+
break;
|
|
43433
|
+
default:
|
|
43434
|
+
axTag = "c:catAx";
|
|
43435
|
+
break;
|
|
43254
43436
|
}
|
|
43437
|
+
let titleXml2 = "";
|
|
43438
|
+
if (ax.title) titleXml2 = `<c:title><c:tx><c:rich><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${escapeXml(ax.title)}</a:t></a:r></a:p></c:rich></c:tx></c:title>`;
|
|
43439
|
+
let scalingXml = '<c:scaling><c:orientation val="minMax"/>';
|
|
43440
|
+
if (ax.min !== void 0) scalingXml += `<c:min val="${ax.min}"/>`;
|
|
43441
|
+
if (ax.max !== void 0) scalingXml += `<c:max val="${ax.max}"/>`;
|
|
43442
|
+
scalingXml += "</c:scaling>";
|
|
43443
|
+
const numFmt = ax.numFmt ? `<c:numFmt formatCode="${escapeXml(ax.numFmt)}" sourceLinked="0"/>` : "";
|
|
43444
|
+
plotArea += `<${axTag}><c:axId val="${axId}"/>${scalingXml}${titleXml2}${numFmt}<c:crossAx val="${crossId}"/></${axTag}>`;
|
|
43255
43445
|
}
|
|
43256
43446
|
}
|
|
43257
|
-
|
|
43258
|
-
|
|
43259
|
-
|
|
43260
|
-
|
|
43261
|
-
rowLabelCols,
|
|
43262
|
-
rows: totalRows,
|
|
43263
|
-
cols: totalCols
|
|
43264
|
-
};
|
|
43265
|
-
}
|
|
43266
|
-
function sameTuple(a, b) {
|
|
43267
|
-
if (a.length !== b.length) return false;
|
|
43268
|
-
for (let i2 = 0; i2 < a.length; i2++) {
|
|
43269
|
-
if (a[i2] !== b[i2]) {
|
|
43270
|
-
const an = a[i2] === void 0 || a[i2] === null || a[i2] === "";
|
|
43271
|
-
const bn = b[i2] === void 0 || b[i2] === null || b[i2] === "";
|
|
43272
|
-
if (!(an && bn)) return false;
|
|
43273
|
-
}
|
|
43447
|
+
plotArea += "</c:plotArea>";
|
|
43448
|
+
let titleXml = "";
|
|
43449
|
+
if (chart.title) {
|
|
43450
|
+
titleXml = `<c:title><c:tx><c:rich><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${escapeXml(chart.title)}</a:t></a:r></a:p></c:rich></c:tx></c:title>`;
|
|
43274
43451
|
}
|
|
43275
|
-
|
|
43452
|
+
let legendXml = "";
|
|
43453
|
+
if (chart.legendPosition && chart.legendPosition !== "none") {
|
|
43454
|
+
const posMap = { top: "t", bottom: "b", left: "l", right: "r" };
|
|
43455
|
+
legendXml = `<c:legend><c:legendPos val="${posMap[chart.legendPosition] ?? "b"}"/></c:legend>`;
|
|
43456
|
+
}
|
|
43457
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
43458
|
+
<c:chartSpace xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
|
|
43459
|
+
<c:chart>${titleXml}${plotArea}${legendXml}</c:chart>
|
|
43460
|
+
</c:chartSpace>`;
|
|
43276
43461
|
}
|
|
43277
|
-
function
|
|
43278
|
-
|
|
43279
|
-
if (typeof v === "boolean") return v ? "TRUE" : "FALSE";
|
|
43280
|
-
return String(v);
|
|
43462
|
+
function buildAnchorPosition(pos) {
|
|
43463
|
+
return `<xdr:col>${pos.col}</xdr:col><xdr:colOff>${pos.colOffset ?? 0}</xdr:colOff><xdr:row>${pos.row}</xdr:row><xdr:rowOff>${pos.rowOffset ?? 0}</xdr:rowOff>`;
|
|
43281
43464
|
}
|
|
43282
|
-
|
|
43283
|
-
|
|
43284
|
-
|
|
43285
|
-
|
|
43286
|
-
|
|
43287
|
-
|
|
43465
|
+
function buildChartAnchorXml(chart, rId) {
|
|
43466
|
+
return `<xdr:twoCellAnchor>
|
|
43467
|
+
<xdr:from>${buildAnchorPosition(chart.anchor.from)}</xdr:from>
|
|
43468
|
+
<xdr:to>${buildAnchorPosition(chart.anchor.to)}</xdr:to>
|
|
43469
|
+
<xdr:graphicFrame macro="">
|
|
43470
|
+
<xdr:nvGraphicFramePr><xdr:cNvPr id="0" name="Chart"/><xdr:cNvGraphicFramePr/></xdr:nvGraphicFramePr>
|
|
43471
|
+
<xdr:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/></xdr:xfrm>
|
|
43472
|
+
<a:graphic><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart"><c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" r:id="${rId}"/></a:graphicData></a:graphic>
|
|
43473
|
+
</xdr:graphicFrame>
|
|
43474
|
+
<xdr:clientData/>
|
|
43475
|
+
</xdr:twoCellAnchor>`;
|
|
43476
|
+
}
|
|
43477
|
+
function buildImageAnchorXml(image, rId) {
|
|
43478
|
+
return `<xdr:twoCellAnchor editAs="oneCell">
|
|
43479
|
+
<xdr:from>${buildAnchorPosition(image.tl)}</xdr:from>
|
|
43480
|
+
<xdr:to>${buildAnchorPosition(image.br)}</xdr:to>
|
|
43481
|
+
<xdr:pic>
|
|
43482
|
+
<xdr:nvPicPr><xdr:cNvPr id="0" name="Image"/><xdr:cNvPicPr/></xdr:nvPicPr>
|
|
43483
|
+
<xdr:blipFill><a:blip xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:embed="${rId}"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill>
|
|
43484
|
+
<xdr:spPr><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></xdr:spPr>
|
|
43485
|
+
</xdr:pic>
|
|
43486
|
+
<xdr:clientData/>
|
|
43487
|
+
</xdr:twoCellAnchor>`;
|
|
43488
|
+
}
|
|
43489
|
+
function buildShapeAnchorXml(drawing) {
|
|
43490
|
+
let fillXml = "";
|
|
43491
|
+
if (drawing.fillColor) fillXml = `<a:solidFill><a:srgbClr val="${hexToOoxmlRgb(drawing.fillColor)}"/></a:solidFill>`;
|
|
43492
|
+
let outlineXml = "";
|
|
43493
|
+
if (drawing.outlineColor) {
|
|
43494
|
+
const w = Math.round((drawing.outlineWidth ?? 1) * 12700);
|
|
43495
|
+
outlineXml = `<a:ln w="${w}"><a:solidFill><a:srgbClr val="${hexToOoxmlRgb(drawing.outlineColor)}"/></a:solidFill></a:ln>`;
|
|
43288
43496
|
}
|
|
43289
|
-
|
|
43290
|
-
|
|
43291
|
-
|
|
43292
|
-
|
|
43293
|
-
|
|
43294
|
-
|
|
43295
|
-
|
|
43296
|
-
|
|
43297
|
-
|
|
43298
|
-
|
|
43497
|
+
const geom = drawing.geometry ?? "rect";
|
|
43498
|
+
let textXml = "";
|
|
43499
|
+
if (drawing.text) textXml = `<xdr:txBody><a:bodyPr/><a:lstStyle/><a:p><a:r><a:t>${escapeXml(drawing.text)}</a:t></a:r></a:p></xdr:txBody>`;
|
|
43500
|
+
return `<xdr:twoCellAnchor>
|
|
43501
|
+
<xdr:from>${buildAnchorPosition(drawing.anchor.from)}</xdr:from>
|
|
43502
|
+
<xdr:to>${buildAnchorPosition(drawing.anchor.to)}</xdr:to>
|
|
43503
|
+
<xdr:sp><xdr:nvSpPr><xdr:cNvPr id="0" name="Shape"/><xdr:cNvSpPr/></xdr:nvSpPr>
|
|
43504
|
+
<xdr:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="0" cy="0"/></a:xfrm><a:prstGeom prst="${geom}"><a:avLst/></a:prstGeom>${fillXml}${outlineXml}</xdr:spPr>
|
|
43505
|
+
${textXml}</xdr:sp>
|
|
43506
|
+
<xdr:clientData/>
|
|
43507
|
+
</xdr:twoCellAnchor>`;
|
|
43508
|
+
}
|
|
43509
|
+
function buildTableXml(table, tableId) {
|
|
43510
|
+
const colsXml = table.columns.map((col) => {
|
|
43511
|
+
let inner = "";
|
|
43512
|
+
if (col.totalsFunction) inner += `<totalsRowFunction>${escapeXml(col.totalsFunction)}</totalsRowFunction>`;
|
|
43513
|
+
if (col.totalsFormula) inner += `<totalsRowFormula>${escapeXml(col.totalsFormula)}</totalsRowFormula>`;
|
|
43514
|
+
return `<tableColumn id="${col.id}" name="${escapeXml(col.name)}">${inner}</tableColumn>`;
|
|
43515
|
+
}).join("");
|
|
43516
|
+
const autoFilterXml = table.autoFilter ? `<autoFilter ref="${escapeXml(table.ref)}"/>` : "";
|
|
43517
|
+
const styleName = table.styleName ?? "TableStyleMedium2";
|
|
43518
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
43519
|
+
<table xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" id="${tableId}" name="${escapeXml(table.name)}" displayName="${escapeXml(table.displayName)}" ref="${escapeXml(table.ref)}" totalsRowCount="${table.totalsRow ? 1 : 0}">
|
|
43520
|
+
${autoFilterXml}
|
|
43521
|
+
<tableColumns count="${table.columns.length}">${colsXml}</tableColumns>
|
|
43522
|
+
<tableStyleInfo name="${escapeXml(styleName)}" showFirstColumn="0" showLastColumn="0" showRowStripes="1" showColumnStripes="0"/>
|
|
43523
|
+
</table>`;
|
|
43524
|
+
}
|
|
43525
|
+
function buildConditionalFormattingXml(cf, dxfMap) {
|
|
43526
|
+
const rules = cf.rules.map((rule) => {
|
|
43527
|
+
switch (rule.ruleType) {
|
|
43528
|
+
case "colorScale": {
|
|
43529
|
+
const count = rule.colors.length;
|
|
43530
|
+
const cfvos = count === 2 ? '<cfvo type="min"/><cfvo type="max"/>' : '<cfvo type="min"/><cfvo type="percentile" val="50"/><cfvo type="max"/>';
|
|
43531
|
+
const colors = rule.colors.map((c) => `<color rgb="${hexToArgb(c)}"/>`).join("");
|
|
43532
|
+
return `<cfRule type="colorScale" priority="${rule.priority}"><colorScale>${cfvos}${colors}</colorScale></cfRule>`;
|
|
43533
|
+
}
|
|
43534
|
+
case "dataBar": {
|
|
43535
|
+
const showVal = rule.showValue ? "1" : "0";
|
|
43536
|
+
return `<cfRule type="dataBar" priority="${rule.priority}"><dataBar minLength="${rule.minLength}" maxLength="${rule.maxLength}" showValue="${showVal}"><cfvo type="min"/><cfvo type="max"/><color rgb="${hexToArgb(rule.color)}"/></dataBar></cfRule>`;
|
|
43537
|
+
}
|
|
43538
|
+
case "iconSet": {
|
|
43539
|
+
const thresholds = rule.thresholds.map((t) => {
|
|
43540
|
+
if (t.type === "min" || t.type === "autoMin") return '<cfvo type="min"/>';
|
|
43541
|
+
if (t.type === "max" || t.type === "autoMax") return '<cfvo type="max"/>';
|
|
43542
|
+
return `<cfvo type="${t.type}" val="${t.value ?? 0}"/>`;
|
|
43543
|
+
}).join("");
|
|
43544
|
+
const showVal = rule.showValue ? "" : ' showValue="0"';
|
|
43545
|
+
const reverse = rule.reverse ? ' reverse="1"' : "";
|
|
43546
|
+
return `<cfRule type="iconSet" priority="${rule.priority}"><iconSet iconSet="${rule.iconSet}"${showVal}${reverse}>${thresholds}</iconSet></cfRule>`;
|
|
43547
|
+
}
|
|
43548
|
+
case "style": {
|
|
43549
|
+
let attrs = `type="${rule.type}" priority="${rule.priority}"`;
|
|
43550
|
+
if (rule.style) {
|
|
43551
|
+
const dxfId = dxfMap.get(JSON.stringify(rule.style));
|
|
43552
|
+
if (dxfId !== void 0) attrs += ` dxfId="${dxfId}"`;
|
|
43553
|
+
}
|
|
43554
|
+
if (rule.operator) attrs += ` operator="${rule.operator}"`;
|
|
43555
|
+
if (rule.text) attrs += ` text="${escapeXml(rule.text)}"`;
|
|
43556
|
+
if (rule.rank !== void 0) attrs += ` rank="${rule.rank}"`;
|
|
43557
|
+
if (rule.percent) attrs += ' percent="1"';
|
|
43558
|
+
if (rule.bottom) attrs += ' bottom="1"';
|
|
43559
|
+
if (rule.aboveAverage === false) attrs += ' aboveAverage="0"';
|
|
43560
|
+
if (rule.timePeriod) attrs += ` timePeriod="${rule.timePeriod}"`;
|
|
43561
|
+
let inner = "";
|
|
43562
|
+
if (rule.formulae) {
|
|
43563
|
+
inner = rule.formulae.map((f) => `<formula>${escapeXml(String(f))}</formula>`).join("");
|
|
43564
|
+
}
|
|
43565
|
+
return `<cfRule ${attrs}>${inner}</cfRule>`;
|
|
43566
|
+
}
|
|
43299
43567
|
}
|
|
43300
|
-
|
|
43301
|
-
}
|
|
43302
|
-
}
|
|
43303
|
-
function
|
|
43304
|
-
|
|
43305
|
-
|
|
43306
|
-
|
|
43307
|
-
|
|
43308
|
-
|
|
43309
|
-
|
|
43310
|
-
|
|
43311
|
-
for (let col = range.startCol; col <= range.endCol; col++) {
|
|
43312
|
-
const cell = sheet.getCell(rowColToRef(range.startRow, col));
|
|
43313
|
-
header.push(formatHeader(cell?.value));
|
|
43568
|
+
}).join("");
|
|
43569
|
+
return `<conditionalFormatting sqref="${cf.ref}">${rules}</conditionalFormatting>`;
|
|
43570
|
+
}
|
|
43571
|
+
function buildDxfXml(style) {
|
|
43572
|
+
let inner = "";
|
|
43573
|
+
if (style.fontBold || style.fontItalic || style.fontColor) {
|
|
43574
|
+
let fontParts = "";
|
|
43575
|
+
if (style.fontBold) fontParts += "<b/>";
|
|
43576
|
+
if (style.fontItalic) fontParts += "<i/>";
|
|
43577
|
+
if (style.fontColor) fontParts += `<color rgb="${hexToArgb(style.fontColor)}"/>`;
|
|
43578
|
+
inner += `<font>${fontParts}</font>`;
|
|
43314
43579
|
}
|
|
43315
|
-
|
|
43316
|
-
|
|
43317
|
-
const rec = [];
|
|
43318
|
-
for (let col = range.startCol; col <= range.endCol; col++) {
|
|
43319
|
-
const cell = sheet.getCell(rowColToRef(row, col));
|
|
43320
|
-
rec.push(coerceValue(cell?.value));
|
|
43321
|
-
}
|
|
43322
|
-
records.push(rec);
|
|
43580
|
+
if (style.backgroundColor) {
|
|
43581
|
+
inner += `<fill><patternFill><bgColor rgb="${hexToArgb(style.backgroundColor)}"/></patternFill></fill>`;
|
|
43323
43582
|
}
|
|
43324
|
-
return {
|
|
43583
|
+
return `<dxf>${inner}</dxf>`;
|
|
43325
43584
|
}
|
|
43326
|
-
function
|
|
43327
|
-
if (
|
|
43328
|
-
|
|
43585
|
+
function getImageExtension(dataUrl) {
|
|
43586
|
+
if (dataUrl.startsWith("data:image/png")) return "png";
|
|
43587
|
+
if (dataUrl.startsWith("data:image/jpeg") || dataUrl.startsWith("data:image/jpg")) return "jpeg";
|
|
43588
|
+
if (dataUrl.startsWith("data:image/gif")) return "gif";
|
|
43589
|
+
return "png";
|
|
43329
43590
|
}
|
|
43330
|
-
function
|
|
43331
|
-
|
|
43332
|
-
if (
|
|
43333
|
-
|
|
43334
|
-
|
|
43335
|
-
|
|
43591
|
+
function dataUrlToBytes(dataUrl) {
|
|
43592
|
+
const match = dataUrl.match(/^data:[^;]+;base64,(.+)$/);
|
|
43593
|
+
if (!match) return null;
|
|
43594
|
+
const binary = atob(match[1]);
|
|
43595
|
+
const bytes = new Uint8Array(binary.length);
|
|
43596
|
+
for (let i2 = 0; i2 < binary.length; i2++) bytes[i2] = binary.charCodeAt(i2);
|
|
43597
|
+
return bytes;
|
|
43336
43598
|
}
|
|
43337
|
-
|
|
43338
|
-
|
|
43339
|
-
|
|
43340
|
-
|
|
43341
|
-
|
|
43342
|
-
|
|
43343
|
-
|
|
43344
|
-
|
|
43345
|
-
const end = refToRowCol(endRef);
|
|
43346
|
-
if (!end) return void 0;
|
|
43347
|
-
return {
|
|
43348
|
-
startRow: start.row,
|
|
43349
|
-
startCol: start.col,
|
|
43350
|
-
endRow: end.row,
|
|
43351
|
-
endCol: end.col
|
|
43352
|
-
};
|
|
43599
|
+
|
|
43600
|
+
// ../xlsx/src/style_helpers.ts
|
|
43601
|
+
function border(style = "thin", color = "#000000") {
|
|
43602
|
+
return { width: 1, style, color };
|
|
43603
|
+
}
|
|
43604
|
+
function allBorders(style = "thin", color = "#000000") {
|
|
43605
|
+
const b = border(style, color);
|
|
43606
|
+
return { borderTop: b, borderRight: b, borderBottom: b, borderLeft: b };
|
|
43353
43607
|
}
|
|
43354
43608
|
|
|
43355
43609
|
// ../xlsx/src/workbook_model.ts
|