exceljs-lts 4.5.0 → 4.5.1
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 +9 -0
- package/README_zh.md +7 -0
- package/dist/es5/doc/table.js +25 -0
- package/dist/es5/doc/table.js.map +1 -1
- package/dist/es5/doc/worksheet.js +41 -0
- package/dist/es5/doc/worksheet.js.map +1 -1
- package/dist/es5/xlsx/xform/sheet/worksheet-xform.js +3 -4
- package/dist/es5/xlsx/xform/sheet/worksheet-xform.js.map +1 -1
- package/dist/es5/xlsx/xlsx.js +1 -1
- package/dist/es5/xlsx/xlsx.js.map +1 -1
- package/dist/exceljs.bare.js +70 -5
- package/dist/exceljs.bare.js.map +5 -5
- package/dist/exceljs.bare.min.js +4 -4
- package/dist/exceljs.bare.min.js.map +1 -1
- package/dist/exceljs.js +70 -5
- package/dist/exceljs.js.map +5 -5
- package/dist/exceljs.min.js +5 -5
- package/dist/exceljs.min.js.map +1 -1
- package/lib/doc/table.js +37 -0
- package/lib/doc/worksheet.js +37 -0
- package/lib/xlsx/xform/sheet/worksheet-xform.js +4 -4
- package/lib/xlsx/xlsx.js +1 -1
- package/package.json +1 -1
package/lib/doc/table.js
CHANGED
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
/* eslint-disable max-classes-per-file */
|
|
2
2
|
const colCache = require('../utils/col-cache');
|
|
3
3
|
|
|
4
|
+
// Excel's rules for table names: start with a letter, '_' or '\\', then letters, digits, '.' or
|
|
5
|
+
// '_'; at most 255 characters; and the name must not be read as a cell reference.
|
|
6
|
+
// Any non-ASCII character is treated as a letter so that names Excel accepts keep working.
|
|
7
|
+
const tableNameRegex = /^[A-Za-z_\\\u0080-\uFFFF][A-Za-z0-9._\u0080-\uFFFF]*$/;
|
|
8
|
+
|
|
9
|
+
function isCellReference(name) {
|
|
10
|
+
if (/^[RC]$/i.test(name) || /^R\d*C\d*$/i.test(name)) {
|
|
11
|
+
// 'R', 'C' and R1C1-style references such as 'R1C1' or 'RC'
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
const match = /^([A-Z]{1,3})(\d+)$/i.exec(name);
|
|
15
|
+
if (!match) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
// letters past XFD are not a column, so a name like 'ZZZ1' is fine
|
|
19
|
+
const letters = match[1].toUpperCase();
|
|
20
|
+
const isColumn = letters.length < 3 || letters <= 'XFD';
|
|
21
|
+
const row = parseInt(match[2], 10);
|
|
22
|
+
return isColumn && row >= 1 && row <= 1048576;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isValidTableName(name) {
|
|
26
|
+
return (
|
|
27
|
+
typeof name === 'string' &&
|
|
28
|
+
name.length <= 255 &&
|
|
29
|
+
tableNameRegex.test(name) &&
|
|
30
|
+
!isCellReference(name)
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
4
34
|
class Column {
|
|
5
35
|
// wrapper around column model, allowing access and manipulation
|
|
6
36
|
constructor(table, column, index) {
|
|
@@ -149,6 +179,13 @@ class Table {
|
|
|
149
179
|
throw new Error(message);
|
|
150
180
|
}
|
|
151
181
|
};
|
|
182
|
+
assert(table.name, 'Table must have a name');
|
|
183
|
+
assert(
|
|
184
|
+
isValidTableName(table.name),
|
|
185
|
+
`Invalid table name '${table.name}'. A table name must start with a letter, underscore ` +
|
|
186
|
+
'or backslash, contain only letters, digits, periods and underscores, ' +
|
|
187
|
+
'not look like a cell reference and be at most 255 characters long.'
|
|
188
|
+
);
|
|
152
189
|
assert(table.ref, 'Table must have ref');
|
|
153
190
|
assert(table.columns, 'Table must have column definitions');
|
|
154
191
|
assert(table.rows, 'Table must have row definitions');
|
package/lib/doc/worksheet.js
CHANGED
|
@@ -271,6 +271,23 @@ class Worksheet {
|
|
|
271
271
|
spliceColumns(start, count, ...inserts) {
|
|
272
272
|
const rows = this._rows;
|
|
273
273
|
const nRows = rows.length;
|
|
274
|
+
|
|
275
|
+
// unmerge any merges that touch the spliced or shifted columns so their cells move
|
|
276
|
+
// as plain cells; they are re-merged at their new position below
|
|
277
|
+
const merges = Object.values(this._merges).filter(merge => merge.right >= start);
|
|
278
|
+
merges.forEach(merge => {
|
|
279
|
+
for (let i = merge.top; i <= merge.bottom; i++) {
|
|
280
|
+
for (let j = merge.left; j <= merge.right; j++) {
|
|
281
|
+
// keep each cell's own style (e.g. borders) while unmerging
|
|
282
|
+
const cell = this.getCell(i, j);
|
|
283
|
+
const {style} = cell;
|
|
284
|
+
cell.unmerge();
|
|
285
|
+
cell.style = style;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
delete this._merges[colCache.encodeAddress(merge.top, merge.left)];
|
|
289
|
+
});
|
|
290
|
+
|
|
274
291
|
if (inserts.length > 0) {
|
|
275
292
|
// must iterate over all rows whether they exist yet or not
|
|
276
293
|
for (let i = 0; i < nRows; i++) {
|
|
@@ -309,6 +326,26 @@ class Worksheet {
|
|
|
309
326
|
this.getColumn(i).defn = null;
|
|
310
327
|
}
|
|
311
328
|
|
|
329
|
+
// re-merge the merges that were unmerged above, shifted, shrunk or grown to match.
|
|
330
|
+
// Inserted columns join a merge only when it continues on both sides of them.
|
|
331
|
+
merges.forEach(merge => {
|
|
332
|
+
let {left, right} = merge;
|
|
333
|
+
if (left >= nKeep) {
|
|
334
|
+
left += nExpand;
|
|
335
|
+
} else if (left >= start) {
|
|
336
|
+
left = start + inserts.length;
|
|
337
|
+
}
|
|
338
|
+
if (right >= nKeep) {
|
|
339
|
+
right += nExpand;
|
|
340
|
+
} else if (right >= start) {
|
|
341
|
+
right = start - 1;
|
|
342
|
+
}
|
|
343
|
+
// drop merges whose columns were all deleted or that are down to a single cell
|
|
344
|
+
if (left < right || (left === right && merge.top < merge.bottom)) {
|
|
345
|
+
this.mergeCellsWithoutStyle(merge.top, left, merge.bottom, right);
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
|
|
312
349
|
// account for defined names
|
|
313
350
|
this.workbook.definedNames.spliceColumns(this.name, start, count, inserts.length);
|
|
314
351
|
}
|
|
@@ -498,10 +498,10 @@ class WorkSheetXform extends BaseXform {
|
|
|
498
498
|
model.media = [];
|
|
499
499
|
if (model.drawing) {
|
|
500
500
|
const drawingRel = rels[model.drawing.rId];
|
|
501
|
-
const match =
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
501
|
+
const match =
|
|
502
|
+
drawingRel && drawingRel.Target.match(/\/drawings\/([a-zA-Z0-9]+)[.][a-zA-Z]{3,4}$/);
|
|
503
|
+
const drawing = match && options.drawings[match[1]];
|
|
504
|
+
if (drawing) {
|
|
505
505
|
drawing.anchors.forEach(anchor => {
|
|
506
506
|
if (anchor.medium) {
|
|
507
507
|
const image = {
|
package/lib/xlsx/xlsx.js
CHANGED
|
@@ -95,7 +95,7 @@ class XLSX {
|
|
|
95
95
|
Object.keys(model.drawings).forEach(name => {
|
|
96
96
|
const drawing = model.drawings[name];
|
|
97
97
|
const drawingRel = model.drawingRels[name];
|
|
98
|
-
if (drawingRel) {
|
|
98
|
+
if (drawing && drawingRel) {
|
|
99
99
|
drawingOptions.rels = drawingRel.reduce((o, rel) => {
|
|
100
100
|
o[rel.Id] = rel;
|
|
101
101
|
return o;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "exceljs-lts",
|
|
3
|
-
"version": "4.5.
|
|
3
|
+
"version": "4.5.1",
|
|
4
4
|
"description": "Maintained fork of exceljs — drop-in replacement, fixes Excel \"We found a problem with some content\" repair prompts, the TypeError crash on rich-text shared strings, and lost formula results (0, false, ''). Read and write xlsx and csv files.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"license": "MIT",
|