odf.js 1.13.2 → 2.1.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/README.md +19 -4
- package/dist/index.cjs +10 -0
- package/dist/index.d.cts +7 -3
- package/dist/index.d.ts +7 -3
- package/dist/index.js +7 -3
- package/dist/ns.cjs +2 -1
- package/dist/ns.d.cts +1 -0
- package/dist/ns.d.ts +1 -0
- package/dist/ns.js +2 -1
- package/dist/typed/draw/embedded.cjs +42 -0
- package/dist/typed/draw/embedded.d.cts +13 -0
- package/dist/typed/draw/embedded.d.ts +13 -0
- package/dist/typed/draw/embedded.js +41 -0
- package/dist/typed/draw/shapes.cjs +86 -30
- package/dist/typed/draw/shapes.d.cts +4 -1
- package/dist/typed/draw/shapes.d.ts +4 -1
- package/dist/typed/draw/shapes.js +86 -30
- package/dist/typed/formula/read.cjs +14 -0
- package/dist/typed/formula/read.d.cts +3 -2
- package/dist/typed/formula/read.d.ts +3 -2
- package/dist/typed/formula/read.js +14 -1
- package/dist/typed/odb/form.cjs +85 -0
- package/dist/typed/odb/form.d.cts +31 -0
- package/dist/typed/odb/form.d.ts +31 -0
- package/dist/typed/odb/form.js +84 -0
- package/dist/typed/odb/read.cjs +60 -23
- package/dist/typed/odb/read.d.cts +15 -4
- package/dist/typed/odb/read.d.ts +15 -4
- package/dist/typed/odb/read.js +60 -24
- package/dist/typed/odb/report.cjs +161 -0
- package/dist/typed/odb/report.d.cts +48 -0
- package/dist/typed/odb/report.d.ts +48 -0
- package/dist/typed/odb/report.js +160 -0
- package/dist/typed/odb/subdocument.cjs +16 -0
- package/dist/typed/odb/subdocument.d.cts +8 -0
- package/dist/typed/odb/subdocument.d.ts +8 -0
- package/dist/typed/odb/subdocument.js +15 -0
- package/dist/typed/ods/read.cjs +98 -4
- package/dist/typed/ods/read.js +100 -6
- package/dist/typed/shared/table.cjs +94 -7
- package/dist/typed/shared/table.d.cts +9 -2
- package/dist/typed/shared/table.d.ts +9 -2
- package/dist/typed/shared/table.js +94 -8
- package/package.json +1 -1
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_xml_entities = require("../../xml/entities.cjs");
|
|
3
|
+
const require_xml_query = require("../../xml/query.cjs");
|
|
4
|
+
const require_typed_odb_subdocument = require("./subdocument.cjs");
|
|
5
|
+
const require_typed_odb_read = require("./read.cjs");
|
|
6
|
+
//#region src/typed/odb/report.ts
|
|
7
|
+
const CONTENT_PART = "content.xml";
|
|
8
|
+
const GROUP_TAG = "rpt:group";
|
|
9
|
+
const FUNCTION_TAG = "rpt:function";
|
|
10
|
+
const REPORT_ELEMENT_TAG = "rpt:report-element";
|
|
11
|
+
const REPORT_COMPONENT_TAG = "rpt:report-component";
|
|
12
|
+
const RPT_TAG_PREFIX = "rpt:";
|
|
13
|
+
const FIELD_FORMULA_PREFIX = "field:[";
|
|
14
|
+
const FIELD_FORMULA_SUFFIX = "]";
|
|
15
|
+
function reportAttr(element, name) {
|
|
16
|
+
const raw = require_xml_query.attrValue(element, name);
|
|
17
|
+
return raw === void 0 ? void 0 : require_xml_entities.decodeXmlText(raw);
|
|
18
|
+
}
|
|
19
|
+
function parseOptionalBoolean(raw) {
|
|
20
|
+
return raw === void 0 ? void 0 : raw === "true";
|
|
21
|
+
}
|
|
22
|
+
function boundFieldName(formula) {
|
|
23
|
+
if (formula === void 0 || !formula.startsWith(FIELD_FORMULA_PREFIX) || !formula.endsWith(FIELD_FORMULA_SUFFIX)) return;
|
|
24
|
+
const inner = formula.slice(7, formula.length - 1);
|
|
25
|
+
return inner.length === 0 ? void 0 : inner;
|
|
26
|
+
}
|
|
27
|
+
function elementText(element) {
|
|
28
|
+
let text = "";
|
|
29
|
+
for (const child of element.children) if (child.type === "text") text += require_xml_entities.decodeXmlText(child.value);
|
|
30
|
+
else if (child.type === "element") text += elementText(child);
|
|
31
|
+
return text;
|
|
32
|
+
}
|
|
33
|
+
function reportElementChild(element) {
|
|
34
|
+
return require_xml_query.findChildElement(element.children, REPORT_ELEMENT_TAG);
|
|
35
|
+
}
|
|
36
|
+
function readReportElement(element, reportElement) {
|
|
37
|
+
const control = { tag: element.tag };
|
|
38
|
+
const component = require_xml_query.findChildElement(reportElement.children, REPORT_COMPONENT_TAG);
|
|
39
|
+
const name = component === void 0 ? void 0 : reportAttr(component, "draw:name");
|
|
40
|
+
if (name !== void 0) control.name = name;
|
|
41
|
+
const formula = reportAttr(element, "rpt:formula");
|
|
42
|
+
if (formula !== void 0) control.formula = formula;
|
|
43
|
+
let text = "";
|
|
44
|
+
for (const child of element.children) if (child.type === "text") text += require_xml_entities.decodeXmlText(child.value);
|
|
45
|
+
else if (child.type === "element" && !child.tag.startsWith(RPT_TAG_PREFIX)) text += elementText(child);
|
|
46
|
+
if (text.length > 0) control.text = text;
|
|
47
|
+
const dataField = boundFieldName(formula);
|
|
48
|
+
if (dataField !== void 0) control.dataField = dataField;
|
|
49
|
+
return control;
|
|
50
|
+
}
|
|
51
|
+
function collectControls(nodes, controls) {
|
|
52
|
+
for (const node of nodes) {
|
|
53
|
+
if (node.type !== "element") continue;
|
|
54
|
+
if (node.tag.startsWith(RPT_TAG_PREFIX)) {
|
|
55
|
+
const reportElement = reportElementChild(node);
|
|
56
|
+
if (reportElement !== void 0) {
|
|
57
|
+
controls.push(readReportElement(node, reportElement));
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
collectControls(node.children, controls);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function readBand(element, kind) {
|
|
65
|
+
const elements = [];
|
|
66
|
+
collectControls(element.children, elements);
|
|
67
|
+
const band = {
|
|
68
|
+
kind,
|
|
69
|
+
elements
|
|
70
|
+
};
|
|
71
|
+
const table = require_xml_query.findChildElement(element.children, "table:table");
|
|
72
|
+
const name = table === void 0 ? void 0 : reportAttr(table, "table:name");
|
|
73
|
+
if (name !== void 0) band.name = name;
|
|
74
|
+
return band;
|
|
75
|
+
}
|
|
76
|
+
function readBandIfPresent(container, tag, kind) {
|
|
77
|
+
const element = require_xml_query.findChildElement(container.children, tag);
|
|
78
|
+
return element === void 0 ? void 0 : readBand(element, kind);
|
|
79
|
+
}
|
|
80
|
+
function readFunctions(container) {
|
|
81
|
+
const functions = [];
|
|
82
|
+
for (const child of container.children) {
|
|
83
|
+
if (child.type !== "element" || child.tag !== FUNCTION_TAG) continue;
|
|
84
|
+
const name = reportAttr(child, "rpt:name");
|
|
85
|
+
const formula = reportAttr(child, "rpt:formula");
|
|
86
|
+
if (name === void 0 || formula === void 0) continue;
|
|
87
|
+
functions.push({
|
|
88
|
+
name,
|
|
89
|
+
formula
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return functions;
|
|
93
|
+
}
|
|
94
|
+
function readGroup(element) {
|
|
95
|
+
const group = {
|
|
96
|
+
functions: readFunctions(element),
|
|
97
|
+
groups: []
|
|
98
|
+
};
|
|
99
|
+
const groupExpression = reportAttr(element, "rpt:group-expression");
|
|
100
|
+
if (groupExpression !== void 0) group.groupExpression = groupExpression;
|
|
101
|
+
const sortExpression = reportAttr(element, "rpt:sort-expression");
|
|
102
|
+
if (sortExpression !== void 0) group.sortExpression = sortExpression;
|
|
103
|
+
const sortAscending = parseOptionalBoolean(require_xml_query.attrValue(element, "rpt:sort-ascending"));
|
|
104
|
+
if (sortAscending !== void 0) group.sortAscending = sortAscending;
|
|
105
|
+
const startNewColumn = parseOptionalBoolean(require_xml_query.attrValue(element, "rpt:start-new-column"));
|
|
106
|
+
if (startNewColumn !== void 0) group.startNewColumn = startNewColumn;
|
|
107
|
+
const resetPageNumber = parseOptionalBoolean(require_xml_query.attrValue(element, "rpt:reset-page-number"));
|
|
108
|
+
if (resetPageNumber !== void 0) group.resetPageNumber = resetPageNumber;
|
|
109
|
+
const keepTogether = reportAttr(element, "rpt:keep-together");
|
|
110
|
+
if (keepTogether !== void 0) group.keepTogether = keepTogether;
|
|
111
|
+
const header = readBandIfPresent(element, "rpt:group-header", "group-header");
|
|
112
|
+
if (header !== void 0) group.header = header;
|
|
113
|
+
const footer = readBandIfPresent(element, "rpt:group-footer", "group-footer");
|
|
114
|
+
if (footer !== void 0) group.footer = footer;
|
|
115
|
+
for (const child of element.children) if (child.type === "element" && child.tag === GROUP_TAG) group.groups.push(readGroup(child));
|
|
116
|
+
return group;
|
|
117
|
+
}
|
|
118
|
+
function findDetail(container) {
|
|
119
|
+
const detail = require_xml_query.findChildElement(container.children, "rpt:detail");
|
|
120
|
+
if (detail !== void 0) return readBand(detail, "detail");
|
|
121
|
+
const group = require_xml_query.findChildElement(container.children, GROUP_TAG);
|
|
122
|
+
return group === void 0 ? void 0 : findDetail(group);
|
|
123
|
+
}
|
|
124
|
+
function readOdbReport(pkg, reportName) {
|
|
125
|
+
const component = require_typed_odb_read.resolveOdbComponent(pkg, "report", reportName);
|
|
126
|
+
const contentPart = require_typed_odb_subdocument.subDocumentPackage(pkg, component.href).parts[CONTENT_PART];
|
|
127
|
+
if (contentPart?.kind !== "xml") throw new Error(`readOdbReport: report "${reportName}" sub-document ${component.href}/${CONTENT_PART} is not an XML part`);
|
|
128
|
+
const contentRoot = require_xml_query.rootElement(contentPart.nodes);
|
|
129
|
+
const body = contentRoot === void 0 ? void 0 : require_xml_query.findChildElement(contentRoot.children, "office:body");
|
|
130
|
+
const reportElement = body === void 0 ? void 0 : require_xml_query.findChildElement(body.children, "office:report");
|
|
131
|
+
if (reportElement === void 0) throw new Error(`readOdbReport: report "${reportName}" sub-document ${component.href}/${CONTENT_PART} has no office:body/office:report element`);
|
|
132
|
+
const groups = [];
|
|
133
|
+
for (const child of reportElement.children) if (child.type === "element" && child.tag === GROUP_TAG) groups.push(readGroup(child));
|
|
134
|
+
const report = {
|
|
135
|
+
name: component.name,
|
|
136
|
+
href: component.href,
|
|
137
|
+
groups,
|
|
138
|
+
functions: readFunctions(reportElement)
|
|
139
|
+
};
|
|
140
|
+
const command = reportAttr(reportElement, "rpt:command");
|
|
141
|
+
if (command !== void 0) report.command = command;
|
|
142
|
+
const commandType = reportAttr(reportElement, "rpt:command-type");
|
|
143
|
+
if (commandType !== void 0) report.commandType = commandType;
|
|
144
|
+
const caption = reportAttr(reportElement, "office:caption");
|
|
145
|
+
if (caption !== void 0) report.caption = caption;
|
|
146
|
+
const mimeType = reportAttr(reportElement, "office:mimetype");
|
|
147
|
+
if (mimeType !== void 0) report.mimeType = mimeType;
|
|
148
|
+
const reportHeader = readBandIfPresent(reportElement, "rpt:report-header", "report-header");
|
|
149
|
+
if (reportHeader !== void 0) report.reportHeader = reportHeader;
|
|
150
|
+
const pageHeader = readBandIfPresent(reportElement, "rpt:page-header", "page-header");
|
|
151
|
+
if (pageHeader !== void 0) report.pageHeader = pageHeader;
|
|
152
|
+
const detail = findDetail(reportElement);
|
|
153
|
+
if (detail !== void 0) report.detail = detail;
|
|
154
|
+
const pageFooter = readBandIfPresent(reportElement, "rpt:page-footer", "page-footer");
|
|
155
|
+
if (pageFooter !== void 0) report.pageFooter = pageFooter;
|
|
156
|
+
const reportFooter = readBandIfPresent(reportElement, "rpt:report-footer", "report-footer");
|
|
157
|
+
if (reportFooter !== void 0) report.reportFooter = reportFooter;
|
|
158
|
+
return report;
|
|
159
|
+
}
|
|
160
|
+
//#endregion
|
|
161
|
+
exports.readOdbReport = readOdbReport;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Package } from "../../model/package.cjs";
|
|
2
|
+
//#region src/typed/odb/report.d.ts
|
|
3
|
+
interface OdbReportElement {
|
|
4
|
+
tag: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
text?: string;
|
|
7
|
+
formula?: string;
|
|
8
|
+
dataField?: string;
|
|
9
|
+
}
|
|
10
|
+
interface OdbReportBand {
|
|
11
|
+
kind: 'report-header' | 'page-header' | 'group-header' | 'detail' | 'group-footer' | 'page-footer' | 'report-footer';
|
|
12
|
+
name?: string;
|
|
13
|
+
elements: OdbReportElement[];
|
|
14
|
+
}
|
|
15
|
+
interface OdbReportFunction {
|
|
16
|
+
name: string;
|
|
17
|
+
formula: string;
|
|
18
|
+
}
|
|
19
|
+
interface OdbReportGroup {
|
|
20
|
+
groupExpression?: string;
|
|
21
|
+
sortExpression?: string;
|
|
22
|
+
sortAscending?: boolean;
|
|
23
|
+
startNewColumn?: boolean;
|
|
24
|
+
resetPageNumber?: boolean;
|
|
25
|
+
keepTogether?: string;
|
|
26
|
+
header?: OdbReportBand;
|
|
27
|
+
footer?: OdbReportBand;
|
|
28
|
+
functions: OdbReportFunction[];
|
|
29
|
+
groups: OdbReportGroup[];
|
|
30
|
+
}
|
|
31
|
+
interface OdbReport {
|
|
32
|
+
name: string;
|
|
33
|
+
href: string;
|
|
34
|
+
command?: string;
|
|
35
|
+
commandType?: string;
|
|
36
|
+
caption?: string;
|
|
37
|
+
mimeType?: string;
|
|
38
|
+
reportHeader?: OdbReportBand;
|
|
39
|
+
pageHeader?: OdbReportBand;
|
|
40
|
+
groups: OdbReportGroup[];
|
|
41
|
+
detail?: OdbReportBand;
|
|
42
|
+
pageFooter?: OdbReportBand;
|
|
43
|
+
reportFooter?: OdbReportBand;
|
|
44
|
+
functions: OdbReportFunction[];
|
|
45
|
+
}
|
|
46
|
+
declare function readOdbReport(pkg: Package, reportName: string): OdbReport;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { OdbReport, OdbReportBand, OdbReportElement, OdbReportFunction, OdbReportGroup, readOdbReport };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Package } from "../../model/package.js";
|
|
2
|
+
//#region src/typed/odb/report.d.ts
|
|
3
|
+
interface OdbReportElement {
|
|
4
|
+
tag: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
text?: string;
|
|
7
|
+
formula?: string;
|
|
8
|
+
dataField?: string;
|
|
9
|
+
}
|
|
10
|
+
interface OdbReportBand {
|
|
11
|
+
kind: 'report-header' | 'page-header' | 'group-header' | 'detail' | 'group-footer' | 'page-footer' | 'report-footer';
|
|
12
|
+
name?: string;
|
|
13
|
+
elements: OdbReportElement[];
|
|
14
|
+
}
|
|
15
|
+
interface OdbReportFunction {
|
|
16
|
+
name: string;
|
|
17
|
+
formula: string;
|
|
18
|
+
}
|
|
19
|
+
interface OdbReportGroup {
|
|
20
|
+
groupExpression?: string;
|
|
21
|
+
sortExpression?: string;
|
|
22
|
+
sortAscending?: boolean;
|
|
23
|
+
startNewColumn?: boolean;
|
|
24
|
+
resetPageNumber?: boolean;
|
|
25
|
+
keepTogether?: string;
|
|
26
|
+
header?: OdbReportBand;
|
|
27
|
+
footer?: OdbReportBand;
|
|
28
|
+
functions: OdbReportFunction[];
|
|
29
|
+
groups: OdbReportGroup[];
|
|
30
|
+
}
|
|
31
|
+
interface OdbReport {
|
|
32
|
+
name: string;
|
|
33
|
+
href: string;
|
|
34
|
+
command?: string;
|
|
35
|
+
commandType?: string;
|
|
36
|
+
caption?: string;
|
|
37
|
+
mimeType?: string;
|
|
38
|
+
reportHeader?: OdbReportBand;
|
|
39
|
+
pageHeader?: OdbReportBand;
|
|
40
|
+
groups: OdbReportGroup[];
|
|
41
|
+
detail?: OdbReportBand;
|
|
42
|
+
pageFooter?: OdbReportBand;
|
|
43
|
+
reportFooter?: OdbReportBand;
|
|
44
|
+
functions: OdbReportFunction[];
|
|
45
|
+
}
|
|
46
|
+
declare function readOdbReport(pkg: Package, reportName: string): OdbReport;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { OdbReport, OdbReportBand, OdbReportElement, OdbReportFunction, OdbReportGroup, readOdbReport };
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { decodeXmlText } from "../../xml/entities.js";
|
|
2
|
+
import { attrValue, findChildElement, rootElement } from "../../xml/query.js";
|
|
3
|
+
import { subDocumentPackage } from "./subdocument.js";
|
|
4
|
+
import { resolveOdbComponent } from "./read.js";
|
|
5
|
+
//#region src/typed/odb/report.ts
|
|
6
|
+
const CONTENT_PART = "content.xml";
|
|
7
|
+
const GROUP_TAG = "rpt:group";
|
|
8
|
+
const FUNCTION_TAG = "rpt:function";
|
|
9
|
+
const REPORT_ELEMENT_TAG = "rpt:report-element";
|
|
10
|
+
const REPORT_COMPONENT_TAG = "rpt:report-component";
|
|
11
|
+
const RPT_TAG_PREFIX = "rpt:";
|
|
12
|
+
const FIELD_FORMULA_PREFIX = "field:[";
|
|
13
|
+
const FIELD_FORMULA_SUFFIX = "]";
|
|
14
|
+
function reportAttr(element, name) {
|
|
15
|
+
const raw = attrValue(element, name);
|
|
16
|
+
return raw === void 0 ? void 0 : decodeXmlText(raw);
|
|
17
|
+
}
|
|
18
|
+
function parseOptionalBoolean(raw) {
|
|
19
|
+
return raw === void 0 ? void 0 : raw === "true";
|
|
20
|
+
}
|
|
21
|
+
function boundFieldName(formula) {
|
|
22
|
+
if (formula === void 0 || !formula.startsWith(FIELD_FORMULA_PREFIX) || !formula.endsWith(FIELD_FORMULA_SUFFIX)) return;
|
|
23
|
+
const inner = formula.slice(7, formula.length - 1);
|
|
24
|
+
return inner.length === 0 ? void 0 : inner;
|
|
25
|
+
}
|
|
26
|
+
function elementText(element) {
|
|
27
|
+
let text = "";
|
|
28
|
+
for (const child of element.children) if (child.type === "text") text += decodeXmlText(child.value);
|
|
29
|
+
else if (child.type === "element") text += elementText(child);
|
|
30
|
+
return text;
|
|
31
|
+
}
|
|
32
|
+
function reportElementChild(element) {
|
|
33
|
+
return findChildElement(element.children, REPORT_ELEMENT_TAG);
|
|
34
|
+
}
|
|
35
|
+
function readReportElement(element, reportElement) {
|
|
36
|
+
const control = { tag: element.tag };
|
|
37
|
+
const component = findChildElement(reportElement.children, REPORT_COMPONENT_TAG);
|
|
38
|
+
const name = component === void 0 ? void 0 : reportAttr(component, "draw:name");
|
|
39
|
+
if (name !== void 0) control.name = name;
|
|
40
|
+
const formula = reportAttr(element, "rpt:formula");
|
|
41
|
+
if (formula !== void 0) control.formula = formula;
|
|
42
|
+
let text = "";
|
|
43
|
+
for (const child of element.children) if (child.type === "text") text += decodeXmlText(child.value);
|
|
44
|
+
else if (child.type === "element" && !child.tag.startsWith(RPT_TAG_PREFIX)) text += elementText(child);
|
|
45
|
+
if (text.length > 0) control.text = text;
|
|
46
|
+
const dataField = boundFieldName(formula);
|
|
47
|
+
if (dataField !== void 0) control.dataField = dataField;
|
|
48
|
+
return control;
|
|
49
|
+
}
|
|
50
|
+
function collectControls(nodes, controls) {
|
|
51
|
+
for (const node of nodes) {
|
|
52
|
+
if (node.type !== "element") continue;
|
|
53
|
+
if (node.tag.startsWith(RPT_TAG_PREFIX)) {
|
|
54
|
+
const reportElement = reportElementChild(node);
|
|
55
|
+
if (reportElement !== void 0) {
|
|
56
|
+
controls.push(readReportElement(node, reportElement));
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
collectControls(node.children, controls);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function readBand(element, kind) {
|
|
64
|
+
const elements = [];
|
|
65
|
+
collectControls(element.children, elements);
|
|
66
|
+
const band = {
|
|
67
|
+
kind,
|
|
68
|
+
elements
|
|
69
|
+
};
|
|
70
|
+
const table = findChildElement(element.children, "table:table");
|
|
71
|
+
const name = table === void 0 ? void 0 : reportAttr(table, "table:name");
|
|
72
|
+
if (name !== void 0) band.name = name;
|
|
73
|
+
return band;
|
|
74
|
+
}
|
|
75
|
+
function readBandIfPresent(container, tag, kind) {
|
|
76
|
+
const element = findChildElement(container.children, tag);
|
|
77
|
+
return element === void 0 ? void 0 : readBand(element, kind);
|
|
78
|
+
}
|
|
79
|
+
function readFunctions(container) {
|
|
80
|
+
const functions = [];
|
|
81
|
+
for (const child of container.children) {
|
|
82
|
+
if (child.type !== "element" || child.tag !== FUNCTION_TAG) continue;
|
|
83
|
+
const name = reportAttr(child, "rpt:name");
|
|
84
|
+
const formula = reportAttr(child, "rpt:formula");
|
|
85
|
+
if (name === void 0 || formula === void 0) continue;
|
|
86
|
+
functions.push({
|
|
87
|
+
name,
|
|
88
|
+
formula
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
return functions;
|
|
92
|
+
}
|
|
93
|
+
function readGroup(element) {
|
|
94
|
+
const group = {
|
|
95
|
+
functions: readFunctions(element),
|
|
96
|
+
groups: []
|
|
97
|
+
};
|
|
98
|
+
const groupExpression = reportAttr(element, "rpt:group-expression");
|
|
99
|
+
if (groupExpression !== void 0) group.groupExpression = groupExpression;
|
|
100
|
+
const sortExpression = reportAttr(element, "rpt:sort-expression");
|
|
101
|
+
if (sortExpression !== void 0) group.sortExpression = sortExpression;
|
|
102
|
+
const sortAscending = parseOptionalBoolean(attrValue(element, "rpt:sort-ascending"));
|
|
103
|
+
if (sortAscending !== void 0) group.sortAscending = sortAscending;
|
|
104
|
+
const startNewColumn = parseOptionalBoolean(attrValue(element, "rpt:start-new-column"));
|
|
105
|
+
if (startNewColumn !== void 0) group.startNewColumn = startNewColumn;
|
|
106
|
+
const resetPageNumber = parseOptionalBoolean(attrValue(element, "rpt:reset-page-number"));
|
|
107
|
+
if (resetPageNumber !== void 0) group.resetPageNumber = resetPageNumber;
|
|
108
|
+
const keepTogether = reportAttr(element, "rpt:keep-together");
|
|
109
|
+
if (keepTogether !== void 0) group.keepTogether = keepTogether;
|
|
110
|
+
const header = readBandIfPresent(element, "rpt:group-header", "group-header");
|
|
111
|
+
if (header !== void 0) group.header = header;
|
|
112
|
+
const footer = readBandIfPresent(element, "rpt:group-footer", "group-footer");
|
|
113
|
+
if (footer !== void 0) group.footer = footer;
|
|
114
|
+
for (const child of element.children) if (child.type === "element" && child.tag === GROUP_TAG) group.groups.push(readGroup(child));
|
|
115
|
+
return group;
|
|
116
|
+
}
|
|
117
|
+
function findDetail(container) {
|
|
118
|
+
const detail = findChildElement(container.children, "rpt:detail");
|
|
119
|
+
if (detail !== void 0) return readBand(detail, "detail");
|
|
120
|
+
const group = findChildElement(container.children, GROUP_TAG);
|
|
121
|
+
return group === void 0 ? void 0 : findDetail(group);
|
|
122
|
+
}
|
|
123
|
+
function readOdbReport(pkg, reportName) {
|
|
124
|
+
const component = resolveOdbComponent(pkg, "report", reportName);
|
|
125
|
+
const contentPart = subDocumentPackage(pkg, component.href).parts[CONTENT_PART];
|
|
126
|
+
if (contentPart?.kind !== "xml") throw new Error(`readOdbReport: report "${reportName}" sub-document ${component.href}/${CONTENT_PART} is not an XML part`);
|
|
127
|
+
const contentRoot = rootElement(contentPart.nodes);
|
|
128
|
+
const body = contentRoot === void 0 ? void 0 : findChildElement(contentRoot.children, "office:body");
|
|
129
|
+
const reportElement = body === void 0 ? void 0 : findChildElement(body.children, "office:report");
|
|
130
|
+
if (reportElement === void 0) throw new Error(`readOdbReport: report "${reportName}" sub-document ${component.href}/${CONTENT_PART} has no office:body/office:report element`);
|
|
131
|
+
const groups = [];
|
|
132
|
+
for (const child of reportElement.children) if (child.type === "element" && child.tag === GROUP_TAG) groups.push(readGroup(child));
|
|
133
|
+
const report = {
|
|
134
|
+
name: component.name,
|
|
135
|
+
href: component.href,
|
|
136
|
+
groups,
|
|
137
|
+
functions: readFunctions(reportElement)
|
|
138
|
+
};
|
|
139
|
+
const command = reportAttr(reportElement, "rpt:command");
|
|
140
|
+
if (command !== void 0) report.command = command;
|
|
141
|
+
const commandType = reportAttr(reportElement, "rpt:command-type");
|
|
142
|
+
if (commandType !== void 0) report.commandType = commandType;
|
|
143
|
+
const caption = reportAttr(reportElement, "office:caption");
|
|
144
|
+
if (caption !== void 0) report.caption = caption;
|
|
145
|
+
const mimeType = reportAttr(reportElement, "office:mimetype");
|
|
146
|
+
if (mimeType !== void 0) report.mimeType = mimeType;
|
|
147
|
+
const reportHeader = readBandIfPresent(reportElement, "rpt:report-header", "report-header");
|
|
148
|
+
if (reportHeader !== void 0) report.reportHeader = reportHeader;
|
|
149
|
+
const pageHeader = readBandIfPresent(reportElement, "rpt:page-header", "page-header");
|
|
150
|
+
if (pageHeader !== void 0) report.pageHeader = pageHeader;
|
|
151
|
+
const detail = findDetail(reportElement);
|
|
152
|
+
if (detail !== void 0) report.detail = detail;
|
|
153
|
+
const pageFooter = readBandIfPresent(reportElement, "rpt:page-footer", "page-footer");
|
|
154
|
+
if (pageFooter !== void 0) report.pageFooter = pageFooter;
|
|
155
|
+
const reportFooter = readBandIfPresent(reportElement, "rpt:report-footer", "report-footer");
|
|
156
|
+
if (reportFooter !== void 0) report.reportFooter = reportFooter;
|
|
157
|
+
return report;
|
|
158
|
+
}
|
|
159
|
+
//#endregion
|
|
160
|
+
export { readOdbReport };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
//#region src/typed/odb/subdocument.ts
|
|
3
|
+
const CONTENT_PART = "content.xml";
|
|
4
|
+
function subDocumentPackage(pkg, prefix, options = {}) {
|
|
5
|
+
const normalised = prefix.endsWith("/") ? prefix : `${prefix}/`;
|
|
6
|
+
const parts = {};
|
|
7
|
+
for (const [path, part] of Object.entries(pkg.parts)) {
|
|
8
|
+
if (!path.startsWith(normalised)) continue;
|
|
9
|
+
const relative = path.slice(normalised.length);
|
|
10
|
+
if (relative.length > 0) parts[relative] = part;
|
|
11
|
+
}
|
|
12
|
+
if (options.allowMissingContent !== true && parts[CONTENT_PART] === void 0) throw new Error(`subDocumentPackage: package has no ${normalised}${CONTENT_PART} part`);
|
|
13
|
+
return { parts };
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
exports.subDocumentPackage = subDocumentPackage;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Package } from "../../model/package.cjs";
|
|
2
|
+
//#region src/typed/odb/subdocument.d.ts
|
|
3
|
+
interface SubDocumentPackageOptions {
|
|
4
|
+
allowMissingContent?: boolean;
|
|
5
|
+
}
|
|
6
|
+
declare function subDocumentPackage(pkg: Package, prefix: string, options?: SubDocumentPackageOptions): Package;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { SubDocumentPackageOptions, subDocumentPackage };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Package } from "../../model/package.js";
|
|
2
|
+
//#region src/typed/odb/subdocument.d.ts
|
|
3
|
+
interface SubDocumentPackageOptions {
|
|
4
|
+
allowMissingContent?: boolean;
|
|
5
|
+
}
|
|
6
|
+
declare function subDocumentPackage(pkg: Package, prefix: string, options?: SubDocumentPackageOptions): Package;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { SubDocumentPackageOptions, subDocumentPackage };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/typed/odb/subdocument.ts
|
|
2
|
+
const CONTENT_PART = "content.xml";
|
|
3
|
+
function subDocumentPackage(pkg, prefix, options = {}) {
|
|
4
|
+
const normalised = prefix.endsWith("/") ? prefix : `${prefix}/`;
|
|
5
|
+
const parts = {};
|
|
6
|
+
for (const [path, part] of Object.entries(pkg.parts)) {
|
|
7
|
+
if (!path.startsWith(normalised)) continue;
|
|
8
|
+
const relative = path.slice(normalised.length);
|
|
9
|
+
if (relative.length > 0) parts[relative] = part;
|
|
10
|
+
}
|
|
11
|
+
if (options.allowMissingContent !== true && parts[CONTENT_PART] === void 0) throw new Error(`subDocumentPackage: package has no ${normalised}${CONTENT_PART} part`);
|
|
12
|
+
return { parts };
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { subDocumentPackage };
|
package/dist/typed/ods/read.cjs
CHANGED
|
@@ -6,7 +6,14 @@ const require_typed_shared_geometry = require("../shared/geometry.cjs");
|
|
|
6
6
|
const require_typed_shared_cascade = require("../shared/cascade.cjs");
|
|
7
7
|
const require_typed_shared_metadata = require("../shared/metadata.cjs");
|
|
8
8
|
const require_typed_shared_paragraph = require("../shared/paragraph.cjs");
|
|
9
|
+
const require_typed_shared_table = require("../shared/table.cjs");
|
|
10
|
+
const require_typed_shared_transform = require("../shared/transform.cjs");
|
|
9
11
|
const require_typed_shared_masterpage = require("../shared/masterpage.cjs");
|
|
12
|
+
const require_typed_draw_shapes = require("../draw/shapes.cjs");
|
|
13
|
+
const require_typed_draw_embedded = require("../draw/embedded.cjs");
|
|
14
|
+
const require_typed_odp_read = require("../odp/read.cjs");
|
|
15
|
+
const require_typed_odt_read = require("../odt/read.cjs");
|
|
16
|
+
const require_typed_odg_read = require("../odg/read.cjs");
|
|
10
17
|
let document_schema_js = require("document-schema.js");
|
|
11
18
|
//#region src/typed/ods/read.ts
|
|
12
19
|
const CONTENT_PART = "content.xml";
|
|
@@ -155,10 +162,84 @@ function parseNonNegativeInteger(value) {
|
|
|
155
162
|
const parsed = Number.parseInt(value, 10);
|
|
156
163
|
return Number.isInteger(parsed) && parsed >= 0 ? parsed : void 0;
|
|
157
164
|
}
|
|
165
|
+
function readEmbeddedObjectDocument(reference) {
|
|
166
|
+
switch (reference.objectKind) {
|
|
167
|
+
case "wordprocessing": {
|
|
168
|
+
const { metadata, sections } = require_typed_odt_read.readOdt(reference.package);
|
|
169
|
+
return {
|
|
170
|
+
kind: "wordprocessing",
|
|
171
|
+
formatVersion: document_schema_js.CONTENT_FORMAT_VERSION,
|
|
172
|
+
metadata,
|
|
173
|
+
sections
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
case "presentation": {
|
|
177
|
+
const { metadata, slides } = require_typed_odp_read.readOdp(reference.package);
|
|
178
|
+
return {
|
|
179
|
+
kind: "presentation",
|
|
180
|
+
formatVersion: document_schema_js.CONTENT_FORMAT_VERSION,
|
|
181
|
+
metadata,
|
|
182
|
+
slides
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
case "drawing": {
|
|
186
|
+
const { metadata, pages } = require_typed_odg_read.readOdg(reference.package);
|
|
187
|
+
return {
|
|
188
|
+
kind: "drawing",
|
|
189
|
+
formatVersion: document_schema_js.CONTENT_FORMAT_VERSION,
|
|
190
|
+
metadata,
|
|
191
|
+
pages
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
case "spreadsheet": {
|
|
195
|
+
const { metadata, sheets } = readOds(reference.package);
|
|
196
|
+
return {
|
|
197
|
+
kind: "spreadsheet",
|
|
198
|
+
formatVersion: document_schema_js.CONTENT_FORMAT_VERSION,
|
|
199
|
+
metadata,
|
|
200
|
+
sheets
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function collectAnchoredFrame(frameElement, groupFunctions, pkg, anchorRow, anchorColumn, images, embeddedObjects) {
|
|
206
|
+
const shape = require_typed_draw_shapes.readDrawFrame(frameElement, groupFunctions, pkg);
|
|
207
|
+
if (shape === void 0) return;
|
|
208
|
+
const reference = require_typed_draw_embedded.readDrawObjectReference(frameElement, pkg);
|
|
209
|
+
if (reference !== void 0) {
|
|
210
|
+
embeddedObjects.push({
|
|
211
|
+
objectKind: reference.objectKind,
|
|
212
|
+
document: readEmbeddedObjectDocument(reference),
|
|
213
|
+
frame: shape.frame
|
|
214
|
+
});
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
for (const block of shape.blocks) if (block.kind === "image") images.push({
|
|
218
|
+
...block,
|
|
219
|
+
anchorRow,
|
|
220
|
+
anchorColumn,
|
|
221
|
+
offsetXPt: shape.frame.xPt,
|
|
222
|
+
offsetYPt: shape.frame.yPt
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
function collectAnchoredFrames(children, groupFunctions, pkg, anchorRow, anchorColumn, images, embeddedObjects) {
|
|
226
|
+
for (const child of children) {
|
|
227
|
+
if (child.type !== "element") continue;
|
|
228
|
+
if (child.tag === "draw:frame") collectAnchoredFrame(child, groupFunctions, pkg, anchorRow, anchorColumn, images, embeddedObjects);
|
|
229
|
+
else if (child.tag === "draw:g") {
|
|
230
|
+
const ownValue = require_xml_query.attrValue(child, "draw:transform");
|
|
231
|
+
const ownFunctions = ownValue === void 0 ? [] : require_typed_shared_transform.parseOdfTransform(ownValue);
|
|
232
|
+
const nested = ownFunctions.length === 0 ? groupFunctions : [...ownFunctions, ...groupFunctions];
|
|
233
|
+
collectAnchoredFrames(child.children, nested, pkg, anchorRow, anchorColumn, images, embeddedObjects);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
158
237
|
function readTable(tableElement, pkg) {
|
|
159
238
|
const columns = [];
|
|
160
239
|
const rows = [];
|
|
161
240
|
const cells = [];
|
|
241
|
+
const images = [];
|
|
242
|
+
const embeddedObjects = [];
|
|
162
243
|
const manualBreakRows = [];
|
|
163
244
|
const manualBreakColumns = [];
|
|
164
245
|
let repeatColumns;
|
|
@@ -183,6 +264,7 @@ function readTable(tableElement, pkg) {
|
|
|
183
264
|
const columnIndex = cursor.columnIndex;
|
|
184
265
|
const rowIndex = cursor.rowIndex;
|
|
185
266
|
cursor.nextCell(readRepeatCount(child, "table:number-columns-repeated"));
|
|
267
|
+
collectAnchoredFrames(child.children, [], pkg, rowIndex, columnIndex, images, embeddedObjects);
|
|
186
268
|
const formula = require_xml_query.attrValue(child, "table:formula");
|
|
187
269
|
const { runs, displayText } = readCellText(child, pkg);
|
|
188
270
|
if (!(require_xml_query.attrValue(child, "office:value-type") !== void 0) && formula === void 0 && displayText.length === 0) continue;
|
|
@@ -199,6 +281,13 @@ function readTable(tableElement, pkg) {
|
|
|
199
281
|
if (runs.length > 0) cell.runs = runs;
|
|
200
282
|
if (colSpan !== void 0) cell.colSpan = colSpan;
|
|
201
283
|
if (rowSpan !== void 0) cell.rowSpan = rowSpan;
|
|
284
|
+
const cellStyleName = require_xml_query.attrValue(child, "table:style-name");
|
|
285
|
+
const { elements: cellStyleChain } = require_typed_shared_cascade.resolveStyleElementChain(cellStyleName, "table-cell", pkg);
|
|
286
|
+
const decoration = require_typed_shared_table.readCellStyleDecoration(cellStyleChain);
|
|
287
|
+
if (decoration.background !== void 0) cell.background = decoration.background;
|
|
288
|
+
if (decoration.borders !== void 0) cell.borders = decoration.borders;
|
|
289
|
+
if (decoration.alignment !== void 0) cell.alignment = decoration.alignment;
|
|
290
|
+
if (decoration.verticalAlignment !== void 0) cell.verticalAlignment = decoration.verticalAlignment;
|
|
202
291
|
cells.push(cell);
|
|
203
292
|
}
|
|
204
293
|
}
|
|
@@ -217,7 +306,8 @@ function readTable(tableElement, pkg) {
|
|
|
217
306
|
}
|
|
218
307
|
for (const child of tableElement.children) {
|
|
219
308
|
if (child.type !== "element") continue;
|
|
220
|
-
if (child.tag === "table:
|
|
309
|
+
if (child.tag === "table:shapes") collectAnchoredFrames(child.children, [], pkg, 0, 0, images, embeddedObjects);
|
|
310
|
+
else if (child.tag === "table:table-column") processColumn(child);
|
|
221
311
|
else if (child.tag === "table:table-header-columns") {
|
|
222
312
|
const startIndex = columnCursor;
|
|
223
313
|
for (const headerChild of child.children) if (headerChild.type === "element" && headerChild.tag === "table:table-column") processColumn(headerChild);
|
|
@@ -239,6 +329,8 @@ function readTable(tableElement, pkg) {
|
|
|
239
329
|
columns,
|
|
240
330
|
rows,
|
|
241
331
|
cells,
|
|
332
|
+
images,
|
|
333
|
+
embeddedObjects,
|
|
242
334
|
repeatColumns,
|
|
243
335
|
repeatRows,
|
|
244
336
|
manualBreakRows,
|
|
@@ -288,15 +380,17 @@ function readPrintSettings(tableElement, pkg, repeatColumns, repeatRows, manualB
|
|
|
288
380
|
function readSheet(tableElement, pkg) {
|
|
289
381
|
const name = require_xml_query.attrValue(tableElement, "table:name");
|
|
290
382
|
if (name === void 0) return;
|
|
291
|
-
const { columns, rows, cells, repeatColumns, repeatRows, manualBreakRows, manualBreakColumns } = readTable(tableElement, pkg);
|
|
292
|
-
|
|
383
|
+
const { columns, rows, cells, images, embeddedObjects, repeatColumns, repeatRows, manualBreakRows, manualBreakColumns } = readTable(tableElement, pkg);
|
|
384
|
+
const sheet = {
|
|
293
385
|
name,
|
|
294
386
|
cells,
|
|
295
387
|
columns,
|
|
296
388
|
rows,
|
|
297
|
-
images
|
|
389
|
+
images,
|
|
298
390
|
printSettings: readPrintSettings(tableElement, pkg, repeatColumns, repeatRows, manualBreakRows, manualBreakColumns)
|
|
299
391
|
};
|
|
392
|
+
if (embeddedObjects.length > 0) sheet.embeddedObjects = embeddedObjects;
|
|
393
|
+
return sheet;
|
|
300
394
|
}
|
|
301
395
|
function readOds(pkg) {
|
|
302
396
|
const contentPart = pkg.parts[CONTENT_PART];
|