xlvane 1.2.3 → 1.3.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 +35 -4
- package/dist/cli.js +60 -27
- package/dist/index.d.ts +28 -10
- package/dist/index.js +3 -3
- package/dist/{node-files-Bxzv7THG.js → node-files-SVg17pky.js} +2 -2
- package/dist/node.d.ts +1 -1
- package/dist/node.js +3 -3
- package/dist/{options-Cw7OraxE.js → options-Cxt-LJE4.js} +7859 -6878
- package/dist/{rows-DnlfBgme.js → rows-DltZ-hiW.js} +1017 -378
- package/dist/{stream-write-DWD8Pflj.js → stream-write-D573ewpr.js} +32 -2
- package/dist/{stream-write-y52KUDW8.d.ts → stream-write-XnCyLdOy.d.ts} +320 -5
- package/docs/cli-json/inspect.schema.json +76 -0
- package/docs/errors.md +27 -10
- package/docs/exceljs-compat.md +32 -12
- package/docs/inspect-json.md +4 -0
- package/docs/migrate-from-exceljs.md +131 -0
- package/docs/xlsx-cves.md +88 -0
- package/llms-full.txt +414 -28
- package/package.json +1 -1
- package/skills/xlvane/SKILL.md +14 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $t as
|
|
1
|
+
import { $t as metricsOf, A as checkSource$1, B as createWorksheetParser, Bt as resolveLimits, Cn as CORE_PROPERTIES_PART, Ct as relationshipsPartName, D as HEAD_BYTES, Dt as checkUniqueName, E as CORRUPT_HINT, Et as checkDefinedName, F as readCentralDirectory, Ht as printNames, I as unsupported, Jt as DRAWING_CONTENT_TYPE, K as SheetRels, L as validateLocalHeaders, Lt as DEFAULT_READ_LIMITS, M as limitExceeded, N as locateCentralDirectory, Nn as clip, O as NotLoaded, Ot as nameScopeKey, Pt as normalizeStyle, Q as createSharedStrings, R as WarningCollector, Rt as checkKeyText, Sn as APP_PROPERTIES_PART, St as openPackage, T as Bytes, Tn as corePropertiesXml, Tt as normalizeTable, Ut as printXml, Wt as sheetProtectionXml, X as cellXml, Xt as MediaParts, Y as buildStyles, Yt as IMAGE_CONTENT_TYPES, Z as contentTypesXml, Zt as drawingParts, _t as FormulaGroups, a as DATE_FORMAT, b as readNotes, bn as partKey, cn as chartPartXml, ct as sheetHead, d as convertCellInput, dt as sheetTail, en as resolveAnchor, f as createWorkbook, g as detectHeader, gn as formatCellRef, gt as workbookXml, hn as columnLetters, ht as workbookRelsXml, i as readOptions, in as classifyRelationship, it as noteParts, j as corrupt, k as TAIL_BYTES, kn as createXmlByteStreamParser, ln as chartSheetNames, lt as sheetRelsPartName, mn as MAX_ROWS, n as oneOfOption, nt as hyperlinksXml, o as DATE_TIME_FORMAT, on as CHART_CONTENT_TYPE, ot as rootRelsXml, p as sortedNotes, pn as MAX_COLUMNS, pt as tableParts, rt as nameTitles, sn as chartPartName, st as rowStart, tn as resolveImage, u as checkBookViews, un as resolveChartSheets, ut as sheetRulesXml, v as isoDate, w as workbookPartsToLoad, wn as appPropertiesXml, wt as TABLE_CONTENT_TYPE, xn as zipNameToPartName, y as analyzeWorkbook, yt as crc32, z as sheetNotFound, zn as XlvError, zt as checkOutputPositions } from "./options-Cxt-LJE4.js";
|
|
2
2
|
import { Deflate, Inflate } from "fflate";
|
|
3
3
|
// src/zip/stream.ts
|
|
4
4
|
/**
|
|
@@ -952,6 +952,7 @@ function writeWorkbookStream(options) {
|
|
|
952
952
|
"tables",
|
|
953
953
|
"images",
|
|
954
954
|
"background",
|
|
955
|
+
"charts",
|
|
955
956
|
"rows"
|
|
956
957
|
], `sheets[${String(i)}]`);
|
|
957
958
|
const state = s.get("state");
|
|
@@ -1058,6 +1059,7 @@ function writeWorkbookStream(options) {
|
|
|
1058
1059
|
sheet.addImage(image, anchor, options);
|
|
1059
1060
|
}
|
|
1060
1061
|
if (s.has("background")) sheet.background(s.get("background"));
|
|
1062
|
+
for (const v of listOf("charts", "{ type: \"column\", anchor: \"E2:L18\", series: [{ values: \"Data!B2:B13\" }] }")) sheet.addChart(v);
|
|
1061
1063
|
return {
|
|
1062
1064
|
spec: raw,
|
|
1063
1065
|
sheet,
|
|
@@ -1074,6 +1076,12 @@ function writeWorkbookStream(options) {
|
|
|
1074
1076
|
const prepared = dynamic ? [] : specs.map(prepare);
|
|
1075
1077
|
if (!dynamic && !prepared.some((p) => p.sheet.state === "visible")) throw noVisibleSheet();
|
|
1076
1078
|
if (!dynamic) addNames();
|
|
1079
|
+
if (!dynamic) {
|
|
1080
|
+
const lookup = chartSheetNames(prepared.map((q) => q.sheet.name));
|
|
1081
|
+
for (const p of prepared) for (const c of p.sheet.chartList) resolveChartSheets(c.chart, lookup, p.sheet.name);
|
|
1082
|
+
}
|
|
1083
|
+
/** Charts in workbook order (CH-01); their parts are written once every sheet name is known. */
|
|
1084
|
+
const chartQueue = [];
|
|
1077
1085
|
const strings = shared ? createSharedStrings() : null;
|
|
1078
1086
|
const styleCache = /* @__PURE__ */ new WeakMap();
|
|
1079
1087
|
const dateStyle = /* @__PURE__ */ new Map();
|
|
@@ -1228,7 +1236,19 @@ function writeWorkbookStream(options) {
|
|
|
1228
1236
|
conditionalFormats: p.sheet.conditionalList,
|
|
1229
1237
|
dataValidations: p.sheet.validationList
|
|
1230
1238
|
}, n);
|
|
1231
|
-
const
|
|
1239
|
+
const frames = p.sheet.chartList.map((c) => {
|
|
1240
|
+
chartQueue.push({
|
|
1241
|
+
chart: c.chart,
|
|
1242
|
+
sheet: p.sheet.name
|
|
1243
|
+
});
|
|
1244
|
+
return {
|
|
1245
|
+
...resolveAnchor(c.anchor, metricsOf(p.sheet.columnMap, p.sheet.rowMap)),
|
|
1246
|
+
name: c.chart.name,
|
|
1247
|
+
description: c.chart.description,
|
|
1248
|
+
target: `../charts/chart${String(chartQueue.length)}.xml`
|
|
1249
|
+
};
|
|
1250
|
+
});
|
|
1251
|
+
const drawing = drawingParts(p.sheet.imageList.map((i) => resolveImage(i, metricsOf(p.sheet.columnMap, p.sheet.rowMap))), p.sheet.backgroundImage, media, ++drawingCount, p.rels, frames);
|
|
1232
1252
|
if (drawing.part === null) drawingCount--;
|
|
1233
1253
|
p.drawing = drawing.part;
|
|
1234
1254
|
const sheetTables = tableParts(p.sheet.tableList, tableCount + 1, p.rels);
|
|
@@ -1345,10 +1365,16 @@ function writeWorkbookStream(options) {
|
|
|
1345
1365
|
if (prepared.length === 0) throw new XlvError("XLV_E_INVALID_INPUT", "The workbook has no sheets.", { hint: "Add at least one sheet before closing the stream." });
|
|
1346
1366
|
if (!selected) throw noVisibleSheet();
|
|
1347
1367
|
if (dynamic) addNames();
|
|
1368
|
+
const names = chartSheetNames(prepared.map((p) => p.sheet.name));
|
|
1369
|
+
const chartParts = chartQueue.map((c, k) => ({
|
|
1370
|
+
name: chartPartName(k + 1),
|
|
1371
|
+
xml: chartPartXml(resolveChartSheets(c.chart, names, c.sheet), null)
|
|
1372
|
+
}));
|
|
1348
1373
|
const app = appXml() !== null;
|
|
1349
1374
|
const overrides = [
|
|
1350
1375
|
...tableTypes(),
|
|
1351
1376
|
...prepared.flatMap((p) => p.drawing === null ? [] : [[p.drawing.name, DRAWING_CONTENT_TYPE]]),
|
|
1377
|
+
...chartParts.map((c) => [c.name, CHART_CONTENT_TYPE]),
|
|
1352
1378
|
...media.entries().map((m) => [m.name, IMAGE_CONTENT_TYPES[m.name.slice(m.name.lastIndexOf(".") + 1)]])
|
|
1353
1379
|
];
|
|
1354
1380
|
yield {
|
|
@@ -1360,6 +1386,10 @@ function writeWorkbookStream(options) {
|
|
|
1360
1386
|
data: encoder.encode(rootRelsXml(core !== null, app))
|
|
1361
1387
|
};
|
|
1362
1388
|
yield* media.entries();
|
|
1389
|
+
for (const c of chartParts) yield {
|
|
1390
|
+
name: c.name,
|
|
1391
|
+
data: encoder.encode(c.xml)
|
|
1392
|
+
};
|
|
1363
1393
|
yield* closingParts();
|
|
1364
1394
|
}
|
|
1365
1395
|
return createZipStream(entries(), level);
|
|
@@ -81,7 +81,12 @@ interface ReadLimits {
|
|
|
81
81
|
readonly maxXmlTextLength: number;
|
|
82
82
|
/** Maximum number of elements plus attributes in a part that is parsed into a tree (workbook, styles, relationships). Default 1 000 000. */
|
|
83
83
|
readonly maxXmlTreeElements: number;
|
|
84
|
-
/**
|
|
84
|
+
/**
|
|
85
|
+
* Maximum number of cells in the workbook. Default 5 000 000 (about 0.9 GB of memory; see the
|
|
86
|
+
* README). `readWorkbook` reads charts after the cells of every sheet, and their chart groups and
|
|
87
|
+
* series (each counted once per chart part) count against what the cells leave of this limit;
|
|
88
|
+
* charts over it are skipped with `XLV_W_LIMIT_REACHED`.
|
|
89
|
+
*/
|
|
85
90
|
readonly maxCells: number;
|
|
86
91
|
/**
|
|
87
92
|
* Maximum total length, in UTF-16 code units, of the shared strings that cells refer to, each
|
|
@@ -112,7 +117,7 @@ declare const DEFAULT_READ_LIMITS: Readonly<ReadLimits>;
|
|
|
112
117
|
* console.log(ERROR_CODES.includes('XLV_E_SHEET_NOT_FOUND')); // true
|
|
113
118
|
* ```
|
|
114
119
|
*/
|
|
115
|
-
declare const ERROR_CODES: readonly ["XLV_E_INVALID_INPUT", "XLV_E_INVALID_OPTION", "XLV_E_INVALID_ARGUMENT", "XLV_E_LIMIT_EXCEEDED", "XLV_E_NOT_ZIP", "XLV_E_UNSUPPORTED_CONTAINER", "XLV_E_ZIP_CORRUPT", "XLV_E_ZIP_UNSUPPORTED", "XLV_E_XML_MALFORMED", "XLV_E_XML_DTD_FORBIDDEN", "XLV_E_XML_ENTITY_FORBIDDEN", "XLV_E_XML_ENCODING", "XLV_E_PART_MISSING", "XLV_E_PART_INVALID", "XLV_E_INVALID_CELL_REF", "XLV_E_SHEET_NOT_FOUND", "XLV_E_TABLE_NOT_FOUND", "XLV_E_FILE_READ", "XLV_E_INVALID_VALUE", "XLV_E_INVALID_STYLE", "XLV_E_INVALID_SHEET_NAME", "XLV_E_DUPLICATE_SHEET_NAME", "XLV_E_INVALID_DEFINED_NAME", "XLV_E_INVALID_HYPERLINK", "XLV_E_INVALID_TABLE", "XLV_E_INVALID_IMAGE", "XLV_E_OVERLAPPING_MERGE", "XLV_E_FILE_EXISTS", "XLV_E_FILE_WRITE", "XLV_E_HEADER_NOT_FOUND", "XLV_E_SCHEMA_INVALID", "XLV_E_ASYNC_SCHEMA", "XLV_E_INVALID_ROWS", "XLV_E_JSON_INVALID", "XLV_E_CSV_MALFORMED", "XLV_E_NOT_SUPPORTED", "XLV_E_USAGE", "XLV_E_NOT_INSTALLED", "XLV_E_INTERNAL", "XLV_E_PATH_NOT_ALLOWED"];
|
|
120
|
+
declare const ERROR_CODES: readonly ["XLV_E_INVALID_INPUT", "XLV_E_INVALID_OPTION", "XLV_E_INVALID_ARGUMENT", "XLV_E_LIMIT_EXCEEDED", "XLV_E_NOT_ZIP", "XLV_E_UNSUPPORTED_CONTAINER", "XLV_E_ZIP_CORRUPT", "XLV_E_ZIP_UNSUPPORTED", "XLV_E_XML_MALFORMED", "XLV_E_XML_DTD_FORBIDDEN", "XLV_E_XML_ENTITY_FORBIDDEN", "XLV_E_XML_ENCODING", "XLV_E_PART_MISSING", "XLV_E_PART_INVALID", "XLV_E_INVALID_CELL_REF", "XLV_E_SHEET_NOT_FOUND", "XLV_E_TABLE_NOT_FOUND", "XLV_E_FILE_READ", "XLV_E_INVALID_VALUE", "XLV_E_INVALID_STYLE", "XLV_E_INVALID_SHEET_NAME", "XLV_E_DUPLICATE_SHEET_NAME", "XLV_E_INVALID_DEFINED_NAME", "XLV_E_INVALID_HYPERLINK", "XLV_E_INVALID_TABLE", "XLV_E_INVALID_IMAGE", "XLV_E_INVALID_CHART", "XLV_E_OVERLAPPING_MERGE", "XLV_E_FILE_EXISTS", "XLV_E_FILE_WRITE", "XLV_E_HEADER_NOT_FOUND", "XLV_E_SCHEMA_INVALID", "XLV_E_ASYNC_SCHEMA", "XLV_E_INVALID_ROWS", "XLV_E_JSON_INVALID", "XLV_E_CSV_MALFORMED", "XLV_E_NOT_SUPPORTED", "XLV_E_USAGE", "XLV_E_NOT_INSTALLED", "XLV_E_INTERNAL", "XLV_E_PATH_NOT_ALLOWED"];
|
|
116
121
|
/**
|
|
117
122
|
* Every warning code xlvane can report. Warnings never stop reading; they describe something
|
|
118
123
|
* in the file that the caller may want to know about. Each one is described in docs/errors.md.
|
|
@@ -1202,6 +1207,250 @@ interface ResolvedImage {
|
|
|
1202
1207
|
readonly description: string | null;
|
|
1203
1208
|
readonly hyperlink: string | null;
|
|
1204
1209
|
}
|
|
1210
|
+
/** Markers of a resolved anchor (see {@link ResolvedImage}). */
|
|
1211
|
+
type ResolvedAnchor = Pick<ResolvedImage, "from" | "to" | "ext" | "editAs">;
|
|
1212
|
+
/**
|
|
1213
|
+
* Chart types `NewSheet.addChart` writes. `column` and `bar` are both a `barChart` (vertical and
|
|
1214
|
+
* horizontal bars), the others are `lineChart`, `pieChart`, `scatterChart` and `areaChart`
|
|
1215
|
+
* (docs/facts/charts.md CH-10).
|
|
1216
|
+
*
|
|
1217
|
+
* @example
|
|
1218
|
+
* ```ts
|
|
1219
|
+
* import type { ChartType } from 'xlvane';
|
|
1220
|
+
*
|
|
1221
|
+
* const type: ChartType = 'column';
|
|
1222
|
+
* ```
|
|
1223
|
+
*/
|
|
1224
|
+
type ChartType = "column" | "bar" | "line" | "pie" | "scatter" | "area";
|
|
1225
|
+
/**
|
|
1226
|
+
* Where a chart's legend is shown (ST_LegendPos `r`, `b`, `t`, `l`; CH-27).
|
|
1227
|
+
*
|
|
1228
|
+
* @example
|
|
1229
|
+
* ```ts
|
|
1230
|
+
* import type { ChartLegendPosition } from 'xlvane';
|
|
1231
|
+
*
|
|
1232
|
+
* const legend: ChartLegendPosition = 'bottom';
|
|
1233
|
+
* ```
|
|
1234
|
+
*/
|
|
1235
|
+
type ChartLegendPosition = "right" | "bottom" | "top" | "left";
|
|
1236
|
+
/**
|
|
1237
|
+
* One series of a chart for `NewSheet.addChart`:
|
|
1238
|
+
* - `values`: a sheet-qualified range of one row or one column, such as `"'Sales'!B2:B13"` (for
|
|
1239
|
+
* scatter charts the y values);
|
|
1240
|
+
* - `categories`: the same for the category labels (for scatter charts the x values);
|
|
1241
|
+
* - `name`: the series name, either literal text or a reference to one cell such as `"Sales!B1"`;
|
|
1242
|
+
* text that reads as a sheet-qualified cell reference is always taken as a reference;
|
|
1243
|
+
* - `color`: the colour as six hex digits `RRGGBB` (a leading `#` is accepted). Without it the
|
|
1244
|
+
* series takes the next colour of the default palette (CH-35). Pie charts colour each slice
|
|
1245
|
+
* from the palette and do not take `color`.
|
|
1246
|
+
*
|
|
1247
|
+
* @example
|
|
1248
|
+
* ```ts
|
|
1249
|
+
* import type { ChartSeriesInput } from 'xlvane';
|
|
1250
|
+
*
|
|
1251
|
+
* const series: ChartSeriesInput = { name: 'Sales!B1', categories: 'Sales!A2:A13', values: 'Sales!B2:B13', color: '2E75B6' };
|
|
1252
|
+
* ```
|
|
1253
|
+
*/
|
|
1254
|
+
interface ChartSeriesInput {
|
|
1255
|
+
readonly values: string;
|
|
1256
|
+
readonly categories?: string;
|
|
1257
|
+
readonly name?: string;
|
|
1258
|
+
readonly color?: string;
|
|
1259
|
+
}
|
|
1260
|
+
/**
|
|
1261
|
+
* Options of one chart axis: its title, and for the value axis (`y`) the fixed minimum and
|
|
1262
|
+
* maximum of its scale (CH-26).
|
|
1263
|
+
*
|
|
1264
|
+
* @example
|
|
1265
|
+
* ```ts
|
|
1266
|
+
* import type { ChartAxisInput } from 'xlvane';
|
|
1267
|
+
*
|
|
1268
|
+
* const y: ChartAxisInput = { title: 'Revenue', min: 0, max: 100 };
|
|
1269
|
+
* ```
|
|
1270
|
+
*/
|
|
1271
|
+
interface ChartAxisInput {
|
|
1272
|
+
readonly title?: string;
|
|
1273
|
+
readonly min?: number;
|
|
1274
|
+
readonly max?: number;
|
|
1275
|
+
}
|
|
1276
|
+
/**
|
|
1277
|
+
* A chart for `NewSheet.addChart`. `anchor` places it like a picture (see `ImageAnchorInput`).
|
|
1278
|
+
* `stacked` (column, bar, line and area only) stacks the series, or with `'percent'` stacks them
|
|
1279
|
+
* to 100 %. `legend` defaults to `'right'`; `false` leaves the legend out. `axes.x` is the
|
|
1280
|
+
* category axis (the x values of a scatter chart; drawn vertically for `bar`), `axes.y` the
|
|
1281
|
+
* value axis; pie charts have no axes. Options left out (`undefined`) take their defaults;
|
|
1282
|
+
* `null` is refused. A chart has 1 to 255 series (a limit of xlvane), each an object (no holes
|
|
1283
|
+
* in the array), a pie chart exactly one with at most 1 000 values; titles and literal series
|
|
1284
|
+
* names are 1 to 255 characters without control characters. `writeWorkbook` writes the cached
|
|
1285
|
+
* values of at most 4 000 000 cells, with at most 8 388 608 characters of cached text once
|
|
1286
|
+
* escaped, for all charts of a workbook together (limits of xlvane; `writeWorkbookStream` writes
|
|
1287
|
+
* no caches).
|
|
1288
|
+
* The anchor is copied when the chart is added. A sheet name that reads as a cell reference is
|
|
1289
|
+
* given in quotes (`'S1'!B2:B5`); without quotes it must be exactly the name of a sheet.
|
|
1290
|
+
*
|
|
1291
|
+
* @example
|
|
1292
|
+
* ```ts
|
|
1293
|
+
* import type { ChartInput } from 'xlvane';
|
|
1294
|
+
*
|
|
1295
|
+
* const chart: ChartInput = {
|
|
1296
|
+
* type: 'line',
|
|
1297
|
+
* anchor: 'E2:L18',
|
|
1298
|
+
* title: 'Monthly sales',
|
|
1299
|
+
* series: [{ name: 'Sales!B1', categories: 'Sales!A2:A13', values: 'Sales!B2:B13' }],
|
|
1300
|
+
* axes: { y: { title: 'EUR', min: 0 } },
|
|
1301
|
+
* };
|
|
1302
|
+
* ```
|
|
1303
|
+
*/
|
|
1304
|
+
interface ChartInput {
|
|
1305
|
+
readonly type: ChartType;
|
|
1306
|
+
readonly anchor: ImageAnchorInput;
|
|
1307
|
+
readonly series: readonly ChartSeriesInput[];
|
|
1308
|
+
readonly title?: string;
|
|
1309
|
+
readonly legend?: ChartLegendPosition | false;
|
|
1310
|
+
readonly stacked?: boolean | "percent";
|
|
1311
|
+
readonly axes?: {
|
|
1312
|
+
readonly x?: {
|
|
1313
|
+
readonly title?: string;
|
|
1314
|
+
};
|
|
1315
|
+
readonly y?: ChartAxisInput;
|
|
1316
|
+
};
|
|
1317
|
+
/** Name of the chart object, by default "Chart N". */
|
|
1318
|
+
readonly name?: string;
|
|
1319
|
+
/** Alternative text of the chart object. */
|
|
1320
|
+
readonly description?: string;
|
|
1321
|
+
}
|
|
1322
|
+
/**
|
|
1323
|
+
* The type of a chart group as read: a {@link ChartType} (`column` or `bar` from `barDir`), or
|
|
1324
|
+
* `other:` and the element name for chart types xlvane does not model, such as
|
|
1325
|
+
* `'other:radarChart'` or `'other:bar3DChart'`.
|
|
1326
|
+
*
|
|
1327
|
+
* @example
|
|
1328
|
+
* ```ts
|
|
1329
|
+
* import type { ChartKind } from 'xlvane';
|
|
1330
|
+
*
|
|
1331
|
+
* const kinds: ChartKind[] = ['column', 'line', 'other:doughnutChart'];
|
|
1332
|
+
* ```
|
|
1333
|
+
*/
|
|
1334
|
+
type ChartKind = ChartType | `other:${string}`;
|
|
1335
|
+
/**
|
|
1336
|
+
* A title or series name as read: literal `text`, or a `ref`erence to a cell (the formula text as
|
|
1337
|
+
* stored, for example `Sheet1!$B$1`; never evaluated).
|
|
1338
|
+
*
|
|
1339
|
+
* @example
|
|
1340
|
+
* ```ts
|
|
1341
|
+
* import type { ChartText } from 'xlvane';
|
|
1342
|
+
*
|
|
1343
|
+
* const show = (t: ChartText | null): string => (t === null ? '(none)' : 'text' in t ? t.text : `=${t.ref}`);
|
|
1344
|
+
* ```
|
|
1345
|
+
*/
|
|
1346
|
+
type ChartText = {
|
|
1347
|
+
readonly text: string;
|
|
1348
|
+
} | {
|
|
1349
|
+
readonly ref: string;
|
|
1350
|
+
};
|
|
1351
|
+
/**
|
|
1352
|
+
* An axis of a chart as read: its title and the fixed `min` and `max` of its scale, or `null`
|
|
1353
|
+
* where the file sets none.
|
|
1354
|
+
*
|
|
1355
|
+
* @example
|
|
1356
|
+
* ```ts
|
|
1357
|
+
* import type { ChartAxis } from 'xlvane';
|
|
1358
|
+
*
|
|
1359
|
+
* const axis: ChartAxis = { title: { text: 'EUR' }, min: 0, max: null };
|
|
1360
|
+
* ```
|
|
1361
|
+
*/
|
|
1362
|
+
interface ChartAxis {
|
|
1363
|
+
readonly title: ChartText | null;
|
|
1364
|
+
readonly min: number | null;
|
|
1365
|
+
readonly max: number | null;
|
|
1366
|
+
}
|
|
1367
|
+
/**
|
|
1368
|
+
* A series of a chart as read. `categories` and `values` are the reference texts as stored (the
|
|
1369
|
+
* x and y values of a scatter series), or `null` when the series has none or holds literal data.
|
|
1370
|
+
*
|
|
1371
|
+
* @example
|
|
1372
|
+
* ```ts
|
|
1373
|
+
* import { readWorkbook, type ChartSeries } from 'xlvane';
|
|
1374
|
+
*
|
|
1375
|
+
* declare const bytes: Uint8Array;
|
|
1376
|
+
* const series: readonly ChartSeries[] = readWorkbook(bytes).getSheet('Report').charts[0]?.series ?? [];
|
|
1377
|
+
* for (const s of series) console.log(s.type, s.values);
|
|
1378
|
+
* ```
|
|
1379
|
+
*/
|
|
1380
|
+
interface ChartSeries {
|
|
1381
|
+
readonly type: ChartKind;
|
|
1382
|
+
readonly name: ChartText | null;
|
|
1383
|
+
readonly categories: string | null;
|
|
1384
|
+
readonly values: string | null;
|
|
1385
|
+
}
|
|
1386
|
+
/**
|
|
1387
|
+
* A chart on a worksheet (a `graphicFrame` of the sheet's drawing and its chart part, CH-02,
|
|
1388
|
+
* CH-04). `types` lists the chart groups of the plot area in order; a combination chart has
|
|
1389
|
+
* several, for example `['column', 'line']`. `stacked` comes from the first group that has a
|
|
1390
|
+
* grouping (`true` for `stacked`, `'percent'` for `percentStacked`, `false` otherwise; `null`
|
|
1391
|
+
* for pie, scatter and unmodelled types). `title` is `null` without a title and for an automatic
|
|
1392
|
+
* title whose text the file does not hold. `legend` is `null` without a legend. `axes.x` is the
|
|
1393
|
+
* category axis (the x axis of a scatter chart) and `axes.y` the value axis of the first group
|
|
1394
|
+
* with axes. Charts on chart sheets are not read.
|
|
1395
|
+
*
|
|
1396
|
+
* @example
|
|
1397
|
+
* ```ts
|
|
1398
|
+
* import { readWorkbook, type SheetChart } from 'xlvane';
|
|
1399
|
+
*
|
|
1400
|
+
* declare const bytes: Uint8Array;
|
|
1401
|
+
* const charts: readonly SheetChart[] = readWorkbook(bytes).getSheet('Report').charts;
|
|
1402
|
+
* for (const c of charts) console.log(c.types.join('+'), c.series.map((s) => s.values));
|
|
1403
|
+
* ```
|
|
1404
|
+
*/
|
|
1405
|
+
interface SheetChart {
|
|
1406
|
+
readonly name: string;
|
|
1407
|
+
readonly description: string | null;
|
|
1408
|
+
readonly anchor: ImageAnchor;
|
|
1409
|
+
readonly types: readonly ChartKind[];
|
|
1410
|
+
readonly stacked: boolean | "percent" | null;
|
|
1411
|
+
readonly title: ChartText | null;
|
|
1412
|
+
readonly legend: ChartLegendPosition | "topRight" | null;
|
|
1413
|
+
readonly axes: {
|
|
1414
|
+
readonly x: ChartAxis | null;
|
|
1415
|
+
readonly y: ChartAxis | null;
|
|
1416
|
+
};
|
|
1417
|
+
readonly series: readonly ChartSeries[];
|
|
1418
|
+
}
|
|
1419
|
+
/** A validated reference: the sheet as written by the caller (resolved at write time) and the cells. */
|
|
1420
|
+
interface ChartRef {
|
|
1421
|
+
readonly sheet: string;
|
|
1422
|
+
readonly range: CellRange;
|
|
1423
|
+
/**
|
|
1424
|
+
* `true` when the sheet name was given without quotes although it reads as a cell or R1C1
|
|
1425
|
+
* reference (such as `S1!$A$1`); it must then be exactly the name of a sheet of the workbook.
|
|
1426
|
+
*/
|
|
1427
|
+
readonly unquoted?: boolean;
|
|
1428
|
+
}
|
|
1429
|
+
/** A validated series. */
|
|
1430
|
+
interface NormalizedSeries {
|
|
1431
|
+
readonly name: {
|
|
1432
|
+
readonly text: string;
|
|
1433
|
+
} | {
|
|
1434
|
+
readonly ref: ChartRef;
|
|
1435
|
+
} | null;
|
|
1436
|
+
readonly values: ChartRef;
|
|
1437
|
+
readonly categories: ChartRef | null;
|
|
1438
|
+
readonly color: string | null;
|
|
1439
|
+
}
|
|
1440
|
+
/** A validated chart, without its anchor. */
|
|
1441
|
+
interface NormalizedChart {
|
|
1442
|
+
readonly type: ChartType;
|
|
1443
|
+
readonly title: string | null;
|
|
1444
|
+
readonly legend: ChartLegendPosition | null;
|
|
1445
|
+
readonly stacked: boolean | "percent";
|
|
1446
|
+
readonly series: readonly NormalizedSeries[];
|
|
1447
|
+
readonly xTitle: string | null;
|
|
1448
|
+
readonly yTitle: string | null;
|
|
1449
|
+
readonly min: number | null;
|
|
1450
|
+
readonly max: number | null;
|
|
1451
|
+
readonly name: string | null;
|
|
1452
|
+
readonly description: string | null;
|
|
1453
|
+
}
|
|
1205
1454
|
/**
|
|
1206
1455
|
* A colour. A string is an RGB colour as 6 hex digits (`"FF0000"`) or ARGB as 8 hex digits
|
|
1207
1456
|
* (`"80FF0000"`); colours read from files are always 8 upper-case digits. Files can also refer
|
|
@@ -2613,8 +2862,19 @@ interface Sheet {
|
|
|
2613
2862
|
readonly hyperlinks: readonly Hyperlink[];
|
|
2614
2863
|
/** Notes (comments) of the sheet, in file order (see `Note`). */
|
|
2615
2864
|
readonly notes: readonly Note[];
|
|
2616
|
-
/**
|
|
2865
|
+
/**
|
|
2866
|
+
* Pictures of the sheet's drawing, in file order (see `SheetImage`); shapes are not read. A
|
|
2867
|
+
* drawing part shared with an earlier sheet is read for that sheet only
|
|
2868
|
+
* (`XLV_W_SHEET_PART_SHARED`).
|
|
2869
|
+
*/
|
|
2617
2870
|
readonly images: readonly SheetImage[];
|
|
2871
|
+
/**
|
|
2872
|
+
* Charts of the sheet's drawing, in file order (see `SheetChart`): types, series references,
|
|
2873
|
+
* titles, legend and axes. References are never evaluated. Charts on chart sheets are not read,
|
|
2874
|
+
* nor charts of a drawing part shared with an earlier sheet. Chart groups and series count
|
|
2875
|
+
* against `limits.maxCells` after the cells (see `ReadLimits.maxCells`).
|
|
2876
|
+
*/
|
|
2877
|
+
readonly charts: readonly SheetChart[];
|
|
2618
2878
|
/** The background image of the sheet (`picture` element), or `null`. */
|
|
2619
2879
|
readonly backgroundImage: WorkbookImage | null;
|
|
2620
2880
|
/** Colour of the sheet tab (`sheetPr/tabColor`), or `null`. */
|
|
@@ -3015,6 +3275,21 @@ interface InspectSheet {
|
|
|
3015
3275
|
readonly cell: string | null;
|
|
3016
3276
|
readonly format: "png" | "jpeg" | "gif" | null;
|
|
3017
3277
|
}[];
|
|
3278
|
+
/** Number of charts of the sheet's drawing (`Sheet.charts`). */
|
|
3279
|
+
readonly chartCount: number;
|
|
3280
|
+
/**
|
|
3281
|
+
* Up to ten charts: the cell of the top-left corner (or `null` for an absolute position), the
|
|
3282
|
+
* first ten chart group types (see `ChartKind`) and whether the chart has more
|
|
3283
|
+
* (`typesTruncated`), the title (`{ text }` or `{ ref }`, cut to 100 characters and `…`, or
|
|
3284
|
+
* `null`) and the number of series.
|
|
3285
|
+
*/
|
|
3286
|
+
readonly charts: readonly {
|
|
3287
|
+
readonly cell: string | null;
|
|
3288
|
+
readonly types: readonly ChartKind[];
|
|
3289
|
+
readonly typesTruncated: boolean;
|
|
3290
|
+
readonly title: ChartText | null;
|
|
3291
|
+
readonly seriesCount: number;
|
|
3292
|
+
}[];
|
|
3018
3293
|
/** `true` when the sheet is protected (`Sheet.protection.sheet`). */
|
|
3019
3294
|
readonly protected: boolean;
|
|
3020
3295
|
/** The print area (`Sheet.printArea`), or `null`. */
|
|
@@ -3152,6 +3427,10 @@ interface WriteSheetData {
|
|
|
3152
3427
|
readonly images?: readonly ResolvedImage[];
|
|
3153
3428
|
/** Background image (index into `WritePackageInput.images`), or `null`. */
|
|
3154
3429
|
readonly background?: number | null;
|
|
3430
|
+
/** Charts with resolved anchors (D-K01). */
|
|
3431
|
+
readonly charts?: readonly (ResolvedAnchor & {
|
|
3432
|
+
readonly chart: NormalizedChart;
|
|
3433
|
+
})[];
|
|
3155
3434
|
}
|
|
3156
3435
|
/** Height, visibility and outline of a row. */
|
|
3157
3436
|
interface RowFormat {
|
|
@@ -3579,6 +3858,11 @@ declare class NewSheet {
|
|
|
3579
3858
|
readonly imageList: StoredImage[];
|
|
3580
3859
|
/** @internal Background image (index of `NewWorkbook.addImage`), or `null`. */
|
|
3581
3860
|
backgroundImage: number | null;
|
|
3861
|
+
/** @internal Charts in the order they were added (D-K01). */
|
|
3862
|
+
readonly chartList: {
|
|
3863
|
+
readonly anchor: ImageAnchorInput;
|
|
3864
|
+
readonly chart: NormalizedChart;
|
|
3865
|
+
}[];
|
|
3582
3866
|
/** @internal Data validations in the order they were added (SR-01). */
|
|
3583
3867
|
readonly validationList: DataValidation[];
|
|
3584
3868
|
/** @internal Conditional formats in the order they were added (SR-07). */
|
|
@@ -3918,7 +4202,8 @@ declare class NewSheet {
|
|
|
3918
4202
|
* two corners `{ from, to }` (with `editAs`), or a corner and a size in pixels
|
|
3919
4203
|
* (`{ from, size }`), see `ImageAnchorInput`. Fractional positions and pixel sizes use the
|
|
3920
4204
|
* sheet's column widths and row heights at the time the workbook is written, at 96 pixels per
|
|
3921
|
-
* inch (TD-33).
|
|
4205
|
+
* inch (TD-33). The anchor is copied, so changing its object afterwards does not move the
|
|
4206
|
+
* picture.
|
|
3922
4207
|
*
|
|
3923
4208
|
* @example
|
|
3924
4209
|
* ```ts
|
|
@@ -3931,6 +4216,29 @@ declare class NewSheet {
|
|
|
3931
4216
|
* ```
|
|
3932
4217
|
*/
|
|
3933
4218
|
addImage(image: number, anchor: ImageAnchorInput, options?: ImageOptions): this;
|
|
4219
|
+
/**
|
|
4220
|
+
* Places a chart on the sheet: a column, bar, line, pie, scatter or area chart over ranges of
|
|
4221
|
+
* this or another sheet of the workbook (see `ChartInput`). `anchor` places it like a picture.
|
|
4222
|
+
* Each series gets an explicit colour from the default palette unless it has `color`, and the
|
|
4223
|
+
* file holds the current cell values of the ranges as caches, as Excel writes them
|
|
4224
|
+
* (docs/facts/charts.md CH-19, CH-21). The sheets named in the ranges must exist when the
|
|
4225
|
+
* workbook is written. Charts are drawn above the sheet's pictures. The caches of all charts
|
|
4226
|
+
* of a workbook cover at most 4 000 000 cells and hold at most 8 388 608 characters of text as
|
|
4227
|
+
* written, after escaping (limits of xlvane, checked when the workbook is written;
|
|
4228
|
+
* `writeWorkbookStream` writes no caches). The chart options and the anchor are copied, so changing the objects afterwards
|
|
4229
|
+
* does not change the chart. Throws `XLV_E_INVALID_CHART`.
|
|
4230
|
+
*
|
|
4231
|
+
* @example
|
|
4232
|
+
* ```ts
|
|
4233
|
+
* import { createWorkbook } from 'xlvane';
|
|
4234
|
+
*
|
|
4235
|
+
* const workbook = createWorkbook();
|
|
4236
|
+
* const sales = workbook.addSheet('Sales').set('A1', 'Month').set('B1', 'Sales');
|
|
4237
|
+
* ['Jan', 'Feb', 'Mar'].forEach((m, i) => sales.set(`A${String(i + 2)}`, m).set(`B${String(i + 2)}`, (i + 1) * 10));
|
|
4238
|
+
* sales.addChart({ type: 'column', anchor: 'D2:K16', title: 'Sales', series: [{ name: 'Sales!B1', categories: 'Sales!A2:A4', values: 'Sales!B2:B4' }] });
|
|
4239
|
+
* ```
|
|
4240
|
+
*/
|
|
4241
|
+
addChart(chart: ChartInput): this;
|
|
3934
4242
|
/**
|
|
3935
4243
|
* Sets the picture shown behind the cells of the sheet (`picture` element, Part 1 §18.3.1.67),
|
|
3936
4244
|
* or removes it with `null`. `image` is the number `NewWorkbook.addImage` returned.
|
|
@@ -4875,6 +5183,13 @@ interface StreamSheetSpec {
|
|
|
4875
5183
|
})[];
|
|
4876
5184
|
/** Background image (a position in `WriteWorkbookStreamOptions.images`), as for `NewSheet.background`. */
|
|
4877
5185
|
readonly background?: number;
|
|
5186
|
+
/**
|
|
5187
|
+
* Charts, as for `NewSheet.addChart`. The streaming writer does not keep cell values, so the
|
|
5188
|
+
* chart parts hold the references without caches; LibreOffice 24.2.7.2 draws such charts from
|
|
5189
|
+
* the cells (docs/facts/charts.md CH-20). PROVISIONAL: whether Excel shows a chart without
|
|
5190
|
+
* caches is not verified (R6-4). Fractional row positions assume the default row height.
|
|
5191
|
+
*/
|
|
5192
|
+
readonly charts?: readonly ChartInput[];
|
|
4878
5193
|
/** The rows, from row 1. Any iterable or async iterable (arrays, generators, streams of rows). */
|
|
4879
5194
|
readonly rows: Iterable<StreamRowInput> | AsyncIterable<StreamRowInput>;
|
|
4880
5195
|
}
|
|
@@ -4991,4 +5306,4 @@ interface WriteTableStreamOptions {
|
|
|
4991
5306
|
* ```
|
|
4992
5307
|
*/
|
|
4993
5308
|
declare function writeTableStream(rows: Iterable<object> | AsyncIterable<object>, options: WriteTableStreamOptions): ReadableStream<Uint8Array>;
|
|
4994
|
-
export { InspectOptions as $,
|
|
5309
|
+
export { InspectOptions as $, SheetProtection as $n, DataValidationOperator as $t, toJSON as A, SheetChart as An, Workbook as At, FormulaResult as B, Hyperlink as Bn, CfValue as Bt, TableRow as C, ChartInput as Cn, isXlvError as Cr, Sheet as Ct, fromJSON as D, ChartSeriesInput as Dn, DefinedNameOptions as Dr, SheetState as Dt, WriteTableOptions as E, ChartSeries as En, DefinedName as Er, SheetProperties as Et, CellInput as F, ImageOptions as Fn, TableDefinitionColumn as Ft, SheetPropertiesOptions as G, PageOrder as Gn, ConditionalFormatRule as Gt, NewSheet as H, HeaderFooter as Hn, CfValueType as Ht, ColumnOptions as I, ImagePositionInput as In, TableInput as It, WriteWorkbookOptions as J, PageSetupOptions as Jn, DataBarAxisPosition as Jt, SheetViewOptions as K, PageOrientation as Kn, ConditionalFormatRuleInput as Kt, CreateWorkbookOptions as L, SheetImage as Ln, TableStyleOptions as Lt, StandardSchemaV1 as M, ImageAnchor as Mn, WorkbookView as Mt, AddSheetOptions as N, ImageAnchorInput as Nn, TableColumnInput as Nt, readTable as O, ChartText as On, SheetView as Ot, CalculationOptions as P, ImageFormat as Pn, TableDefinition as Pt, InspectDefinedName as Q, PrintTitles as Qn, DataValidationImeMode as Qt, ERROR_VALUES as R, WorkbookImage as Rn, TotalsRowFunction as Rt, TableResult as S, ChartAxisInput as Sn, XlvWarningCode as Sr, RowInfo as St, ToJSONOptions as T, ChartLegendPosition as Tn, ReadLimits as Tr, SheetLayout as Tt, NewWorkbook as U, PageBreaks as Un, ConditionalFormat as Ut, FreezeOptions as V, HyperlinkTarget as Vn, CfValueInput as Vt, RowOptions as W, PageMargins as Wn, ConditionalFormatOperator as Wt, writeWorkbook as X, PrintErrors as Xn, DataValidation as Xt, createWorkbook as Y, PrintCellComments as Yn, DataBarDirection as Yt, InspectColumn as Z, PrintOptions as Zn, DataValidationErrorStyle as Zt, JsonTable as _, ReadingOrder as _n, XlvErrorCode as _r, DateSystem as _t, WriteWorkbookStreamOptions as a, BorderEdge as an, PasswordHash as ar, ReadOptions as at, TableColumnSpec as b, VerticalAlignment as bn, XlvLocation as br, FrozenPanes as bt, OpenWorkbookStreamOptions as c, CellStyle as cn, legacyPasswordHash as cr, NoteBox as ct, StreamRow as d, FontScheme as dn, WorkbookProperties as dr, NoteMargins as dt, DataValidationRule as en, SheetProtectionFlags as er, InspectReport as et, StreamSheetInfo as f, FontStyle as fn, ERROR_CODES as fr, Cell as ft, readTableStream as g, ProtectionStyle as gn, XlvError as gr, Conformance as gt, openWorkbookStream as h, PatternType as hn, XlvDetails as hr, ColumnInfo as ht, WriteTableStreamOptions as i, AlignmentStyle as in, HashPasswordOptions as ir, inspect as it, writeTable as j, AnchorMarker as jn, WorkbookFormat as jt, readTableAsync as k, ChartType as kn, SplitPanes as kt, ReadTableStreamOptions as l, Color as ln, verifyPassword as lr, NoteBoxInput as lt, WorkbookStream as m, HorizontalAlignment as mn, XlvDetailValue as mr, CellValue as mt, StreamRowInput as n, IconSetType as nn, WorkbookProtection as nr, InspectTypeCounts as nt, writeTableStream as o, BorderLineStyle as on, PasswordVerifier as or, readWorkbook as ot, TableStreamItem as p, GradientFill as pn, WARNING_CODES as pr, CellType as pt, WorkbookViewOptions as q, PageSetup as qn, ConditionalFormatType as qt, StreamSheetSpec as r, TimePeriod as rn, WorkbookProtectionOptions as rr, InspectValue as rt, writeWorkbookStream as s, BorderStyle as sn, hashPassword as sr, Note as st, StreamDefinedName as t, DataValidationType as tn, SheetProtectionOptions as tr, InspectSheet as tt, STREAM_LIMIT_DEFAULTS as u, FillStyle as un, ShaAlgorithm as ur, NoteInput as ut, ReadTableOptions as v, UnderlineStyle as vn, XlvErrorInit as vr, Formula as vt, TableValue as w, ChartKind as wn, DEFAULT_READ_LIMITS as wr, SheetKind as wt, TableIssue as x, ChartAxis as xn, XlvWarning as xr, RichTextRun as xt, TableColumn as y, VerticalAlignRun as yn, XlvErrorJSON as yr, FormulaKind as yt, ErrorValue as z, imageFormat as zn, CfIcon as zt };
|
|
@@ -359,6 +359,80 @@
|
|
|
359
359
|
"additionalProperties": false
|
|
360
360
|
}
|
|
361
361
|
},
|
|
362
|
+
"chartCount": {
|
|
363
|
+
"type": "integer",
|
|
364
|
+
"minimum": 0
|
|
365
|
+
},
|
|
366
|
+
"charts": {
|
|
367
|
+
"type": "array",
|
|
368
|
+
"items": {
|
|
369
|
+
"type": "object",
|
|
370
|
+
"properties": {
|
|
371
|
+
"cell": {
|
|
372
|
+
"anyOf": [
|
|
373
|
+
{
|
|
374
|
+
"type": "null"
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
"type": "string"
|
|
378
|
+
}
|
|
379
|
+
]
|
|
380
|
+
},
|
|
381
|
+
"types": {
|
|
382
|
+
"type": "array",
|
|
383
|
+
"items": {
|
|
384
|
+
"type": "string"
|
|
385
|
+
}
|
|
386
|
+
},
|
|
387
|
+
"typesTruncated": {
|
|
388
|
+
"type": "boolean"
|
|
389
|
+
},
|
|
390
|
+
"title": {
|
|
391
|
+
"anyOf": [
|
|
392
|
+
{
|
|
393
|
+
"type": "null"
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
"type": "object",
|
|
397
|
+
"properties": {
|
|
398
|
+
"text": {
|
|
399
|
+
"type": "string"
|
|
400
|
+
}
|
|
401
|
+
},
|
|
402
|
+
"required": [
|
|
403
|
+
"text"
|
|
404
|
+
],
|
|
405
|
+
"additionalProperties": false
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
"type": "object",
|
|
409
|
+
"properties": {
|
|
410
|
+
"ref": {
|
|
411
|
+
"type": "string"
|
|
412
|
+
}
|
|
413
|
+
},
|
|
414
|
+
"required": [
|
|
415
|
+
"ref"
|
|
416
|
+
],
|
|
417
|
+
"additionalProperties": false
|
|
418
|
+
}
|
|
419
|
+
]
|
|
420
|
+
},
|
|
421
|
+
"seriesCount": {
|
|
422
|
+
"type": "integer",
|
|
423
|
+
"minimum": 0
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
"required": [
|
|
427
|
+
"cell",
|
|
428
|
+
"types",
|
|
429
|
+
"typesTruncated",
|
|
430
|
+
"title",
|
|
431
|
+
"seriesCount"
|
|
432
|
+
],
|
|
433
|
+
"additionalProperties": false
|
|
434
|
+
}
|
|
435
|
+
},
|
|
362
436
|
"protected": {
|
|
363
437
|
"type": "boolean"
|
|
364
438
|
},
|
|
@@ -485,6 +559,8 @@
|
|
|
485
559
|
"noteCount",
|
|
486
560
|
"imageCount",
|
|
487
561
|
"images",
|
|
562
|
+
"chartCount",
|
|
563
|
+
"charts",
|
|
488
564
|
"notes",
|
|
489
565
|
"protected",
|
|
490
566
|
"printArea",
|