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/dist/exceljs.js
CHANGED
|
@@ -2674,6 +2674,29 @@ module.exports = Row;
|
|
|
2674
2674
|
|
|
2675
2675
|
/* eslint-disable max-classes-per-file */
|
|
2676
2676
|
const colCache = require('../utils/col-cache');
|
|
2677
|
+
|
|
2678
|
+
// Excel's rules for table names: start with a letter, '_' or '\\', then letters, digits, '.' or
|
|
2679
|
+
// '_'; at most 255 characters; and the name must not be read as a cell reference.
|
|
2680
|
+
// Any non-ASCII character is treated as a letter so that names Excel accepts keep working.
|
|
2681
|
+
const tableNameRegex = /^[A-Za-z_\\\u0080-\uFFFF][A-Za-z0-9._\u0080-\uFFFF]*$/;
|
|
2682
|
+
function isCellReference(name) {
|
|
2683
|
+
if (/^[RC]$/i.test(name) || /^R\d*C\d*$/i.test(name)) {
|
|
2684
|
+
// 'R', 'C' and R1C1-style references such as 'R1C1' or 'RC'
|
|
2685
|
+
return true;
|
|
2686
|
+
}
|
|
2687
|
+
const match = /^([A-Z]{1,3})(\d+)$/i.exec(name);
|
|
2688
|
+
if (!match) {
|
|
2689
|
+
return false;
|
|
2690
|
+
}
|
|
2691
|
+
// letters past XFD are not a column, so a name like 'ZZZ1' is fine
|
|
2692
|
+
const letters = match[1].toUpperCase();
|
|
2693
|
+
const isColumn = letters.length < 3 || letters <= 'XFD';
|
|
2694
|
+
const row = parseInt(match[2], 10);
|
|
2695
|
+
return isColumn && row >= 1 && row <= 1048576;
|
|
2696
|
+
}
|
|
2697
|
+
function isValidTableName(name) {
|
|
2698
|
+
return typeof name === 'string' && name.length <= 255 && tableNameRegex.test(name) && !isCellReference(name);
|
|
2699
|
+
}
|
|
2677
2700
|
class Column {
|
|
2678
2701
|
// wrapper around column model, allowing access and manipulation
|
|
2679
2702
|
constructor(table, column, index) {
|
|
@@ -2807,6 +2830,8 @@ class Table {
|
|
|
2807
2830
|
throw new Error(message);
|
|
2808
2831
|
}
|
|
2809
2832
|
};
|
|
2833
|
+
assert(table.name, 'Table must have a name');
|
|
2834
|
+
assert(isValidTableName(table.name), `Invalid table name '${table.name}'. A table name must start with a letter, underscore ` + 'or backslash, contain only letters, digits, periods and underscores, ' + 'not look like a cell reference and be at most 255 characters long.');
|
|
2810
2835
|
assert(table.ref, 'Table must have ref');
|
|
2811
2836
|
assert(table.columns, 'Table must have column definitions');
|
|
2812
2837
|
assert(table.rows, 'Table must have row definitions');
|
|
@@ -3560,6 +3585,24 @@ class Worksheet {
|
|
|
3560
3585
|
spliceColumns(start, count, ...inserts) {
|
|
3561
3586
|
const rows = this._rows;
|
|
3562
3587
|
const nRows = rows.length;
|
|
3588
|
+
|
|
3589
|
+
// unmerge any merges that touch the spliced or shifted columns so their cells move
|
|
3590
|
+
// as plain cells; they are re-merged at their new position below
|
|
3591
|
+
const merges = Object.values(this._merges).filter(merge => merge.right >= start);
|
|
3592
|
+
merges.forEach(merge => {
|
|
3593
|
+
for (let i = merge.top; i <= merge.bottom; i++) {
|
|
3594
|
+
for (let j = merge.left; j <= merge.right; j++) {
|
|
3595
|
+
// keep each cell's own style (e.g. borders) while unmerging
|
|
3596
|
+
const cell = this.getCell(i, j);
|
|
3597
|
+
const {
|
|
3598
|
+
style
|
|
3599
|
+
} = cell;
|
|
3600
|
+
cell.unmerge();
|
|
3601
|
+
cell.style = style;
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
delete this._merges[colCache.encodeAddress(merge.top, merge.left)];
|
|
3605
|
+
});
|
|
3563
3606
|
if (inserts.length > 0) {
|
|
3564
3607
|
// must iterate over all rows whether they exist yet or not
|
|
3565
3608
|
for (let i = 0; i < nRows; i++) {
|
|
@@ -3598,6 +3641,29 @@ class Worksheet {
|
|
|
3598
3641
|
this.getColumn(i).defn = null;
|
|
3599
3642
|
}
|
|
3600
3643
|
|
|
3644
|
+
// re-merge the merges that were unmerged above, shifted, shrunk or grown to match.
|
|
3645
|
+
// Inserted columns join a merge only when it continues on both sides of them.
|
|
3646
|
+
merges.forEach(merge => {
|
|
3647
|
+
let {
|
|
3648
|
+
left,
|
|
3649
|
+
right
|
|
3650
|
+
} = merge;
|
|
3651
|
+
if (left >= nKeep) {
|
|
3652
|
+
left += nExpand;
|
|
3653
|
+
} else if (left >= start) {
|
|
3654
|
+
left = start + inserts.length;
|
|
3655
|
+
}
|
|
3656
|
+
if (right >= nKeep) {
|
|
3657
|
+
right += nExpand;
|
|
3658
|
+
} else if (right >= start) {
|
|
3659
|
+
right = start - 1;
|
|
3660
|
+
}
|
|
3661
|
+
// drop merges whose columns were all deleted or that are down to a single cell
|
|
3662
|
+
if (left < right || left === right && merge.top < merge.bottom) {
|
|
3663
|
+
this.mergeCellsWithoutStyle(merge.top, left, merge.bottom, right);
|
|
3664
|
+
}
|
|
3665
|
+
});
|
|
3666
|
+
|
|
3601
3667
|
// account for defined names
|
|
3602
3668
|
this.workbook.definedNames.spliceColumns(this.name, start, count, inserts.length);
|
|
3603
3669
|
}
|
|
@@ -13159,10 +13225,9 @@ class WorkSheetXform extends BaseXform {
|
|
|
13159
13225
|
model.media = [];
|
|
13160
13226
|
if (model.drawing) {
|
|
13161
13227
|
const drawingRel = rels[model.drawing.rId];
|
|
13162
|
-
const match = drawingRel.Target.match(/\/drawings\/([a-zA-Z0-9]+)[.][a-zA-Z]{3,4}$/);
|
|
13163
|
-
|
|
13164
|
-
|
|
13165
|
-
const drawing = options.drawings[drawingName];
|
|
13228
|
+
const match = drawingRel && drawingRel.Target.match(/\/drawings\/([a-zA-Z0-9]+)[.][a-zA-Z]{3,4}$/);
|
|
13229
|
+
const drawing = match && options.drawings[match[1]];
|
|
13230
|
+
if (drawing) {
|
|
13166
13231
|
drawing.anchors.forEach(anchor => {
|
|
13167
13232
|
if (anchor.medium) {
|
|
13168
13233
|
const image = {
|
|
@@ -16326,7 +16391,7 @@ class XLSX {
|
|
|
16326
16391
|
Object.keys(model.drawings).forEach(name => {
|
|
16327
16392
|
const drawing = model.drawings[name];
|
|
16328
16393
|
const drawingRel = model.drawingRels[name];
|
|
16329
|
-
if (drawingRel) {
|
|
16394
|
+
if (drawing && drawingRel) {
|
|
16330
16395
|
drawingOptions.rels = drawingRel.reduce((o, rel) => {
|
|
16331
16396
|
o[rel.Id] = rel;
|
|
16332
16397
|
return o;
|