reamkit 1.15.3 → 1.16.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/esm/core/converter/facade.d.ts +5 -0
- package/dist/esm/core/converter/ream.d.ts +6 -0
- package/dist/esm/core/converter/ream.js +34 -8
- package/dist/esm/core/document-model/index.d.ts +1 -1
- package/dist/esm/core/document-model/types.d.ts +187 -1
- package/dist/esm/core/drawingml/chart-geometry.d.ts +28 -0
- package/dist/esm/core/drawingml/chart-geometry.js +371 -88
- package/dist/esm/core/drawingml/chart-parser.js +262 -11
- package/dist/esm/core/drawingml/colors.d.ts +6 -6
- package/dist/esm/core/drawingml/colors.js +58 -18
- package/dist/esm/core/drawingml/preset-geometry.js +7 -6
- package/dist/esm/core/drawingml/sparkline-geometry.js +6 -4
- package/dist/esm/core/drawingml/theme-parser.d.ts +41 -0
- package/dist/esm/core/drawingml/theme-parser.js +74 -1
- package/dist/esm/core/font/ttf-subset.js +26 -1
- package/dist/esm/core/images.js +172 -43
- package/dist/esm/core/indexed-colors.d.ts +11 -0
- package/dist/esm/core/indexed-colors.js +81 -0
- package/dist/esm/core/ir/sheet.d.ts +67 -3
- package/dist/esm/{excel → core}/number-format.d.ts +37 -0
- package/dist/esm/core/number-format.js +800 -0
- package/dist/esm/core/opc/alternate-content.d.ts +13 -0
- package/dist/esm/core/opc/alternate-content.js +72 -0
- package/dist/esm/core/opc/core-properties.js +1 -0
- package/dist/esm/core/opc/package.d.ts +14 -1
- package/dist/esm/core/opc/package.js +43 -4
- package/dist/esm/core/opc/relationships.js +1 -0
- package/dist/esm/core/opc/xml-entities.d.ts +12 -0
- package/dist/esm/core/opc/xml-entities.js +91 -0
- package/dist/esm/core/spreadsheet-model/index.d.ts +1 -1
- package/dist/esm/core/spreadsheet-model/types.d.ts +137 -0
- package/dist/esm/core/vector.d.ts +13 -0
- package/dist/esm/excel/activex-parser.d.ts +9 -0
- package/dist/esm/excel/activex-parser.js +16 -1
- package/dist/esm/excel/column-bands.d.ts +26 -1
- package/dist/esm/excel/column-bands.js +156 -20
- package/dist/esm/excel/comments-parser.js +5 -3
- package/dist/esm/excel/conditional-format.d.ts +25 -2
- package/dist/esm/excel/conditional-format.js +63 -19
- package/dist/esm/excel/escaped-text.d.ts +9 -0
- package/dist/esm/excel/escaped-text.js +20 -0
- package/dist/esm/excel/form-control-parser.js +1 -0
- package/dist/esm/excel/formula/dates.js +1 -1
- package/dist/esm/excel/header-footer.d.ts +9 -1
- package/dist/esm/excel/header-footer.js +162 -14
- package/dist/esm/excel/index.d.ts +1 -1
- package/dist/esm/excel/index.js +2 -2
- package/dist/esm/excel/pivot-table-parser.js +1 -0
- package/dist/esm/excel/print-model.d.ts +75 -0
- package/dist/esm/excel/print-model.js +902 -77
- package/dist/esm/excel/printer-settings.d.ts +16 -0
- package/dist/esm/excel/printer-settings.js +36 -0
- package/dist/esm/excel/rich-value.d.ts +13 -0
- package/dist/esm/excel/rich-value.js +120 -0
- package/dist/esm/excel/shared-strings-parser.js +11 -7
- package/dist/esm/excel/sheet-drawing.d.ts +11 -0
- package/dist/esm/excel/sheet-drawing.js +26 -3
- package/dist/esm/excel/sheet-shape-parser.d.ts +53 -1
- package/dist/esm/excel/sheet-shape-parser.js +461 -32
- package/dist/esm/excel/sheet-to-flow.d.ts +23 -2
- package/dist/esm/excel/sheet-to-flow.js +551 -36
- package/dist/esm/excel/slicer-parser.js +1 -0
- package/dist/esm/excel/styles-parser.d.ts +30 -2
- package/dist/esm/excel/styles-parser.js +177 -40
- package/dist/esm/excel/table-parser.js +1 -0
- package/dist/esm/excel/vml-drawing.d.ts +68 -0
- package/dist/esm/excel/vml-drawing.js +158 -0
- package/dist/esm/excel/workbook-parser.d.ts +5 -0
- package/dist/esm/excel/workbook-parser.js +5 -1
- package/dist/esm/excel/worksheet-parser.d.ts +2 -1
- package/dist/esm/excel/worksheet-parser.js +149 -28
- package/dist/esm/excel/xlsx-reader.js +271 -33
- package/dist/esm/excel/xlsx-to-pdf.js +12 -1
- package/dist/esm/html/html-writer.js +11 -2
- package/dist/esm/layout/page-doc.d.ts +26 -0
- package/dist/esm/layout/styled-layout.d.ts +2 -0
- package/dist/esm/layout/styled-layout.js +493 -64
- package/dist/esm/pdf/cid-font.js +20 -9
- package/dist/esm/pdf/objects.d.ts +13 -0
- package/dist/esm/pdf/objects.js +18 -1
- package/dist/esm/pdf/styled-page-emitter.js +164 -32
- package/dist/esm/pdf/text-page-renderer.js +1 -0
- package/dist/esm/pdf/vector-graphics.d.ts +3 -1
- package/dist/esm/pdf/vector-graphics.js +19 -2
- package/dist/esm/pptx/pptx-reader.js +1 -0
- package/dist/esm/pptx/slide-parser.js +12 -1
- package/dist/esm/svg/svg-writer.js +23 -4
- package/dist/esm/word/document-parser.js +1 -0
- package/dist/esm/word/drawing-parser.d.ts +34 -1
- package/dist/esm/word/drawing-parser.js +52 -2
- package/dist/esm/word/numbering-parser.js +1 -0
- package/dist/esm/word/settings-parser.js +1 -0
- package/dist/esm/word/styles-parser.js +1 -0
- package/package.json +7 -3
- package/dist/esm/excel/number-format.js +0 -476
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** The paper size and orientation a DEVMODE records, when it records them. */
|
|
2
|
+
export interface PrinterPageSetup {
|
|
3
|
+
/** `dmPaperSize` — the same §18.3.1.63 enumeration `<pageSetup paperSize>` uses. */
|
|
4
|
+
readonly paperSize?: number;
|
|
5
|
+
readonly orientation?: 'portrait' | 'landscape';
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Read the paper size and orientation out of a `printerSettings#.bin` part.
|
|
9
|
+
*
|
|
10
|
+
* Returns an empty record for anything that does not look like a DEVMODE — the
|
|
11
|
+
* part is opaque binary from an arbitrary printer driver, so nothing here may
|
|
12
|
+
* assume more than the fixed header it is required to start with.
|
|
13
|
+
*
|
|
14
|
+
* @param data The raw part bytes.
|
|
15
|
+
*/
|
|
16
|
+
export declare function parsePrinterSettings(data: Uint8Array): PrinterPageSetup;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region src/excel/printer-settings.ts
|
|
2
|
+
var DEVICE_NAME_BYTES = 64;
|
|
3
|
+
var OFFSET_SIZE = DEVICE_NAME_BYTES + 4;
|
|
4
|
+
var OFFSET_ORIENTATION = DEVICE_NAME_BYTES + 12;
|
|
5
|
+
var OFFSET_PAPER_SIZE = DEVICE_NAME_BYTES + 14;
|
|
6
|
+
var DM_ORIENTATION = 1;
|
|
7
|
+
var DM_PAPERSIZE = 2;
|
|
8
|
+
/**
|
|
9
|
+
* Read the paper size and orientation out of a `printerSettings#.bin` part.
|
|
10
|
+
*
|
|
11
|
+
* Returns an empty record for anything that does not look like a DEVMODE — the
|
|
12
|
+
* part is opaque binary from an arbitrary printer driver, so nothing here may
|
|
13
|
+
* assume more than the fixed header it is required to start with.
|
|
14
|
+
*
|
|
15
|
+
* @param data The raw part bytes.
|
|
16
|
+
*/
|
|
17
|
+
function parsePrinterSettings(data) {
|
|
18
|
+
if (data.byteLength < OFFSET_PAPER_SIZE + 2) return {};
|
|
19
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
20
|
+
const dmSize = view.getUint16(OFFSET_SIZE, true);
|
|
21
|
+
if (dmSize < OFFSET_PAPER_SIZE + 2 || dmSize > data.byteLength) return {};
|
|
22
|
+
const fields = view.getUint32(DEVICE_NAME_BYTES + 8, true);
|
|
23
|
+
const out = {};
|
|
24
|
+
if (fields & DM_PAPERSIZE) {
|
|
25
|
+
const paper = view.getInt16(OFFSET_PAPER_SIZE, true);
|
|
26
|
+
if (paper > 0) out.paperSize = paper;
|
|
27
|
+
}
|
|
28
|
+
if (fields & DM_ORIENTATION) {
|
|
29
|
+
const orientation = view.getInt16(OFFSET_ORIENTATION, true);
|
|
30
|
+
if (orientation === 1) out.orientation = "portrait";
|
|
31
|
+
else if (orientation === 2) out.orientation = "landscape";
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { parsePrinterSettings };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the `vm` → display-text map for a workbook's rich values.
|
|
3
|
+
*
|
|
4
|
+
* All three parts are optional and any of them being absent, malformed or of a
|
|
5
|
+
* structure this understands nothing about simply yields no entry for that
|
|
6
|
+
* index — the caller then keeps whatever the cell's `<v>` said.
|
|
7
|
+
*
|
|
8
|
+
* @param metadata `xl/metadata.xml`, or undefined when the package has none.
|
|
9
|
+
* @param structures `xl/richData/rdrichvaluestructure.xml`.
|
|
10
|
+
* @param values `xl/richData/rdrichvalue.xml`.
|
|
11
|
+
* @returns A map from a cell's 1-based `vm` index to the text to render.
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseRichValueText(metadata: Uint8Array | undefined, structures: Uint8Array | undefined, values: Uint8Array | undefined): ReadonlyMap<number, string>;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { XMLParser } from "fast-xml-parser";
|
|
2
|
+
//#region src/excel/rich-value.ts
|
|
3
|
+
var decoder = new TextDecoder("utf-8");
|
|
4
|
+
var parser = new XMLParser({
|
|
5
|
+
ignoreAttributes: false,
|
|
6
|
+
attributeNamePrefix: "@_",
|
|
7
|
+
textNodeName: "#text",
|
|
8
|
+
parseAttributeValue: false,
|
|
9
|
+
parseTagValue: false,
|
|
10
|
+
trimValues: true,
|
|
11
|
+
removeNSPrefix: true
|
|
12
|
+
});
|
|
13
|
+
/** The metadata type whose future blocks point into the rich-value table. */
|
|
14
|
+
var RICH_VALUE_TYPE = "XLRICHVALUE";
|
|
15
|
+
/**
|
|
16
|
+
* The `_error` structure's `errorType` codes, and only the ones a real document
|
|
17
|
+
* has corroborated. `Spill.xlsx` writes 8 alongside `subType="1"` and
|
|
18
|
+
* `rwOffset="3"`, and the cell three rows down is the one holding the text that
|
|
19
|
+
* blocks the spill — which names the error beyond doubt. The rest of the
|
|
20
|
+
* enumeration is not written down anywhere this code can check, and a wrong
|
|
21
|
+
* error is worse than the stand-in the file already provides, so an unmapped
|
|
22
|
+
* code resolves to nothing.
|
|
23
|
+
*/
|
|
24
|
+
var ERROR_TYPES = new Map([[8, "#SPILL!"]]);
|
|
25
|
+
function nodes(parent, name) {
|
|
26
|
+
if (typeof parent !== "object" || parent === null) return [];
|
|
27
|
+
const child = parent[name];
|
|
28
|
+
if (child === void 0) return [];
|
|
29
|
+
return (Array.isArray(child) ? child : [child]).filter((n) => typeof n === "object" && n !== null);
|
|
30
|
+
}
|
|
31
|
+
function attr(node, name) {
|
|
32
|
+
const value = node?.[`@_${name}`];
|
|
33
|
+
return typeof value === "string" ? value : void 0;
|
|
34
|
+
}
|
|
35
|
+
function intAttr(node, name) {
|
|
36
|
+
const raw = attr(node, name);
|
|
37
|
+
if (raw === void 0) return void 0;
|
|
38
|
+
const n = Number(raw);
|
|
39
|
+
return Number.isInteger(n) ? n : void 0;
|
|
40
|
+
}
|
|
41
|
+
function textValues(node) {
|
|
42
|
+
const out = [];
|
|
43
|
+
const v = node["v"];
|
|
44
|
+
for (const item of Array.isArray(v) ? v : [v]) if (typeof item === "string") out.push(item);
|
|
45
|
+
else if (typeof item === "number") out.push(String(item));
|
|
46
|
+
else if (typeof item === "object" && item !== null) {
|
|
47
|
+
const text = item["#text"];
|
|
48
|
+
out.push(typeof text === "string" ? text : "");
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build the `vm` → display-text map for a workbook's rich values.
|
|
54
|
+
*
|
|
55
|
+
* All three parts are optional and any of them being absent, malformed or of a
|
|
56
|
+
* structure this understands nothing about simply yields no entry for that
|
|
57
|
+
* index — the caller then keeps whatever the cell's `<v>` said.
|
|
58
|
+
*
|
|
59
|
+
* @param metadata `xl/metadata.xml`, or undefined when the package has none.
|
|
60
|
+
* @param structures `xl/richData/rdrichvaluestructure.xml`.
|
|
61
|
+
* @param values `xl/richData/rdrichvalue.xml`.
|
|
62
|
+
* @returns A map from a cell's 1-based `vm` index to the text to render.
|
|
63
|
+
*/
|
|
64
|
+
function parseRichValueText(metadata, structures, values) {
|
|
65
|
+
const out = /* @__PURE__ */ new Map();
|
|
66
|
+
if (!metadata || !structures || !values) return out;
|
|
67
|
+
const structureList = parseStructures(structures);
|
|
68
|
+
if (structureList.length === 0) return out;
|
|
69
|
+
const richValues = parseValues(values);
|
|
70
|
+
if (richValues.length === 0) return out;
|
|
71
|
+
const root = nodes(parser.parse(decoder.decode(metadata)), "metadata")[0];
|
|
72
|
+
if (!root) return out;
|
|
73
|
+
const typeNames = nodes(root, "metadataTypes").flatMap((t) => nodes(t, "metadataType")).map((t) => attr(t, "name") ?? "");
|
|
74
|
+
const futureByType = /* @__PURE__ */ new Map();
|
|
75
|
+
for (const fm of nodes(root, "futureMetadata")) {
|
|
76
|
+
const name = attr(fm, "name");
|
|
77
|
+
if (name === void 0) continue;
|
|
78
|
+
futureByType.set(name, nodes(fm, "bk").map((bk) => {
|
|
79
|
+
const rvb = nodes(bk, "extLst").flatMap((ext) => nodes(ext, "ext")).flatMap((ext) => nodes(ext, "rvb"))[0];
|
|
80
|
+
return intAttr(rvb, "i");
|
|
81
|
+
}));
|
|
82
|
+
}
|
|
83
|
+
const valueMetadata = nodes(root, "valueMetadata").flatMap((vm) => nodes(vm, "bk"));
|
|
84
|
+
for (const [index, bk] of valueMetadata.entries()) {
|
|
85
|
+
const rc = nodes(bk, "rc")[0];
|
|
86
|
+
const typeIndex = intAttr(rc, "t");
|
|
87
|
+
const blockIndex = intAttr(rc, "v");
|
|
88
|
+
if (typeIndex === void 0 || blockIndex === void 0) continue;
|
|
89
|
+
if (typeNames[typeIndex - 1] !== RICH_VALUE_TYPE) continue;
|
|
90
|
+
const richIndex = futureByType.get(RICH_VALUE_TYPE)?.[blockIndex];
|
|
91
|
+
if (richIndex === void 0) continue;
|
|
92
|
+
const text = displayText(richValues[richIndex], structureList);
|
|
93
|
+
if (text !== void 0) out.set(index + 1, text);
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
/** What one rich value renders as, or undefined when nothing here understands it. */
|
|
98
|
+
function displayText(value, structures) {
|
|
99
|
+
if (!value) return void 0;
|
|
100
|
+
const structure = structures[value.structureIndex];
|
|
101
|
+
if (structure?.type !== "_error") return void 0;
|
|
102
|
+
const at = structure.keys.indexOf("errorType");
|
|
103
|
+
if (at < 0) return void 0;
|
|
104
|
+
const code = Number(value.values[at]);
|
|
105
|
+
return Number.isInteger(code) ? ERROR_TYPES.get(code) : void 0;
|
|
106
|
+
}
|
|
107
|
+
function parseStructures(part) {
|
|
108
|
+
return nodes(parser.parse(decoder.decode(part)), "rvStructures").flatMap((r) => nodes(r, "s")).map((s) => ({
|
|
109
|
+
type: attr(s, "t") ?? "",
|
|
110
|
+
keys: nodes(s, "k").map((k) => attr(k, "n") ?? "")
|
|
111
|
+
}));
|
|
112
|
+
}
|
|
113
|
+
function parseValues(part) {
|
|
114
|
+
return nodes(parser.parse(decoder.decode(part)), "rvData").flatMap((r) => nodes(r, "rv")).map((rv) => ({
|
|
115
|
+
structureIndex: intAttr(rv, "s") ?? 0,
|
|
116
|
+
values: textValues(rv)
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
//#endregion
|
|
120
|
+
export { parseRichValueText };
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { resolveInternalEntities } from "../core/opc/xml-entities.js";
|
|
2
|
+
import { decodeXstring } from "./escaped-text.js";
|
|
1
3
|
import { XMLParser } from "fast-xml-parser";
|
|
2
4
|
//#region src/excel/shared-strings-parser.ts
|
|
3
5
|
var decoder = new TextDecoder("utf-8");
|
|
4
6
|
var parser = new XMLParser({
|
|
7
|
+
htmlEntities: true,
|
|
5
8
|
ignoreAttributes: false,
|
|
6
9
|
attributeNamePrefix: "@_",
|
|
7
10
|
textNodeName: "#text",
|
|
@@ -20,13 +23,13 @@ function capLen(s) {
|
|
|
20
23
|
* cell limit (32 767 chars).
|
|
21
24
|
*/
|
|
22
25
|
function parseSharedStrings(data) {
|
|
23
|
-
const xml = decoder.decode(data);
|
|
26
|
+
const xml = resolveInternalEntities(decoder.decode(data));
|
|
24
27
|
const sst = parser.parse(xml)["sst"];
|
|
25
28
|
if (!sst || typeof sst !== "object") return {
|
|
26
29
|
texts: [],
|
|
27
30
|
runs: []
|
|
28
31
|
};
|
|
29
|
-
const siRaw = sst["si"];
|
|
32
|
+
const siRaw = sst["si"] ?? sst["sstItem"];
|
|
30
33
|
const items = Array.isArray(siRaw) ? siRaw : siRaw !== void 0 ? [siRaw] : [];
|
|
31
34
|
const texts = [];
|
|
32
35
|
const runs = [];
|
|
@@ -84,9 +87,10 @@ function richRun(text, rPr) {
|
|
|
84
87
|
const p = rPr && typeof rPr === "object" ? rPr : void 0;
|
|
85
88
|
if (!p) return { text };
|
|
86
89
|
const out = { text };
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (has(p, "u")) out.underline = true;
|
|
90
|
+
out.bold = has(p, "b");
|
|
91
|
+
out.italic = has(p, "i");
|
|
92
|
+
if (has(p, "u") && attrStr(p["u"], "val") !== "none") out.underline = true;
|
|
93
|
+
out.strike = has(p, "strike");
|
|
90
94
|
const color = colorRgb(p["color"]);
|
|
91
95
|
if (color) out.colorHex = color;
|
|
92
96
|
const sz = attrNum(p["sz"], "val");
|
|
@@ -119,11 +123,11 @@ function colorRgb(node) {
|
|
|
119
123
|
return /^[0-9A-Fa-f]{6}$/.test(hex) ? hex.toUpperCase() : void 0;
|
|
120
124
|
}
|
|
121
125
|
function textOf(node) {
|
|
122
|
-
if (typeof node === "string") return node;
|
|
126
|
+
if (typeof node === "string") return decodeXstring(node);
|
|
123
127
|
if (typeof node === "number") return String(node);
|
|
124
128
|
if (!node || typeof node !== "object") return "";
|
|
125
129
|
const inner = node["#text"];
|
|
126
|
-
if (typeof inner === "string") return inner;
|
|
130
|
+
if (typeof inner === "string") return decodeXstring(inner);
|
|
127
131
|
if (typeof inner === "number") return String(inner);
|
|
128
132
|
return "";
|
|
129
133
|
}
|
|
@@ -9,6 +9,14 @@ export interface SheetChartRef {
|
|
|
9
9
|
readonly chartPartPath: string;
|
|
10
10
|
readonly widthPt: number;
|
|
11
11
|
readonly heightPt: number;
|
|
12
|
+
/**
|
|
13
|
+
* Where the anchor puts the frame, in points from the grid's top-left. A
|
|
14
|
+
* chart is anchored over the sheet like any other drawing; placed in the flow
|
|
15
|
+
* instead it lands at the left margin, below everything, and on whatever page
|
|
16
|
+
* that turns out to be.
|
|
17
|
+
*/
|
|
18
|
+
readonly xPt: number;
|
|
19
|
+
readonly yPt: number;
|
|
12
20
|
/** Anchor top row (0-based) — used only to order charts on the sheet. */
|
|
13
21
|
readonly anchorRow: number;
|
|
14
22
|
}
|
|
@@ -21,6 +29,9 @@ export interface SheetPicture {
|
|
|
21
29
|
readonly imagePartPath: string;
|
|
22
30
|
readonly widthPt: number;
|
|
23
31
|
readonly heightPt: number;
|
|
32
|
+
/** Where the anchor puts it, in points from the grid's top-left. */
|
|
33
|
+
readonly xPt: number;
|
|
34
|
+
readonly yPt: number;
|
|
24
35
|
/** Anchor top row (0-based) — used only to order pictures on the sheet. */
|
|
25
36
|
readonly anchorRow: number;
|
|
26
37
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { emuToPt } from "../core/ir/units.js";
|
|
2
|
-
import "./print-model.js";
|
|
2
|
+
import { columnTwips } from "./print-model.js";
|
|
3
3
|
import { XMLParser } from "fast-xml-parser";
|
|
4
4
|
//#region src/excel/sheet-drawing.ts
|
|
5
5
|
var CHART_URI = "http://schemas.openxmlformats.org/drawingml/2006/chart";
|
|
6
6
|
var parser = new XMLParser({
|
|
7
|
+
htmlEntities: true,
|
|
7
8
|
ignoreAttributes: false,
|
|
8
9
|
attributeNamePrefix: "@_",
|
|
9
10
|
removeNSPrefix: true,
|
|
@@ -47,6 +48,7 @@ function parseSheetDrawing(drawingXml, drawingPartPath, pkg, worksheet) {
|
|
|
47
48
|
const chartRelId = chartRelIdOf(a);
|
|
48
49
|
const picRelId = chartRelId ? void 0 : picRelIdOf(a);
|
|
49
50
|
if (!chartRelId && !picRelId) continue;
|
|
51
|
+
if (isHiddenDrawing(a, chartRelId ? "graphicFrame" : "pic")) continue;
|
|
50
52
|
const from = cellMarker(a["from"]);
|
|
51
53
|
let widthPt = 0;
|
|
52
54
|
let heightPt = 0;
|
|
@@ -64,12 +66,18 @@ function parseSheetDrawing(drawingXml, drawingPartPath, pkg, worksheet) {
|
|
|
64
66
|
}
|
|
65
67
|
if (widthPt <= 0 || heightPt <= 0) continue;
|
|
66
68
|
const anchorRow = from?.row ?? 0;
|
|
69
|
+
const posRaw = kind === "absoluteAnchor" ? a["pos"] : void 0;
|
|
70
|
+
const posNode = posRaw && typeof posRaw === "object" ? posRaw : void 0;
|
|
71
|
+
const xPt = posNode ? emuToPt(num(posNode["@_x"]) ?? 0) : from ? spanPt(0, 0, from.col, from.colOffPt, colWidthPt) : 0;
|
|
72
|
+
const yPt = posNode ? emuToPt(num(posNode["@_y"]) ?? 0) : from ? spanPt(0, 0, from.row, from.rowOffPt, rowHeightPt) : 0;
|
|
67
73
|
if (chartRelId) {
|
|
68
74
|
const path = partPathOf(chartRelId);
|
|
69
75
|
if (path) charts.push({
|
|
70
76
|
chartPartPath: path,
|
|
71
77
|
widthPt,
|
|
72
78
|
heightPt,
|
|
79
|
+
xPt,
|
|
80
|
+
yPt,
|
|
73
81
|
anchorRow
|
|
74
82
|
});
|
|
75
83
|
} else if (picRelId) {
|
|
@@ -78,6 +86,8 @@ function parseSheetDrawing(drawingXml, drawingPartPath, pkg, worksheet) {
|
|
|
78
86
|
imagePartPath: path,
|
|
79
87
|
widthPt,
|
|
80
88
|
heightPt,
|
|
89
|
+
xPt,
|
|
90
|
+
yPt,
|
|
81
91
|
anchorRow
|
|
82
92
|
});
|
|
83
93
|
}
|
|
@@ -89,6 +99,16 @@ function parseSheetDrawing(drawingXml, drawingPartPath, pkg, worksheet) {
|
|
|
89
99
|
pictures
|
|
90
100
|
};
|
|
91
101
|
}
|
|
102
|
+
function isHiddenDrawing(anchor, kind) {
|
|
103
|
+
const node = anchor[kind];
|
|
104
|
+
if (!node || typeof node !== "object") return false;
|
|
105
|
+
const nv = node[kind === "pic" ? "nvPicPr" : "nvGraphicFramePr"];
|
|
106
|
+
if (!nv || typeof nv !== "object") return false;
|
|
107
|
+
const cNvPr = nv["cNvPr"];
|
|
108
|
+
if (!cNvPr || typeof cNvPr !== "object") return false;
|
|
109
|
+
const hidden = cNvPr["@_hidden"];
|
|
110
|
+
return hidden === "1" || hidden === "true" || hidden === true;
|
|
111
|
+
}
|
|
92
112
|
function picRelIdOf(anchor) {
|
|
93
113
|
const pic = anchor["pic"];
|
|
94
114
|
if (!pic || typeof pic !== "object") return void 0;
|
|
@@ -138,8 +158,11 @@ function spanPt(from, fromOffPt, to, toOffPt, trackPt) {
|
|
|
138
158
|
* track geometry.
|
|
139
159
|
*/
|
|
140
160
|
function makeColWidthPt(ws) {
|
|
161
|
+
const widthPt = (chars) => columnTwips(chars, 105) / TWIPS_PER_PT;
|
|
141
162
|
return (col) => {
|
|
142
|
-
for (const c of ws.columns) if (col >= c.min - 1 && col <= c.max - 1) return c.widthChars
|
|
163
|
+
for (const c of ws.columns) if (col >= c.min - 1 && col <= c.max - 1) return widthPt(c.widthChars);
|
|
164
|
+
if (ws.defaultColWidthChars !== void 0) return widthPt(ws.defaultColWidthChars);
|
|
165
|
+
if (ws.baseColWidthChars !== void 0) return (columnTwips(ws.baseColWidthChars, 105) + 75) / TWIPS_PER_PT;
|
|
143
166
|
return 960 / TWIPS_PER_PT;
|
|
144
167
|
};
|
|
145
168
|
}
|
|
@@ -150,7 +173,7 @@ function makeColWidthPt(ws) {
|
|
|
150
173
|
function makeRowHeightPt(ws) {
|
|
151
174
|
return (row) => {
|
|
152
175
|
for (const r of ws.rowHeights) if (r.row === row) return r.heightPt;
|
|
153
|
-
return 300 / TWIPS_PER_PT;
|
|
176
|
+
return ws.defaultRowHeightPt ?? 300 / TWIPS_PER_PT;
|
|
154
177
|
};
|
|
155
178
|
}
|
|
156
179
|
function num(v) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ShapeBlock } from '../core/document-model/index.js';
|
|
2
2
|
import { ColorResolver } from '../core/drawingml/colors.js';
|
|
3
3
|
import { ParsedWorksheet } from '../core/spreadsheet-model/index.js';
|
|
4
|
+
import { PoNode } from '../core/po-helpers.js';
|
|
4
5
|
/**
|
|
5
6
|
* Parse a drawing's `xdr:sp` shape anchors (§20.5.2.30) into anchor-ordered
|
|
6
7
|
* {@link ShapeBlock}s (E-SHEET W2), reusing the shared DrawingML geometry / fill /
|
|
@@ -12,5 +13,56 @@ import { ParsedWorksheet } from '../core/spreadsheet-model/index.js';
|
|
|
12
13
|
* preserveOrder tree the shape readers expect).
|
|
13
14
|
* @param worksheet The host worksheet, for the column/row track geometry.
|
|
14
15
|
* @param colors The theme colour resolver threaded into fill/line parsing.
|
|
16
|
+
* @param themeLineWidths The theme's `a:lnStyleLst` widths in points, which an
|
|
17
|
+
* `<a:lnRef idx>` indexes for a gallery-styled outline.
|
|
18
|
+
* @param themeFillStyles The theme's `a:fillStyleLst` nodes, which an
|
|
19
|
+
* `<a:fillRef idx>` indexes for a gallery-styled fill.
|
|
20
|
+
* @param themeEffectStyles The theme's `a:effectStyleLst` nodes, which an
|
|
21
|
+
* `<a:effectRef idx>` indexes for a gallery-styled shadow.
|
|
15
22
|
*/
|
|
16
|
-
export declare function parseSheetShapes(drawingXml: Uint8Array, worksheet: ParsedWorksheet, colors: ColorResolver): Array<ShapeBlock>;
|
|
23
|
+
export declare function parseSheetShapes(drawingXml: Uint8Array, worksheet: ParsedWorksheet, colors: ColorResolver, themeLineWidths?: ReadonlyArray<number>, themeFillStyles?: ReadonlyArray<PoNode>, themeEffectStyles?: ReadonlyArray<PoNode>): Array<ShapeBlock>;
|
|
24
|
+
/**
|
|
25
|
+
* The boxes the diagram frames of a drawing occupy, in document order.
|
|
26
|
+
*
|
|
27
|
+
* §20.5.2.16 `xdr:graphicFrame` is how a sheet hosts a diagram: the frame is
|
|
28
|
+
* anchored like any other drawing and the diagram itself lives in its own
|
|
29
|
+
* parts. The frame gives the corner its fallback shapes are laid out from —
|
|
30
|
+
* see {@link parseDiagramShapes}.
|
|
31
|
+
*
|
|
32
|
+
* @param drawingXml The drawing part bytes.
|
|
33
|
+
* @param worksheet The host worksheet, for the column/row track geometry.
|
|
34
|
+
* @returns One box per diagram frame, in the order the drawing writes them.
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseDiagramFrames(drawingXml: Uint8Array, worksheet: ParsedWorksheet): Array<AnchorBox>;
|
|
37
|
+
/**
|
|
38
|
+
* Parse the fallback drawing of a SmartArt diagram (§ MS-ODRAWXML 2.1
|
|
39
|
+
* `dsp:drawing`) into the shapes it lays out.
|
|
40
|
+
*
|
|
41
|
+
* A diagram is FOUR parts of description — data, layout, quick style, colours —
|
|
42
|
+
* that a renderer is meant to lay out itself, and nobody outside Office does.
|
|
43
|
+
* The producer therefore also writes what it drew: a plain DrawingML picture of
|
|
44
|
+
* the result, under `dsp:`, reachable from the drawing part by a
|
|
45
|
+
* `diagramDrawing` relationship. Reading it is the difference between a diagram
|
|
46
|
+
* and a blank space — tdf83671_SmartArt_import.xlsx draws three nested circles
|
|
47
|
+
* where we drew nothing between its "start" and its "end".
|
|
48
|
+
*
|
|
49
|
+
* The shapes' `a:xfrm` offsets are relative to the frame the diagram sits in,
|
|
50
|
+
* so the frame's own corner is all that has to be added.
|
|
51
|
+
*
|
|
52
|
+
* @param diagramXml The `dsp:drawing` part bytes.
|
|
53
|
+
* @param frame The box the graphic frame occupies on the page.
|
|
54
|
+
* @param colors The theme colour resolver.
|
|
55
|
+
* @param themeLineWidths `a:lnStyleLst` widths, indexed by `<a:lnRef idx>`.
|
|
56
|
+
* @param themeFillStyles `a:fillStyleLst` nodes, indexed by `<a:fillRef idx>`.
|
|
57
|
+
* @param themeEffectStyles `a:effectStyleLst` nodes, indexed by `<a:effectRef idx>`.
|
|
58
|
+
* @returns The shapes, in the order the diagram stacks them.
|
|
59
|
+
*/
|
|
60
|
+
export declare function parseDiagramShapes(diagramXml: Uint8Array, frame: AnchorBox, colors: ColorResolver, themeLineWidths?: ReadonlyArray<number>, themeFillStyles?: ReadonlyArray<PoNode>, themeEffectStyles?: ReadonlyArray<PoNode>): Array<ShapeBlock>;
|
|
61
|
+
export interface AnchorBox {
|
|
62
|
+
readonly widthPt: number;
|
|
63
|
+
readonly heightPt: number;
|
|
64
|
+
readonly anchorRow: number;
|
|
65
|
+
/** Distance from the sheet's top-left corner to the shape's, in points. */
|
|
66
|
+
readonly xPt: number;
|
|
67
|
+
readonly yPt: number;
|
|
68
|
+
}
|