fix: 修复中介导入成功条数计算错误
问题: - 导入成功条数显示为负数 - 原因:成功数量计算使用 validRecords.size() - failures.size() - 但没有使用实际的数据库操作返回值 修复: - saveBatchWithUpsert 和 saveBatch 方法现在返回 int - 累加实际的数据库影响行数 - 使用 actualSuccessCount 变量跟踪真实成功数量 影响范围: - CcdiIntermediaryPersonImportServiceImpl - CcdiIntermediaryEntityImportServiceImpl
This commit is contained in:
91
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/anchor.js
generated
vendored
Normal file
91
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/anchor.js
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
'use strict';
|
||||
|
||||
const colCache = require('../utils/col-cache');
|
||||
|
||||
class Anchor {
|
||||
constructor(worksheet, address, offset = 0) {
|
||||
this.worksheet = worksheet;
|
||||
|
||||
if (!address) {
|
||||
this.nativeCol = 0;
|
||||
this.nativeColOff = 0;
|
||||
this.nativeRow = 0;
|
||||
this.nativeRowOff = 0;
|
||||
} else if (typeof address === 'string') {
|
||||
const decoded = colCache.decodeAddress(address);
|
||||
this.nativeCol = decoded.col + offset;
|
||||
this.nativeColOff = 0;
|
||||
this.nativeRow = decoded.row + offset;
|
||||
this.nativeRowOff = 0;
|
||||
} else if (address.nativeCol !== undefined) {
|
||||
this.nativeCol = address.nativeCol || 0;
|
||||
this.nativeColOff = address.nativeColOff || 0;
|
||||
this.nativeRow = address.nativeRow || 0;
|
||||
this.nativeRowOff = address.nativeRowOff || 0;
|
||||
} else if (address.col !== undefined) {
|
||||
this.col = address.col + offset;
|
||||
this.row = address.row + offset;
|
||||
} else {
|
||||
this.nativeCol = 0;
|
||||
this.nativeColOff = 0;
|
||||
this.nativeRow = 0;
|
||||
this.nativeRowOff = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static asInstance(model) {
|
||||
return model instanceof Anchor || model == null ? model : new Anchor(model);
|
||||
}
|
||||
|
||||
get col() {
|
||||
return this.nativeCol + (Math.min(this.colWidth - 1, this.nativeColOff) / this.colWidth);
|
||||
}
|
||||
|
||||
set col(v) {
|
||||
this.nativeCol = Math.floor(v);
|
||||
this.nativeColOff = Math.floor((v - this.nativeCol) * this.colWidth);
|
||||
}
|
||||
|
||||
get row() {
|
||||
return this.nativeRow + (Math.min(this.rowHeight - 1, this.nativeRowOff) / this.rowHeight);
|
||||
}
|
||||
|
||||
set row(v) {
|
||||
this.nativeRow = Math.floor(v);
|
||||
this.nativeRowOff = Math.floor((v - this.nativeRow) * this.rowHeight);
|
||||
}
|
||||
|
||||
get colWidth() {
|
||||
return this.worksheet &&
|
||||
this.worksheet.getColumn(this.nativeCol + 1) &&
|
||||
this.worksheet.getColumn(this.nativeCol + 1).isCustomWidth
|
||||
? Math.floor(this.worksheet.getColumn(this.nativeCol + 1).width * 10000)
|
||||
: 640000;
|
||||
}
|
||||
|
||||
get rowHeight() {
|
||||
return this.worksheet &&
|
||||
this.worksheet.getRow(this.nativeRow + 1) &&
|
||||
this.worksheet.getRow(this.nativeRow + 1).height
|
||||
? Math.floor(this.worksheet.getRow(this.nativeRow + 1).height * 10000)
|
||||
: 180000;
|
||||
}
|
||||
|
||||
get model() {
|
||||
return {
|
||||
nativeCol: this.nativeCol,
|
||||
nativeColOff: this.nativeColOff,
|
||||
nativeRow: this.nativeRow,
|
||||
nativeRowOff: this.nativeRowOff,
|
||||
};
|
||||
}
|
||||
|
||||
set model(value) {
|
||||
this.nativeCol = value.nativeCol;
|
||||
this.nativeColOff = value.nativeColOff;
|
||||
this.nativeRow = value.nativeRow;
|
||||
this.nativeRowOff = value.nativeRowOff;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Anchor;
|
||||
1124
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/cell.js
generated
vendored
Normal file
1124
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/cell.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
320
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/column.js
generated
vendored
Normal file
320
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/column.js
generated
vendored
Normal file
@@ -0,0 +1,320 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('../utils/under-dash');
|
||||
|
||||
const Enums = require('./enums');
|
||||
const colCache = require('../utils/col-cache');
|
||||
|
||||
const DEFAULT_COLUMN_WIDTH = 9;
|
||||
|
||||
// Column defines the column properties for 1 column.
|
||||
// This includes header rows, widths, key, (style), etc.
|
||||
// Worksheet will condense the columns as appropriate during serialization
|
||||
class Column {
|
||||
constructor(worksheet, number, defn) {
|
||||
this._worksheet = worksheet;
|
||||
this._number = number;
|
||||
if (defn !== false) {
|
||||
// sometimes defn will follow
|
||||
this.defn = defn;
|
||||
}
|
||||
}
|
||||
|
||||
get number() {
|
||||
return this._number;
|
||||
}
|
||||
|
||||
get worksheet() {
|
||||
return this._worksheet;
|
||||
}
|
||||
|
||||
get letter() {
|
||||
return colCache.n2l(this._number);
|
||||
}
|
||||
|
||||
get isCustomWidth() {
|
||||
return this.width !== undefined && this.width !== DEFAULT_COLUMN_WIDTH;
|
||||
}
|
||||
|
||||
get defn() {
|
||||
return {
|
||||
header: this._header,
|
||||
key: this.key,
|
||||
width: this.width,
|
||||
style: this.style,
|
||||
hidden: this.hidden,
|
||||
outlineLevel: this.outlineLevel,
|
||||
};
|
||||
}
|
||||
|
||||
set defn(value) {
|
||||
if (value) {
|
||||
this.key = value.key;
|
||||
this.width = value.width !== undefined ? value.width : DEFAULT_COLUMN_WIDTH;
|
||||
this.outlineLevel = value.outlineLevel;
|
||||
if (value.style) {
|
||||
this.style = value.style;
|
||||
} else {
|
||||
this.style = {};
|
||||
}
|
||||
|
||||
// headers must be set after style
|
||||
this.header = value.header;
|
||||
this._hidden = !!value.hidden;
|
||||
} else {
|
||||
delete this._header;
|
||||
delete this._key;
|
||||
delete this.width;
|
||||
this.style = {};
|
||||
this.outlineLevel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
get headers() {
|
||||
return this._header && this._header instanceof Array ? this._header : [this._header];
|
||||
}
|
||||
|
||||
get header() {
|
||||
return this._header;
|
||||
}
|
||||
|
||||
set header(value) {
|
||||
if (value !== undefined) {
|
||||
this._header = value;
|
||||
this.headers.forEach((text, index) => {
|
||||
this._worksheet.getCell(index + 1, this.number).value = text;
|
||||
});
|
||||
} else {
|
||||
this._header = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
get key() {
|
||||
return this._key;
|
||||
}
|
||||
|
||||
set key(value) {
|
||||
const column = this._key && this._worksheet.getColumnKey(this._key);
|
||||
if (column === this) {
|
||||
this._worksheet.deleteColumnKey(this._key);
|
||||
}
|
||||
|
||||
this._key = value;
|
||||
if (value) {
|
||||
this._worksheet.setColumnKey(this._key, this);
|
||||
}
|
||||
}
|
||||
|
||||
get hidden() {
|
||||
return !!this._hidden;
|
||||
}
|
||||
|
||||
set hidden(value) {
|
||||
this._hidden = value;
|
||||
}
|
||||
|
||||
get outlineLevel() {
|
||||
return this._outlineLevel || 0;
|
||||
}
|
||||
|
||||
set outlineLevel(value) {
|
||||
this._outlineLevel = value;
|
||||
}
|
||||
|
||||
get collapsed() {
|
||||
return !!(
|
||||
this._outlineLevel && this._outlineLevel >= this._worksheet.properties.outlineLevelCol
|
||||
);
|
||||
}
|
||||
|
||||
toString() {
|
||||
return JSON.stringify({
|
||||
key: this.key,
|
||||
width: this.width,
|
||||
headers: this.headers.length ? this.headers : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
equivalentTo(other) {
|
||||
return (
|
||||
this.width === other.width &&
|
||||
this.hidden === other.hidden &&
|
||||
this.outlineLevel === other.outlineLevel &&
|
||||
_.isEqual(this.style, other.style)
|
||||
);
|
||||
}
|
||||
|
||||
get isDefault() {
|
||||
if (this.isCustomWidth) {
|
||||
return false;
|
||||
}
|
||||
if (this.hidden) {
|
||||
return false;
|
||||
}
|
||||
if (this.outlineLevel) {
|
||||
return false;
|
||||
}
|
||||
const s = this.style;
|
||||
if (s && (s.font || s.numFmt || s.alignment || s.border || s.fill || s.protection)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
get headerCount() {
|
||||
return this.headers.length;
|
||||
}
|
||||
|
||||
eachCell(options, iteratee) {
|
||||
const colNumber = this.number;
|
||||
if (!iteratee) {
|
||||
iteratee = options;
|
||||
options = null;
|
||||
}
|
||||
this._worksheet.eachRow(options, (row, rowNumber) => {
|
||||
iteratee(row.getCell(colNumber), rowNumber);
|
||||
});
|
||||
}
|
||||
|
||||
get values() {
|
||||
const v = [];
|
||||
this.eachCell((cell, rowNumber) => {
|
||||
if (cell && cell.type !== Enums.ValueType.Null) {
|
||||
v[rowNumber] = cell.value;
|
||||
}
|
||||
});
|
||||
return v;
|
||||
}
|
||||
|
||||
set values(v) {
|
||||
if (!v) {
|
||||
return;
|
||||
}
|
||||
const colNumber = this.number;
|
||||
let offset = 0;
|
||||
if (v.hasOwnProperty('0')) {
|
||||
// assume contiguous array, start at row 1
|
||||
offset = 1;
|
||||
}
|
||||
v.forEach((value, index) => {
|
||||
this._worksheet.getCell(index + offset, colNumber).value = value;
|
||||
});
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// styles
|
||||
_applyStyle(name, value) {
|
||||
this.style[name] = value;
|
||||
this.eachCell(cell => {
|
||||
cell[name] = value;
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
get numFmt() {
|
||||
return this.style.numFmt;
|
||||
}
|
||||
|
||||
set numFmt(value) {
|
||||
this._applyStyle('numFmt', value);
|
||||
}
|
||||
|
||||
get font() {
|
||||
return this.style.font;
|
||||
}
|
||||
|
||||
set font(value) {
|
||||
this._applyStyle('font', value);
|
||||
}
|
||||
|
||||
get alignment() {
|
||||
return this.style.alignment;
|
||||
}
|
||||
|
||||
set alignment(value) {
|
||||
this._applyStyle('alignment', value);
|
||||
}
|
||||
|
||||
get protection() {
|
||||
return this.style.protection;
|
||||
}
|
||||
|
||||
set protection(value) {
|
||||
this._applyStyle('protection', value);
|
||||
}
|
||||
|
||||
get border() {
|
||||
return this.style.border;
|
||||
}
|
||||
|
||||
set border(value) {
|
||||
this._applyStyle('border', value);
|
||||
}
|
||||
|
||||
get fill() {
|
||||
return this.style.fill;
|
||||
}
|
||||
|
||||
set fill(value) {
|
||||
this._applyStyle('fill', value);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// static functions
|
||||
|
||||
static toModel(columns) {
|
||||
// Convert array of Column into compressed list cols
|
||||
const cols = [];
|
||||
let col = null;
|
||||
if (columns) {
|
||||
columns.forEach((column, index) => {
|
||||
if (column.isDefault) {
|
||||
if (col) {
|
||||
col = null;
|
||||
}
|
||||
} else if (!col || !column.equivalentTo(col)) {
|
||||
col = {
|
||||
min: index + 1,
|
||||
max: index + 1,
|
||||
width: column.width !== undefined ? column.width : DEFAULT_COLUMN_WIDTH,
|
||||
style: column.style,
|
||||
isCustomWidth: column.isCustomWidth,
|
||||
hidden: column.hidden,
|
||||
outlineLevel: column.outlineLevel,
|
||||
collapsed: column.collapsed,
|
||||
};
|
||||
cols.push(col);
|
||||
} else {
|
||||
col.max = index + 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
return cols.length ? cols : undefined;
|
||||
}
|
||||
|
||||
static fromModel(worksheet, cols) {
|
||||
cols = cols || [];
|
||||
const columns = [];
|
||||
let count = 1;
|
||||
let index = 0;
|
||||
/**
|
||||
* sort cols by min
|
||||
* If it is not sorted, the subsequent column configuration will be overwritten
|
||||
* */
|
||||
cols = cols.sort(function(pre, next) {
|
||||
return pre.min - next.min;
|
||||
});
|
||||
while (index < cols.length) {
|
||||
const col = cols[index++];
|
||||
while (count < col.min) {
|
||||
columns.push(new Column(worksheet, count++));
|
||||
}
|
||||
while (count <= col.max) {
|
||||
columns.push(new Column(worksheet, count++, col));
|
||||
}
|
||||
}
|
||||
return columns.length ? columns : null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Column;
|
||||
19
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/data-validations.js
generated
vendored
Normal file
19
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/data-validations.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
class DataValidations {
|
||||
constructor(model) {
|
||||
this.model = model || {};
|
||||
}
|
||||
|
||||
add(address, validation) {
|
||||
return (this.model[address] = validation);
|
||||
}
|
||||
|
||||
find(address) {
|
||||
return this.model[address];
|
||||
}
|
||||
|
||||
remove(address) {
|
||||
this.model[address] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DataValidations;
|
||||
234
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/data/theme1.json
generated
vendored
Normal file
234
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/data/theme1.json
generated
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
{
|
||||
"TODO:": "This file is for analysis only. Not ready for release",
|
||||
"name": "Office Theme",
|
||||
"themeElements": {
|
||||
"colorScheme": {
|
||||
"name": "Office",
|
||||
"dk1": { "type": "sys", "val": "windowText", "lastClr": "000000" },
|
||||
"lt1": { "type": "sys", "val": "window", "lastClr": "FFFFFF" },
|
||||
"dk2": { "type": "srgb", "val": "44546A" },
|
||||
"lt2": { "type": "srgb", "val": "E7E6E6" },
|
||||
"accent1": { "type": "srgb", "val": "5B9BD5" },
|
||||
"accent2": { "type": "srgb", "val": "ED7D31" },
|
||||
"accent3": { "type": "srgb", "val": "A5A5A5" },
|
||||
"accent4": { "type": "srgb", "val": "FFC000" },
|
||||
"accent5": { "type": "srgb", "val": "4472C4" },
|
||||
"accent6": { "type": "srgb", "val": "70AD47" },
|
||||
"hlink": { "type": "srgb", "val": "0563C1" },
|
||||
"folHlink": { "type": "srgb", "val": "954F72" }
|
||||
},
|
||||
"fontScheme": {
|
||||
"name": "Office",
|
||||
"majorFont": {
|
||||
"latin": { "typeface": "Calibri Light", "panose": "020F0302020204030204" },
|
||||
"ea": { "typeface": "" },
|
||||
"cs": { "typeface": "" },
|
||||
"fonts": [
|
||||
{ "script": "Jpan", "typeface": "游ゴシック Light" },
|
||||
{ "script": "Hang", "typeface": "맑은 고딕" },
|
||||
{ "script": "Hans", "typeface": "等线 Light" },
|
||||
{ "script": "Hant", "typeface": "新細明體" },
|
||||
{ "script": "Arab", "typeface": "Times New Roman" },
|
||||
{ "script": "Hebr", "typeface": "Times New Roman" },
|
||||
{ "script": "Thai", "typeface": "Tahoma" },
|
||||
{ "script": "Ethi", "typeface": "Nyala" },
|
||||
{ "script": "Beng", "typeface": "Vrinda" },
|
||||
{ "script": "Gujr", "typeface": "Shruti" },
|
||||
{ "script": "Khmr", "typeface": "MoolBoran" },
|
||||
{ "script": "Knda", "typeface": "Tunga" },
|
||||
{ "script": "Guru", "typeface": "Raavi" },
|
||||
{ "script": "Cans", "typeface": "Euphemia" },
|
||||
{ "script": "Cher", "typeface": "Plantagenet Cherokee" },
|
||||
{ "script": "Yiii", "typeface": "Microsoft Yi Baiti" },
|
||||
{ "script": "Tibt", "typeface": "Microsoft Himalaya" },
|
||||
{ "script": "Thaa", "typeface": "MV Boli" },
|
||||
{ "script": "Deva", "typeface": "Mangal" },
|
||||
{ "script": "Telu", "typeface": "Gautami" },
|
||||
{ "script": "Taml", "typeface": "Latha" },
|
||||
{ "script": "Syrc", "typeface": "Estrangelo Edessa" },
|
||||
{ "script": "Orya", "typeface": "Kalinga" },
|
||||
{ "script": "Mlym", "typeface": "Kartika" },
|
||||
{ "script": "Laoo", "typeface": "DokChampa" },
|
||||
{ "script": "Sinh", "typeface": "Iskoola Pota" },
|
||||
{ "script": "Mong", "typeface": "Mongolian Baiti" },
|
||||
{ "script": "Viet", "typeface": "Times New Roman" },
|
||||
{ "script": "Uigh", "typeface": "Microsoft Uighur" },
|
||||
{ "script": "Geor", "typeface": "Sylfaen" }
|
||||
]
|
||||
},
|
||||
"minorFont": {
|
||||
"latin": { "typeface": "Calibri Light", "panose": "020F0302020204030204" },
|
||||
"ea": { "typeface": "" },
|
||||
"cs": { "typeface": "" },
|
||||
"fonts": [
|
||||
{ "script":"Jpan", "typeface": "游ゴシック" },
|
||||
{ "script":"Hang", "typeface": "맑은 고딕" },
|
||||
{ "script":"Hans", "typeface": "等线" },
|
||||
{ "script":"Hant", "typeface": "新細明體" },
|
||||
{ "script":"Arab", "typeface": "Arial" },
|
||||
{ "script":"Hebr", "typeface": "Arial" },
|
||||
{ "script":"Thai", "typeface": "Tahoma" },
|
||||
{ "script":"Ethi", "typeface": "Nyala" },
|
||||
{ "script":"Beng", "typeface": "Vrinda" },
|
||||
{ "script":"Gujr", "typeface": "Shruti" },
|
||||
{ "script":"Khmr", "typeface": "DaunPenh" },
|
||||
{ "script":"Knda", "typeface": "Tunga" },
|
||||
{ "script":"Guru", "typeface": "Raavi" },
|
||||
{ "script":"Cans", "typeface": "Euphemia" },
|
||||
{ "script":"Cher", "typeface": "Plantagenet Cherokee" },
|
||||
{ "script":"Yiii", "typeface": "Microsoft Yi Baiti" },
|
||||
{ "script":"Tibt", "typeface": "Microsoft Himalaya" },
|
||||
{ "script":"Thaa", "typeface": "MV Boli" },
|
||||
{ "script":"Deva", "typeface": "Mangal" },
|
||||
{ "script":"Telu", "typeface": "Gautami" },
|
||||
{ "script":"Taml", "typeface": "Latha" },
|
||||
{ "script":"Syrc", "typeface": "Estrangelo Edessa" },
|
||||
{ "script":"Orya", "typeface": "Kalinga" },
|
||||
{ "script":"Mlym", "typeface": "Kartika" },
|
||||
{ "script":"Laoo", "typeface": "DokChampa" },
|
||||
{ "script":"Sinh", "typeface": "Iskoola Pota" },
|
||||
{ "script":"Mong", "typeface": "Mongolian Baiti" },
|
||||
{ "script":"Viet", "typeface": "Arial" },
|
||||
{ "script":"Uigh", "typeface": "Microsoft Uighur" },
|
||||
{ "script":"Geor", "typeface": "Sylfaen" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"fmtScheme": {
|
||||
"name": "Office",
|
||||
"fillStyleLst": [
|
||||
{ "type": "solidFill", "val": "phClr" },
|
||||
{
|
||||
"type": "gradFill",
|
||||
"rotWithShape": true,
|
||||
"gsLst": [
|
||||
{ "pos":0, "schemeClr": { "val": "phClr", "lumMod": 110000, "satMod": 105000, "tint": 67000 } },
|
||||
{ "pos":50000, "schemeClr": { "val": "phClr", "lumMod": 105000, "satMod": 103000, "tint": 73000 } },
|
||||
{ "pos":100000, "schemeClr": { "val": "phClr", "lumMod": 105000, "satMod": 109000, "tint": 81000 } }
|
||||
],
|
||||
"lin": { "ang": 5400000, "scaled": false }
|
||||
},
|
||||
{
|
||||
"type": "gradFill",
|
||||
"rotWithShape": true,
|
||||
"gsLst": [
|
||||
{ "pos":0, "schemeClr": { "val": "phClr", "satMod": 103000, "lumMod": 102000, "tint": 94000 } },
|
||||
{ "pos":50000, "schemeClr": { "val": "phClr", "satMod": 110000, "lumMod": 100000, "shade": 100000 } },
|
||||
{ "pos":100000, "schemeClr": { "val": "phClr", "lumMod": 99000, "satMod": 120000, "tint": 78000 } }
|
||||
],
|
||||
"lin": { "ang": 5400000, "scaled": false }
|
||||
}
|
||||
],
|
||||
"lnStyleLst": [
|
||||
{
|
||||
"w": 6350, "cap": "flat", "cmpd": "sng", "algn": "ctr",
|
||||
"solidFill": { "schemeClr": { "val": "phClr" } },
|
||||
"prstDash": { "val": "solid" },
|
||||
"miter": { "lim": 800000 }
|
||||
},
|
||||
{
|
||||
"w": 12700, "cap": "flat", "cmpd": "sng", "algn": "ctr",
|
||||
"solidFill": { "schemeClr": { "val": "phClr" } },
|
||||
"prstDash": { "val": "solid" },
|
||||
"miter": { "lim": 800000 }
|
||||
},
|
||||
{
|
||||
"w": 19050, "cap": "flat", "cmpd": "sng", "algn": "ctr",
|
||||
"solidFill": { "schemeClr": { "val": "phClr" } },
|
||||
"prstDash": { "val": "solid" },
|
||||
"miter": { "lim": 800000 }
|
||||
}
|
||||
],
|
||||
"effectStyleLst": [
|
||||
{ "effectLst": [] },
|
||||
{ "effectLst": [] },
|
||||
{
|
||||
"effectLst": [
|
||||
{
|
||||
"type": "outerShdw",
|
||||
"blurRad": 57150, "dist": 19050, "dir": 5400000, "algn": "ctr", "rotWithShape": false,
|
||||
"srgbClr": {
|
||||
"val": "000000",
|
||||
"alpha": {"val": 63000 }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"bgFillStyleLst": [
|
||||
{ "type": "solidFill", "schemeClr": { "val": "phClr" } },
|
||||
{ "type": "solidFill", "schemeClr": { "val": "phClr", "tint": 95000, "satMod": 170000 } },
|
||||
{
|
||||
"type": "gradFill",
|
||||
"rotWithShape": true,
|
||||
"gsLst": [
|
||||
{ "pos":0, "schemeClr": { "val": "phClr", "tint": 93000, "satMod": 150000, "shade": 90000, "lumMod": 102000 } },
|
||||
{ "pos":50000, "schemeClr": { "val": "phClr", "tint": 98000, "satMod": 130000, "shade": 73000, "lumMod": 103000 } },
|
||||
{ "pos":100000, "schemeClr": { "val": "phClr", "shade": 63000, "satMod": 120000 } }
|
||||
],
|
||||
"lin": { "ang": 5400000, "scaled": false }
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"objectDefaults": {
|
||||
"spDef": {
|
||||
"spPr": {},
|
||||
"bodyPr": {},
|
||||
"lstStyle": {},
|
||||
"style": {
|
||||
"lnRef": {
|
||||
"idx": 1,
|
||||
"schemeClr": "accent1"
|
||||
},
|
||||
"effectRef": {
|
||||
"idx": 2,
|
||||
"schemeClr": "accent1"
|
||||
},
|
||||
"fillRef": {
|
||||
"idx": 3,
|
||||
"schemeClr": "accent1"
|
||||
},
|
||||
"fontRef": {
|
||||
"idx": "minor",
|
||||
"schemeClr": "lt1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lnDef": {
|
||||
"spPr": {},
|
||||
"bodyPr": {},
|
||||
"lstStyle": {},
|
||||
"style": {
|
||||
"lnRef": {
|
||||
"idx": 2,
|
||||
"schemeClr": "accent1"
|
||||
},
|
||||
"effectRef": {
|
||||
"idx": 0,
|
||||
"schemeClr": "accent1"
|
||||
},
|
||||
"fillRef": {
|
||||
"idx": 1,
|
||||
"schemeClr": "accent1"
|
||||
},
|
||||
"fontRef": {
|
||||
"idx": "minor",
|
||||
"schemeClr": "tx1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"extraClrSchemeLst": [],
|
||||
"extLst": [
|
||||
{
|
||||
"uri": "{05A4C25C-085E-4340-85A3-A5531E510DB2}",
|
||||
"themeFamily": {
|
||||
"name": "Office Theme",
|
||||
"id": "{62F939B6-93AF-4DB8-9C6B-D6C7DFDC589F}",
|
||||
"vid": "{4A3C46E8-61CC-4603-A589-7422A47A8E4A}",
|
||||
"thm15": "http://schemas.microsoft.com/office/thememl/2012/main"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
196
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/defined-names.js
generated
vendored
Normal file
196
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/defined-names.js
generated
vendored
Normal file
@@ -0,0 +1,196 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('../utils/under-dash');
|
||||
const colCache = require('../utils/col-cache');
|
||||
const CellMatrix = require('../utils/cell-matrix');
|
||||
const Range = require('./range');
|
||||
|
||||
const rangeRegexp = /[$](\w+)[$](\d+)(:[$](\w+)[$](\d+))?/;
|
||||
|
||||
class DefinedNames {
|
||||
constructor() {
|
||||
this.matrixMap = {};
|
||||
}
|
||||
|
||||
getMatrix(name) {
|
||||
const matrix = this.matrixMap[name] || (this.matrixMap[name] = new CellMatrix());
|
||||
return matrix;
|
||||
}
|
||||
|
||||
// add a name to a cell. locStr in the form SheetName!$col$row or SheetName!$c1$r1:$c2:$r2
|
||||
add(locStr, name) {
|
||||
const location = colCache.decodeEx(locStr);
|
||||
this.addEx(location, name);
|
||||
}
|
||||
|
||||
addEx(location, name) {
|
||||
const matrix = this.getMatrix(name);
|
||||
if (location.top) {
|
||||
for (let col = location.left; col <= location.right; col++) {
|
||||
for (let row = location.top; row <= location.bottom; row++) {
|
||||
const address = {
|
||||
sheetName: location.sheetName,
|
||||
address: colCache.n2l(col) + row,
|
||||
row,
|
||||
col,
|
||||
};
|
||||
|
||||
matrix.addCellEx(address);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
matrix.addCellEx(location);
|
||||
}
|
||||
}
|
||||
|
||||
remove(locStr, name) {
|
||||
const location = colCache.decodeEx(locStr);
|
||||
this.removeEx(location, name);
|
||||
}
|
||||
|
||||
removeEx(location, name) {
|
||||
const matrix = this.getMatrix(name);
|
||||
matrix.removeCellEx(location);
|
||||
}
|
||||
|
||||
removeAllNames(location) {
|
||||
_.each(this.matrixMap, matrix => {
|
||||
matrix.removeCellEx(location);
|
||||
});
|
||||
}
|
||||
|
||||
forEach(callback) {
|
||||
_.each(this.matrixMap, (matrix, name) => {
|
||||
matrix.forEach(cell => {
|
||||
callback(name, cell);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// get all the names of a cell
|
||||
getNames(addressStr) {
|
||||
return this.getNamesEx(colCache.decodeEx(addressStr));
|
||||
}
|
||||
|
||||
getNamesEx(address) {
|
||||
return _.map(this.matrixMap, (matrix, name) => matrix.findCellEx(address) && name).filter(
|
||||
Boolean
|
||||
);
|
||||
}
|
||||
|
||||
_explore(matrix, cell) {
|
||||
cell.mark = false;
|
||||
const {sheetName} = cell;
|
||||
|
||||
const range = new Range(cell.row, cell.col, cell.row, cell.col, sheetName);
|
||||
let x;
|
||||
let y;
|
||||
|
||||
// grow vertical - only one col to worry about
|
||||
function vGrow(yy, edge) {
|
||||
const c = matrix.findCellAt(sheetName, yy, cell.col);
|
||||
if (!c || !c.mark) {
|
||||
return false;
|
||||
}
|
||||
range[edge] = yy;
|
||||
c.mark = false;
|
||||
return true;
|
||||
}
|
||||
for (y = cell.row - 1; vGrow(y, 'top'); y--);
|
||||
for (y = cell.row + 1; vGrow(y, 'bottom'); y++);
|
||||
|
||||
// grow horizontal - ensure all rows can grow
|
||||
function hGrow(xx, edge) {
|
||||
const cells = [];
|
||||
for (y = range.top; y <= range.bottom; y++) {
|
||||
const c = matrix.findCellAt(sheetName, y, xx);
|
||||
if (c && c.mark) {
|
||||
cells.push(c);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
range[edge] = xx;
|
||||
for (let i = 0; i < cells.length; i++) {
|
||||
cells[i].mark = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
for (x = cell.col - 1; hGrow(x, 'left'); x--);
|
||||
for (x = cell.col + 1; hGrow(x, 'right'); x++);
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
getRanges(name, matrix) {
|
||||
matrix = matrix || this.matrixMap[name];
|
||||
|
||||
if (!matrix) {
|
||||
return {name, ranges: []};
|
||||
}
|
||||
|
||||
// mark and sweep!
|
||||
matrix.forEach(cell => {
|
||||
cell.mark = true;
|
||||
});
|
||||
const ranges = matrix
|
||||
.map(cell => cell.mark && this._explore(matrix, cell))
|
||||
.filter(Boolean)
|
||||
.map(range => range.$shortRange);
|
||||
|
||||
return {
|
||||
name,
|
||||
ranges,
|
||||
};
|
||||
}
|
||||
|
||||
normaliseMatrix(matrix, sheetName) {
|
||||
// some of the cells might have shifted on specified sheet
|
||||
// need to reassign rows, cols
|
||||
matrix.forEachInSheet(sheetName, (cell, row, col) => {
|
||||
if (cell) {
|
||||
if (cell.row !== row || cell.col !== col) {
|
||||
cell.row = row;
|
||||
cell.col = col;
|
||||
cell.address = colCache.n2l(col) + row;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
spliceRows(sheetName, start, numDelete, numInsert) {
|
||||
_.each(this.matrixMap, matrix => {
|
||||
matrix.spliceRows(sheetName, start, numDelete, numInsert);
|
||||
this.normaliseMatrix(matrix, sheetName);
|
||||
});
|
||||
}
|
||||
|
||||
spliceColumns(sheetName, start, numDelete, numInsert) {
|
||||
_.each(this.matrixMap, matrix => {
|
||||
matrix.spliceColumns(sheetName, start, numDelete, numInsert);
|
||||
this.normaliseMatrix(matrix, sheetName);
|
||||
});
|
||||
}
|
||||
|
||||
get model() {
|
||||
// To get names per cell - just iterate over all names finding cells if they exist
|
||||
return _.map(this.matrixMap, (matrix, name) => this.getRanges(name, matrix)).filter(
|
||||
definedName => definedName.ranges.length
|
||||
);
|
||||
}
|
||||
|
||||
set model(value) {
|
||||
// value is [ { name, ranges }, ... ]
|
||||
const matrixMap = (this.matrixMap = {});
|
||||
value.forEach(definedName => {
|
||||
const matrix = (matrixMap[definedName.name] = new CellMatrix());
|
||||
definedName.ranges.forEach(rangeStr => {
|
||||
if (rangeRegexp.test(rangeStr.split('!').pop() || '')) {
|
||||
matrix.addCell(rangeStr);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = DefinedNames;
|
||||
48
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/enums.js
generated
vendored
Normal file
48
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/enums.js
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
ValueType: {
|
||||
Null: 0,
|
||||
Merge: 1,
|
||||
Number: 2,
|
||||
String: 3,
|
||||
Date: 4,
|
||||
Hyperlink: 5,
|
||||
Formula: 6,
|
||||
SharedString: 7,
|
||||
RichText: 8,
|
||||
Boolean: 9,
|
||||
Error: 10,
|
||||
},
|
||||
FormulaType: {
|
||||
None: 0,
|
||||
Master: 1,
|
||||
Shared: 2,
|
||||
},
|
||||
RelationshipType: {
|
||||
None: 0,
|
||||
OfficeDocument: 1,
|
||||
Worksheet: 2,
|
||||
CalcChain: 3,
|
||||
SharedStrings: 4,
|
||||
Styles: 5,
|
||||
Theme: 6,
|
||||
Hyperlink: 7,
|
||||
},
|
||||
DocumentType: {
|
||||
Xlsx: 1,
|
||||
},
|
||||
ReadingOrder: {
|
||||
LeftToRight: 1,
|
||||
RightToLeft: 2,
|
||||
},
|
||||
ErrorValue: {
|
||||
NotApplicable: '#N/A',
|
||||
Ref: '#REF!',
|
||||
Name: '#NAME?',
|
||||
DivZero: '#DIV/0!',
|
||||
Null: '#NULL!',
|
||||
Value: '#VALUE!',
|
||||
Num: '#NUM!',
|
||||
},
|
||||
};
|
||||
59
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/image.js
generated
vendored
Normal file
59
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/image.js
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
const colCache = require('../utils/col-cache');
|
||||
const Anchor = require('./anchor');
|
||||
|
||||
class Image {
|
||||
constructor(worksheet, model) {
|
||||
this.worksheet = worksheet;
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
get model() {
|
||||
switch (this.type) {
|
||||
case 'background':
|
||||
return {
|
||||
type: this.type,
|
||||
imageId: this.imageId,
|
||||
};
|
||||
case 'image':
|
||||
return {
|
||||
type: this.type,
|
||||
imageId: this.imageId,
|
||||
hyperlinks: this.range.hyperlinks,
|
||||
range: {
|
||||
tl: this.range.tl.model,
|
||||
br: this.range.br && this.range.br.model,
|
||||
ext: this.range.ext,
|
||||
editAs: this.range.editAs,
|
||||
},
|
||||
};
|
||||
default:
|
||||
throw new Error('Invalid Image Type');
|
||||
}
|
||||
}
|
||||
|
||||
set model({type, imageId, range, hyperlinks}) {
|
||||
this.type = type;
|
||||
this.imageId = imageId;
|
||||
|
||||
if (type === 'image') {
|
||||
if (typeof range === 'string') {
|
||||
const decoded = colCache.decode(range);
|
||||
this.range = {
|
||||
tl: new Anchor(this.worksheet, {col: decoded.left, row: decoded.top}, -1),
|
||||
br: new Anchor(this.worksheet, {col: decoded.right, row: decoded.bottom}, 0),
|
||||
editAs: 'oneCell',
|
||||
};
|
||||
} else {
|
||||
this.range = {
|
||||
tl: new Anchor(this.worksheet, range.tl, 0),
|
||||
br: range.br && new Anchor(this.worksheet, range.br, 0),
|
||||
ext: range.ext,
|
||||
editAs: range.editAs,
|
||||
hyperlinks: hyperlinks || range.hyperlinks,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Image;
|
||||
18
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/modelcontainer.js
generated
vendored
Normal file
18
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/modelcontainer.js
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
const XLSX = require('../xlsx/xlsx');
|
||||
|
||||
class ModelContainer {
|
||||
constructor(model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
get xlsx() {
|
||||
if (!this._xlsx) {
|
||||
this._xlsx = new XLSX(this);
|
||||
}
|
||||
return this._xlsx;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ModelContainer;
|
||||
65
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/note.js
generated
vendored
Normal file
65
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/note.js
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
const _ = require('../utils/under-dash');
|
||||
|
||||
class Note {
|
||||
constructor(note) {
|
||||
this.note = note;
|
||||
}
|
||||
|
||||
get model() {
|
||||
let value = null;
|
||||
switch (typeof this.note) {
|
||||
case 'string':
|
||||
value = {
|
||||
type: 'note',
|
||||
note: {
|
||||
texts: [
|
||||
{
|
||||
text: this.note,
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
break;
|
||||
default:
|
||||
value = {
|
||||
type: 'note',
|
||||
note: this.note,
|
||||
};
|
||||
break;
|
||||
}
|
||||
// Suitable for all cell comments
|
||||
return _.deepMerge({}, Note.DEFAULT_CONFIGS, value);
|
||||
}
|
||||
|
||||
set model(value) {
|
||||
const {note} = value;
|
||||
const {texts} = note;
|
||||
if (texts.length === 1 && Object.keys(texts[0]).length === 1) {
|
||||
this.note = texts[0].text;
|
||||
} else {
|
||||
this.note = note;
|
||||
}
|
||||
}
|
||||
|
||||
static fromModel(model) {
|
||||
const note = new Note();
|
||||
note.model = model;
|
||||
return note;
|
||||
}
|
||||
}
|
||||
|
||||
Note.DEFAULT_CONFIGS = {
|
||||
note: {
|
||||
margins: {
|
||||
insetmode: 'auto',
|
||||
inset: [0.13, 0.13, 0.25, 0.25],
|
||||
},
|
||||
protection: {
|
||||
locked: 'True',
|
||||
lockText: 'True',
|
||||
},
|
||||
editAs: 'absolute',
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = Note;
|
||||
257
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/range.js
generated
vendored
Normal file
257
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/range.js
generated
vendored
Normal file
@@ -0,0 +1,257 @@
|
||||
const colCache = require('../utils/col-cache');
|
||||
|
||||
// used by worksheet to calculate sheet dimensions
|
||||
class Range {
|
||||
constructor() {
|
||||
this.decode(arguments);
|
||||
}
|
||||
|
||||
setTLBR(t, l, b, r, s) {
|
||||
if (arguments.length < 4) {
|
||||
// setTLBR(tl, br, s)
|
||||
const tl = colCache.decodeAddress(t);
|
||||
const br = colCache.decodeAddress(l);
|
||||
this.model = {
|
||||
top: Math.min(tl.row, br.row),
|
||||
left: Math.min(tl.col, br.col),
|
||||
bottom: Math.max(tl.row, br.row),
|
||||
right: Math.max(tl.col, br.col),
|
||||
sheetName: b,
|
||||
};
|
||||
|
||||
this.setTLBR(tl.row, tl.col, br.row, br.col, s);
|
||||
} else {
|
||||
// setTLBR(t, l, b, r, s)
|
||||
this.model = {
|
||||
top: Math.min(t, b),
|
||||
left: Math.min(l, r),
|
||||
bottom: Math.max(t, b),
|
||||
right: Math.max(l, r),
|
||||
sheetName: s,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
decode(argv) {
|
||||
switch (argv.length) {
|
||||
case 5: // [t,l,b,r,s]
|
||||
this.setTLBR(argv[0], argv[1], argv[2], argv[3], argv[4]);
|
||||
break;
|
||||
case 4: // [t,l,b,r]
|
||||
this.setTLBR(argv[0], argv[1], argv[2], argv[3]);
|
||||
break;
|
||||
|
||||
case 3: // [tl,br,s]
|
||||
this.setTLBR(argv[0], argv[1], argv[2]);
|
||||
break;
|
||||
case 2: // [tl,br]
|
||||
this.setTLBR(argv[0], argv[1]);
|
||||
break;
|
||||
|
||||
case 1: {
|
||||
const value = argv[0];
|
||||
if (value instanceof Range) {
|
||||
// copy constructor
|
||||
this.model = {
|
||||
top: value.model.top,
|
||||
left: value.model.left,
|
||||
bottom: value.model.bottom,
|
||||
right: value.model.right,
|
||||
sheetName: value.sheetName,
|
||||
};
|
||||
} else if (value instanceof Array) {
|
||||
// an arguments array
|
||||
this.decode(value);
|
||||
} else if (value.top && value.left && value.bottom && value.right) {
|
||||
// a model
|
||||
this.model = {
|
||||
top: value.top,
|
||||
left: value.left,
|
||||
bottom: value.bottom,
|
||||
right: value.right,
|
||||
sheetName: value.sheetName,
|
||||
};
|
||||
} else {
|
||||
// [sheetName!]tl:br
|
||||
const tlbr = colCache.decodeEx(value);
|
||||
if (tlbr.top) {
|
||||
this.model = {
|
||||
top: tlbr.top,
|
||||
left: tlbr.left,
|
||||
bottom: tlbr.bottom,
|
||||
right: tlbr.right,
|
||||
sheetName: tlbr.sheetName,
|
||||
};
|
||||
} else {
|
||||
this.model = {
|
||||
top: tlbr.row,
|
||||
left: tlbr.col,
|
||||
bottom: tlbr.row,
|
||||
right: tlbr.col,
|
||||
sheetName: tlbr.sheetName,
|
||||
};
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0:
|
||||
this.model = {
|
||||
top: 0,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
right: 0,
|
||||
};
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error(`Invalid number of arguments to _getDimensions() - ${argv.length}`);
|
||||
}
|
||||
}
|
||||
|
||||
get top() {
|
||||
return this.model.top || 1;
|
||||
}
|
||||
|
||||
set top(value) {
|
||||
this.model.top = value;
|
||||
}
|
||||
|
||||
get left() {
|
||||
return this.model.left || 1;
|
||||
}
|
||||
|
||||
set left(value) {
|
||||
this.model.left = value;
|
||||
}
|
||||
|
||||
get bottom() {
|
||||
return this.model.bottom || 1;
|
||||
}
|
||||
|
||||
set bottom(value) {
|
||||
this.model.bottom = value;
|
||||
}
|
||||
|
||||
get right() {
|
||||
return this.model.right || 1;
|
||||
}
|
||||
|
||||
set right(value) {
|
||||
this.model.right = value;
|
||||
}
|
||||
|
||||
get sheetName() {
|
||||
return this.model.sheetName;
|
||||
}
|
||||
|
||||
set sheetName(value) {
|
||||
this.model.sheetName = value;
|
||||
}
|
||||
|
||||
get _serialisedSheetName() {
|
||||
const {sheetName} = this.model;
|
||||
if (sheetName) {
|
||||
if (/^[a-zA-Z0-9]*$/.test(sheetName)) {
|
||||
return `${sheetName}!`;
|
||||
}
|
||||
return `'${sheetName}'!`;
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
expand(top, left, bottom, right) {
|
||||
if (!this.model.top || top < this.top) this.top = top;
|
||||
if (!this.model.left || left < this.left) this.left = left;
|
||||
if (!this.model.bottom || bottom > this.bottom) this.bottom = bottom;
|
||||
if (!this.model.right || right > this.right) this.right = right;
|
||||
}
|
||||
|
||||
expandRow(row) {
|
||||
if (row) {
|
||||
const {dimensions, number} = row;
|
||||
if (dimensions) {
|
||||
this.expand(number, dimensions.min, number, dimensions.max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expandToAddress(addressStr) {
|
||||
const address = colCache.decodeEx(addressStr);
|
||||
this.expand(address.row, address.col, address.row, address.col);
|
||||
}
|
||||
|
||||
get tl() {
|
||||
return colCache.n2l(this.left) + this.top;
|
||||
}
|
||||
|
||||
get $t$l() {
|
||||
return `$${colCache.n2l(this.left)}$${this.top}`;
|
||||
}
|
||||
|
||||
get br() {
|
||||
return colCache.n2l(this.right) + this.bottom;
|
||||
}
|
||||
|
||||
get $b$r() {
|
||||
return `$${colCache.n2l(this.right)}$${this.bottom}`;
|
||||
}
|
||||
|
||||
get range() {
|
||||
return `${this._serialisedSheetName + this.tl}:${this.br}`;
|
||||
}
|
||||
|
||||
get $range() {
|
||||
return `${this._serialisedSheetName + this.$t$l}:${this.$b$r}`;
|
||||
}
|
||||
|
||||
get shortRange() {
|
||||
return this.count > 1 ? this.range : this._serialisedSheetName + this.tl;
|
||||
}
|
||||
|
||||
get $shortRange() {
|
||||
return this.count > 1 ? this.$range : this._serialisedSheetName + this.$t$l;
|
||||
}
|
||||
|
||||
get count() {
|
||||
return (1 + this.bottom - this.top) * (1 + this.right - this.left);
|
||||
}
|
||||
|
||||
toString() {
|
||||
return this.range;
|
||||
}
|
||||
|
||||
intersects(other) {
|
||||
if (other.sheetName && this.sheetName && other.sheetName !== this.sheetName) return false;
|
||||
if (other.bottom < this.top) return false;
|
||||
if (other.top > this.bottom) return false;
|
||||
if (other.right < this.left) return false;
|
||||
if (other.left > this.right) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
contains(addressStr) {
|
||||
const address = colCache.decodeEx(addressStr);
|
||||
return this.containsEx(address);
|
||||
}
|
||||
|
||||
containsEx(address) {
|
||||
if (address.sheetName && this.sheetName && address.sheetName !== this.sheetName) return false;
|
||||
return (
|
||||
address.row >= this.top &&
|
||||
address.row <= this.bottom &&
|
||||
address.col >= this.left &&
|
||||
address.col <= this.right
|
||||
);
|
||||
}
|
||||
|
||||
forEachAddress(cb) {
|
||||
for (let col = this.left; col <= this.right; col++) {
|
||||
for (let row = this.top; row <= this.bottom; row++) {
|
||||
cb(colCache.encodeAddress(row, col), row, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Range;
|
||||
415
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/row.js
generated
vendored
Normal file
415
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/row.js
generated
vendored
Normal file
@@ -0,0 +1,415 @@
|
||||
'use strict';
|
||||
|
||||
const _ = require('../utils/under-dash');
|
||||
|
||||
const Enums = require('./enums');
|
||||
const colCache = require('../utils/col-cache');
|
||||
const Cell = require('./cell');
|
||||
|
||||
class Row {
|
||||
constructor(worksheet, number) {
|
||||
this._worksheet = worksheet;
|
||||
this._number = number;
|
||||
this._cells = [];
|
||||
this.style = {};
|
||||
this.outlineLevel = 0;
|
||||
}
|
||||
|
||||
// return the row number
|
||||
get number() {
|
||||
return this._number;
|
||||
}
|
||||
|
||||
get worksheet() {
|
||||
return this._worksheet;
|
||||
}
|
||||
|
||||
// Inform Streaming Writer that this row (and all rows before it) are complete
|
||||
// and ready to write. Has no effect on Worksheet document
|
||||
commit() {
|
||||
this._worksheet._commitRow(this); // eslint-disable-line no-underscore-dangle
|
||||
}
|
||||
|
||||
// helps GC by breaking cyclic references
|
||||
destroy() {
|
||||
delete this._worksheet;
|
||||
delete this._cells;
|
||||
delete this.style;
|
||||
}
|
||||
|
||||
findCell(colNumber) {
|
||||
return this._cells[colNumber - 1];
|
||||
}
|
||||
|
||||
// given {address, row, col}, find or create new cell
|
||||
getCellEx(address) {
|
||||
let cell = this._cells[address.col - 1];
|
||||
if (!cell) {
|
||||
const column = this._worksheet.getColumn(address.col);
|
||||
cell = new Cell(this, column, address.address);
|
||||
this._cells[address.col - 1] = cell;
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
// get cell by key, letter or column number
|
||||
getCell(col) {
|
||||
if (typeof col === 'string') {
|
||||
// is it a key?
|
||||
const column = this._worksheet.getColumnKey(col);
|
||||
if (column) {
|
||||
col = column.number;
|
||||
} else {
|
||||
col = colCache.l2n(col);
|
||||
}
|
||||
}
|
||||
return (
|
||||
this._cells[col - 1] ||
|
||||
this.getCellEx({
|
||||
address: colCache.encodeAddress(this._number, col),
|
||||
row: this._number,
|
||||
col,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// remove cell(s) and shift all higher cells down by count
|
||||
splice(start, count, ...inserts) {
|
||||
const nKeep = start + count;
|
||||
const nExpand = inserts.length - count;
|
||||
const nEnd = this._cells.length;
|
||||
let i;
|
||||
let cSrc;
|
||||
let cDst;
|
||||
|
||||
if (nExpand < 0) {
|
||||
// remove cells
|
||||
for (i = start + inserts.length; i <= nEnd; i++) {
|
||||
cDst = this._cells[i - 1];
|
||||
cSrc = this._cells[i - nExpand - 1];
|
||||
if (cSrc) {
|
||||
cDst = this.getCell(i);
|
||||
cDst.value = cSrc.value;
|
||||
cDst.style = cSrc.style;
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
cDst._comment = cSrc._comment;
|
||||
} else if (cDst) {
|
||||
cDst.value = null;
|
||||
cDst.style = {};
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
cDst._comment = undefined;
|
||||
}
|
||||
}
|
||||
} else if (nExpand > 0) {
|
||||
// insert new cells
|
||||
for (i = nEnd; i >= nKeep; i--) {
|
||||
cSrc = this._cells[i - 1];
|
||||
if (cSrc) {
|
||||
cDst = this.getCell(i + nExpand);
|
||||
cDst.value = cSrc.value;
|
||||
cDst.style = cSrc.style;
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
cDst._comment = cSrc._comment;
|
||||
} else {
|
||||
this._cells[i + nExpand - 1] = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now add the new values
|
||||
for (i = 0; i < inserts.length; i++) {
|
||||
cDst = this.getCell(start + i);
|
||||
cDst.value = inserts[i];
|
||||
cDst.style = {};
|
||||
// eslint-disable-next-line no-underscore-dangle
|
||||
cDst._comment = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over all non-null cells in this row
|
||||
eachCell(options, iteratee) {
|
||||
if (!iteratee) {
|
||||
iteratee = options;
|
||||
options = null;
|
||||
}
|
||||
if (options && options.includeEmpty) {
|
||||
const n = this._cells.length;
|
||||
for (let i = 1; i <= n; i++) {
|
||||
iteratee(this.getCell(i), i);
|
||||
}
|
||||
} else {
|
||||
this._cells.forEach((cell, index) => {
|
||||
if (cell && cell.type !== Enums.ValueType.Null) {
|
||||
iteratee(cell, index + 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Page Breaks
|
||||
addPageBreak(lft, rght) {
|
||||
const ws = this._worksheet;
|
||||
const left = Math.max(0, lft - 1) || 0;
|
||||
const right = Math.max(0, rght - 1) || 16838;
|
||||
const pb = {
|
||||
id: this._number,
|
||||
max: right,
|
||||
man: 1,
|
||||
};
|
||||
if (left) pb.min = left;
|
||||
|
||||
ws.rowBreaks.push(pb);
|
||||
}
|
||||
|
||||
// return a sparse array of cell values
|
||||
get values() {
|
||||
const values = [];
|
||||
this._cells.forEach(cell => {
|
||||
if (cell && cell.type !== Enums.ValueType.Null) {
|
||||
values[cell.col] = cell.value;
|
||||
}
|
||||
});
|
||||
return values;
|
||||
}
|
||||
|
||||
// set the values by contiguous or sparse array, or by key'd object literal
|
||||
set values(value) {
|
||||
// this operation is not additive - any prior cells are removed
|
||||
this._cells = [];
|
||||
if (!value) {
|
||||
// empty row
|
||||
} else if (value instanceof Array) {
|
||||
let offset = 0;
|
||||
if (value.hasOwnProperty('0')) {
|
||||
// contiguous array - start at column 1
|
||||
offset = 1;
|
||||
}
|
||||
value.forEach((item, index) => {
|
||||
if (item !== undefined) {
|
||||
this.getCellEx({
|
||||
address: colCache.encodeAddress(this._number, index + offset),
|
||||
row: this._number,
|
||||
col: index + offset,
|
||||
}).value = item;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// assume object with column keys
|
||||
this._worksheet.eachColumnKey((column, key) => {
|
||||
if (value[key] !== undefined) {
|
||||
this.getCellEx({
|
||||
address: colCache.encodeAddress(this._number, column.number),
|
||||
row: this._number,
|
||||
col: column.number,
|
||||
}).value = value[key];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// returns true if the row includes at least one cell with a value
|
||||
get hasValues() {
|
||||
return _.some(this._cells, cell => cell && cell.type !== Enums.ValueType.Null);
|
||||
}
|
||||
|
||||
get cellCount() {
|
||||
return this._cells.length;
|
||||
}
|
||||
|
||||
get actualCellCount() {
|
||||
let count = 0;
|
||||
this.eachCell(() => {
|
||||
count++;
|
||||
});
|
||||
return count;
|
||||
}
|
||||
|
||||
// get the min and max column number for the non-null cells in this row or null
|
||||
get dimensions() {
|
||||
let min = 0;
|
||||
let max = 0;
|
||||
this._cells.forEach(cell => {
|
||||
if (cell && cell.type !== Enums.ValueType.Null) {
|
||||
if (!min || min > cell.col) {
|
||||
min = cell.col;
|
||||
}
|
||||
if (max < cell.col) {
|
||||
max = cell.col;
|
||||
}
|
||||
}
|
||||
});
|
||||
return min > 0
|
||||
? {
|
||||
min,
|
||||
max,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// styles
|
||||
_applyStyle(name, value) {
|
||||
this.style[name] = value;
|
||||
this._cells.forEach(cell => {
|
||||
if (cell) {
|
||||
cell[name] = value;
|
||||
}
|
||||
});
|
||||
return value;
|
||||
}
|
||||
|
||||
get numFmt() {
|
||||
return this.style.numFmt;
|
||||
}
|
||||
|
||||
set numFmt(value) {
|
||||
this._applyStyle('numFmt', value);
|
||||
}
|
||||
|
||||
get font() {
|
||||
return this.style.font;
|
||||
}
|
||||
|
||||
set font(value) {
|
||||
this._applyStyle('font', value);
|
||||
}
|
||||
|
||||
get alignment() {
|
||||
return this.style.alignment;
|
||||
}
|
||||
|
||||
set alignment(value) {
|
||||
this._applyStyle('alignment', value);
|
||||
}
|
||||
|
||||
get protection() {
|
||||
return this.style.protection;
|
||||
}
|
||||
|
||||
set protection(value) {
|
||||
this._applyStyle('protection', value);
|
||||
}
|
||||
|
||||
get border() {
|
||||
return this.style.border;
|
||||
}
|
||||
|
||||
set border(value) {
|
||||
this._applyStyle('border', value);
|
||||
}
|
||||
|
||||
get fill() {
|
||||
return this.style.fill;
|
||||
}
|
||||
|
||||
set fill(value) {
|
||||
this._applyStyle('fill', value);
|
||||
}
|
||||
|
||||
get hidden() {
|
||||
return !!this._hidden;
|
||||
}
|
||||
|
||||
set hidden(value) {
|
||||
this._hidden = value;
|
||||
}
|
||||
|
||||
get outlineLevel() {
|
||||
return this._outlineLevel || 0;
|
||||
}
|
||||
|
||||
set outlineLevel(value) {
|
||||
this._outlineLevel = value;
|
||||
}
|
||||
|
||||
get collapsed() {
|
||||
return !!(
|
||||
this._outlineLevel && this._outlineLevel >= this._worksheet.properties.outlineLevelRow
|
||||
);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
get model() {
|
||||
const cells = [];
|
||||
let min = 0;
|
||||
let max = 0;
|
||||
this._cells.forEach(cell => {
|
||||
if (cell) {
|
||||
const cellModel = cell.model;
|
||||
if (cellModel) {
|
||||
if (!min || min > cell.col) {
|
||||
min = cell.col;
|
||||
}
|
||||
if (max < cell.col) {
|
||||
max = cell.col;
|
||||
}
|
||||
cells.push(cellModel);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return this.height || cells.length
|
||||
? {
|
||||
cells,
|
||||
number: this.number,
|
||||
min,
|
||||
max,
|
||||
height: this.height,
|
||||
style: this.style,
|
||||
hidden: this.hidden,
|
||||
outlineLevel: this.outlineLevel,
|
||||
collapsed: this.collapsed,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
set model(value) {
|
||||
if (value.number !== this._number) {
|
||||
throw new Error('Invalid row number in model');
|
||||
}
|
||||
this._cells = [];
|
||||
let previousAddress;
|
||||
value.cells.forEach(cellModel => {
|
||||
switch (cellModel.type) {
|
||||
case Cell.Types.Merge:
|
||||
// special case - don't add this types
|
||||
break;
|
||||
default: {
|
||||
let address;
|
||||
if (cellModel.address) {
|
||||
address = colCache.decodeAddress(cellModel.address);
|
||||
} else if (previousAddress) {
|
||||
// This is a <c> element without an r attribute
|
||||
// Assume that it's the cell for the next column
|
||||
const {row} = previousAddress;
|
||||
const col = previousAddress.col + 1;
|
||||
address = {
|
||||
row,
|
||||
col,
|
||||
address: colCache.encodeAddress(row, col),
|
||||
$col$row: `$${colCache.n2l(col)}$${row}`,
|
||||
};
|
||||
}
|
||||
previousAddress = address;
|
||||
const cell = this.getCellEx(address);
|
||||
cell.model = cellModel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (value.height) {
|
||||
this.height = value.height;
|
||||
} else {
|
||||
delete this.height;
|
||||
}
|
||||
|
||||
this.hidden = value.hidden;
|
||||
this.outlineLevel = value.outlineLevel || 0;
|
||||
|
||||
this.style = (value.style && JSON.parse(JSON.stringify(value.style))) || {};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Row;
|
||||
465
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/table.js
generated
vendored
Normal file
465
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/table.js
generated
vendored
Normal file
@@ -0,0 +1,465 @@
|
||||
/* eslint-disable max-classes-per-file */
|
||||
const colCache = require('../utils/col-cache');
|
||||
|
||||
class Column {
|
||||
// wrapper around column model, allowing access and manipulation
|
||||
constructor(table, column, index) {
|
||||
this.table = table;
|
||||
this.column = column;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
_set(name, value) {
|
||||
this.table.cacheState();
|
||||
this.column[name] = value;
|
||||
}
|
||||
|
||||
/* eslint-disable lines-between-class-members */
|
||||
get name() {
|
||||
return this.column.name;
|
||||
}
|
||||
set name(value) {
|
||||
this._set('name', value);
|
||||
}
|
||||
|
||||
get filterButton() {
|
||||
return this.column.filterButton;
|
||||
}
|
||||
set filterButton(value) {
|
||||
this.column.filterButton = value;
|
||||
}
|
||||
|
||||
get style() {
|
||||
return this.column.style;
|
||||
}
|
||||
set style(value) {
|
||||
this.column.style = value;
|
||||
}
|
||||
|
||||
get totalsRowLabel() {
|
||||
return this.column.totalsRowLabel;
|
||||
}
|
||||
set totalsRowLabel(value) {
|
||||
this._set('totalsRowLabel', value);
|
||||
}
|
||||
|
||||
get totalsRowFunction() {
|
||||
return this.column.totalsRowFunction;
|
||||
}
|
||||
set totalsRowFunction(value) {
|
||||
this._set('totalsRowFunction', value);
|
||||
}
|
||||
|
||||
get totalsRowResult() {
|
||||
return this.column.totalsRowResult;
|
||||
}
|
||||
set totalsRowResult(value) {
|
||||
this._set('totalsRowResult', value);
|
||||
}
|
||||
|
||||
get totalsRowFormula() {
|
||||
return this.column.totalsRowFormula;
|
||||
}
|
||||
set totalsRowFormula(value) {
|
||||
this._set('totalsRowFormula', value);
|
||||
}
|
||||
/* eslint-enable lines-between-class-members */
|
||||
}
|
||||
|
||||
class Table {
|
||||
constructor(worksheet, table) {
|
||||
this.worksheet = worksheet;
|
||||
if (table) {
|
||||
this.table = table;
|
||||
// check things are ok first
|
||||
this.validate();
|
||||
|
||||
this.store();
|
||||
}
|
||||
}
|
||||
|
||||
getFormula(column) {
|
||||
// get the correct formula to apply to the totals row
|
||||
switch (column.totalsRowFunction) {
|
||||
case 'none':
|
||||
return null;
|
||||
case 'average':
|
||||
return `SUBTOTAL(101,${this.table.name}[${column.name}])`;
|
||||
case 'countNums':
|
||||
return `SUBTOTAL(102,${this.table.name}[${column.name}])`;
|
||||
case 'count':
|
||||
return `SUBTOTAL(103,${this.table.name}[${column.name}])`;
|
||||
case 'max':
|
||||
return `SUBTOTAL(104,${this.table.name}[${column.name}])`;
|
||||
case 'min':
|
||||
return `SUBTOTAL(105,${this.table.name}[${column.name}])`;
|
||||
case 'stdDev':
|
||||
return `SUBTOTAL(106,${this.table.name}[${column.name}])`;
|
||||
case 'var':
|
||||
return `SUBTOTAL(107,${this.table.name}[${column.name}])`;
|
||||
case 'sum':
|
||||
return `SUBTOTAL(109,${this.table.name}[${column.name}])`;
|
||||
case 'custom':
|
||||
return column.totalsRowFormula;
|
||||
default:
|
||||
throw new Error(`Invalid Totals Row Function: ${column.totalsRowFunction}`);
|
||||
}
|
||||
}
|
||||
|
||||
get width() {
|
||||
// width of the table
|
||||
return this.table.columns.length;
|
||||
}
|
||||
|
||||
get height() {
|
||||
// height of the table data
|
||||
return this.table.rows.length;
|
||||
}
|
||||
|
||||
get filterHeight() {
|
||||
// height of the table data plus optional header row
|
||||
return this.height + (this.table.headerRow ? 1 : 0);
|
||||
}
|
||||
|
||||
get tableHeight() {
|
||||
// full height of the table on the sheet
|
||||
return this.filterHeight + (this.table.totalsRow ? 1 : 0);
|
||||
}
|
||||
|
||||
validate() {
|
||||
const {table} = this;
|
||||
// set defaults and check is valid
|
||||
const assign = (o, name, dflt) => {
|
||||
if (o[name] === undefined) {
|
||||
o[name] = dflt;
|
||||
}
|
||||
};
|
||||
assign(table, 'headerRow', true);
|
||||
assign(table, 'totalsRow', false);
|
||||
|
||||
assign(table, 'style', {});
|
||||
assign(table.style, 'theme', 'TableStyleMedium2');
|
||||
assign(table.style, 'showFirstColumn', false);
|
||||
assign(table.style, 'showLastColumn', false);
|
||||
assign(table.style, 'showRowStripes', false);
|
||||
assign(table.style, 'showColumnStripes', false);
|
||||
|
||||
const assert = (test, message) => {
|
||||
if (!test) {
|
||||
throw new Error(message);
|
||||
}
|
||||
};
|
||||
assert(table.ref, 'Table must have ref');
|
||||
assert(table.columns, 'Table must have column definitions');
|
||||
assert(table.rows, 'Table must have row definitions');
|
||||
|
||||
table.tl = colCache.decodeAddress(table.ref);
|
||||
const {row, col} = table.tl;
|
||||
assert(row > 0, 'Table must be on valid row');
|
||||
assert(col > 0, 'Table must be on valid col');
|
||||
|
||||
const {width, filterHeight, tableHeight} = this;
|
||||
|
||||
// autoFilterRef is a range that includes optional headers only
|
||||
table.autoFilterRef = colCache.encode(row, col, row + filterHeight - 1, col + width - 1);
|
||||
|
||||
// tableRef is a range that includes optional headers and totals
|
||||
table.tableRef = colCache.encode(row, col, row + tableHeight - 1, col + width - 1);
|
||||
|
||||
table.columns.forEach((column, i) => {
|
||||
assert(column.name, `Column ${i} must have a name`);
|
||||
if (i === 0) {
|
||||
assign(column, 'totalsRowLabel', 'Total');
|
||||
} else {
|
||||
assign(column, 'totalsRowFunction', 'none');
|
||||
column.totalsRowFormula = this.getFormula(column);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
store() {
|
||||
// where the table needs to store table data, headers, footers in
|
||||
// the sheet...
|
||||
const assignStyle = (cell, style) => {
|
||||
if (style) {
|
||||
Object.keys(style).forEach(key => {
|
||||
cell[key] = style[key];
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const {worksheet, table} = this;
|
||||
const {row, col} = table.tl;
|
||||
let count = 0;
|
||||
if (table.headerRow) {
|
||||
const r = worksheet.getRow(row + count++);
|
||||
table.columns.forEach((column, j) => {
|
||||
const {style, name} = column;
|
||||
const cell = r.getCell(col + j);
|
||||
cell.value = name;
|
||||
assignStyle(cell, style);
|
||||
});
|
||||
}
|
||||
table.rows.forEach(data => {
|
||||
const r = worksheet.getRow(row + count++);
|
||||
data.forEach((value, j) => {
|
||||
const cell = r.getCell(col + j);
|
||||
cell.value = value;
|
||||
|
||||
assignStyle(cell, table.columns[j].style);
|
||||
});
|
||||
});
|
||||
|
||||
if (table.totalsRow) {
|
||||
const r = worksheet.getRow(row + count++);
|
||||
table.columns.forEach((column, j) => {
|
||||
const cell = r.getCell(col + j);
|
||||
if (j === 0) {
|
||||
cell.value = column.totalsRowLabel;
|
||||
} else {
|
||||
const formula = this.getFormula(column);
|
||||
if (formula) {
|
||||
cell.value = {
|
||||
formula: column.totalsRowFormula,
|
||||
result: column.totalsRowResult,
|
||||
};
|
||||
} else {
|
||||
cell.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
assignStyle(cell, column.style);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
load(worksheet) {
|
||||
// where the table will read necessary features from a loaded sheet
|
||||
const {table} = this;
|
||||
const {row, col} = table.tl;
|
||||
let count = 0;
|
||||
if (table.headerRow) {
|
||||
const r = worksheet.getRow(row + count++);
|
||||
table.columns.forEach((column, j) => {
|
||||
const cell = r.getCell(col + j);
|
||||
cell.value = column.name;
|
||||
});
|
||||
}
|
||||
table.rows.forEach(data => {
|
||||
const r = worksheet.getRow(row + count++);
|
||||
data.forEach((value, j) => {
|
||||
const cell = r.getCell(col + j);
|
||||
cell.value = value;
|
||||
});
|
||||
});
|
||||
|
||||
if (table.totalsRow) {
|
||||
const r = worksheet.getRow(row + count++);
|
||||
table.columns.forEach((column, j) => {
|
||||
const cell = r.getCell(col + j);
|
||||
if (j === 0) {
|
||||
cell.value = column.totalsRowLabel;
|
||||
} else {
|
||||
const formula = this.getFormula(column);
|
||||
if (formula) {
|
||||
cell.value = {
|
||||
formula: column.totalsRowFormula,
|
||||
result: column.totalsRowResult,
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get model() {
|
||||
return this.table;
|
||||
}
|
||||
|
||||
set model(value) {
|
||||
this.table = value;
|
||||
}
|
||||
|
||||
// ================================================================
|
||||
// TODO: Mutating methods
|
||||
cacheState() {
|
||||
if (!this._cache) {
|
||||
this._cache = {
|
||||
ref: this.ref,
|
||||
width: this.width,
|
||||
tableHeight: this.tableHeight,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
commit() {
|
||||
// changes may have been made that might have on-sheet effects
|
||||
if (!this._cache) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check things are ok first
|
||||
this.validate();
|
||||
|
||||
const ref = colCache.decodeAddress(this._cache.ref);
|
||||
if (this.ref !== this._cache.ref) {
|
||||
// wipe out whole table footprint at previous location
|
||||
for (let i = 0; i < this._cache.tableHeight; i++) {
|
||||
const row = this.worksheet.getRow(ref.row + i);
|
||||
for (let j = 0; j < this._cache.width; j++) {
|
||||
const cell = row.getCell(ref.col + j);
|
||||
cell.value = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// clear out below table if it has shrunk
|
||||
for (let i = this.tableHeight; i < this._cache.tableHeight; i++) {
|
||||
const row = this.worksheet.getRow(ref.row + i);
|
||||
for (let j = 0; j < this._cache.width; j++) {
|
||||
const cell = row.getCell(ref.col + j);
|
||||
cell.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
// clear out to right of table if it has lost columns
|
||||
for (let i = 0; i < this.tableHeight; i++) {
|
||||
const row = this.worksheet.getRow(ref.row + i);
|
||||
for (let j = this.width; j < this._cache.width; j++) {
|
||||
const cell = row.getCell(ref.col + j);
|
||||
cell.value = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.store();
|
||||
}
|
||||
|
||||
addRow(values, rowNumber) {
|
||||
// Add a row of data, either insert at rowNumber or append
|
||||
this.cacheState();
|
||||
|
||||
if (rowNumber === undefined) {
|
||||
this.table.rows.push(values);
|
||||
} else {
|
||||
this.table.rows.splice(rowNumber, 0, values);
|
||||
}
|
||||
}
|
||||
|
||||
removeRows(rowIndex, count = 1) {
|
||||
// Remove a rows of data
|
||||
this.cacheState();
|
||||
this.table.rows.splice(rowIndex, count);
|
||||
}
|
||||
|
||||
getColumn(colIndex) {
|
||||
const column = this.table.columns[colIndex];
|
||||
return new Column(this, column, colIndex);
|
||||
}
|
||||
|
||||
addColumn(column, values, colIndex) {
|
||||
// Add a new column, including column defn and values
|
||||
// Inserts at colNumber or adds to the right
|
||||
this.cacheState();
|
||||
|
||||
if (colIndex === undefined) {
|
||||
this.table.columns.push(column);
|
||||
this.table.rows.forEach((row, i) => {
|
||||
row.push(values[i]);
|
||||
});
|
||||
} else {
|
||||
this.table.columns.splice(colIndex, 0, column);
|
||||
this.table.rows.forEach((row, i) => {
|
||||
row.splice(colIndex, 0, values[i]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
removeColumns(colIndex, count = 1) {
|
||||
// Remove a column with data
|
||||
this.cacheState();
|
||||
|
||||
this.table.columns.splice(colIndex, count);
|
||||
this.table.rows.forEach(row => {
|
||||
row.splice(colIndex, count);
|
||||
});
|
||||
}
|
||||
|
||||
_assign(target, prop, value) {
|
||||
this.cacheState();
|
||||
target[prop] = value;
|
||||
}
|
||||
|
||||
/* eslint-disable lines-between-class-members */
|
||||
get ref() {
|
||||
return this.table.ref;
|
||||
}
|
||||
set ref(value) {
|
||||
this._assign(this.table, 'ref', value);
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this.table.name;
|
||||
}
|
||||
set name(value) {
|
||||
this.table.name = value;
|
||||
}
|
||||
|
||||
get displayName() {
|
||||
return this.table.displyName || this.table.name;
|
||||
}
|
||||
set displayNamename(value) {
|
||||
this.table.displayName = value;
|
||||
}
|
||||
|
||||
get headerRow() {
|
||||
return this.table.headerRow;
|
||||
}
|
||||
set headerRow(value) {
|
||||
this._assign(this.table, 'headerRow', value);
|
||||
}
|
||||
|
||||
get totalsRow() {
|
||||
return this.table.totalsRow;
|
||||
}
|
||||
set totalsRow(value) {
|
||||
this._assign(this.table, 'totalsRow', value);
|
||||
}
|
||||
|
||||
get theme() {
|
||||
return this.table.style.name;
|
||||
}
|
||||
set theme(value) {
|
||||
this.table.style.name = value;
|
||||
}
|
||||
|
||||
get showFirstColumn() {
|
||||
return this.table.style.showFirstColumn;
|
||||
}
|
||||
set showFirstColumn(value) {
|
||||
this.table.style.showFirstColumn = value;
|
||||
}
|
||||
|
||||
get showLastColumn() {
|
||||
return this.table.style.showLastColumn;
|
||||
}
|
||||
set showLastColumn(value) {
|
||||
this.table.style.showLastColumn = value;
|
||||
}
|
||||
|
||||
get showRowStripes() {
|
||||
return this.table.style.showRowStripes;
|
||||
}
|
||||
set showRowStripes(value) {
|
||||
this.table.style.showRowStripes = value;
|
||||
}
|
||||
|
||||
get showColumnStripes() {
|
||||
return this.table.style.showColumnStripes;
|
||||
}
|
||||
set showColumnStripes(value) {
|
||||
this.table.style.showColumnStripes = value;
|
||||
}
|
||||
/* eslint-enable lines-between-class-members */
|
||||
}
|
||||
|
||||
module.exports = Table;
|
||||
221
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/workbook.js
generated
vendored
Normal file
221
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/workbook.js
generated
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
'use strict';
|
||||
|
||||
const Worksheet = require('./worksheet');
|
||||
const DefinedNames = require('./defined-names');
|
||||
const XLSX = require('../xlsx/xlsx');
|
||||
const CSV = require('../csv/csv');
|
||||
|
||||
// Workbook requirements
|
||||
// Load and Save from file and stream
|
||||
// Access/Add/Delete individual worksheets
|
||||
// Manage String table, Hyperlink table, etc.
|
||||
// Manage scaffolding for contained objects to write to/read from
|
||||
|
||||
class Workbook {
|
||||
constructor() {
|
||||
this.category = '';
|
||||
this.company = '';
|
||||
this.created = new Date();
|
||||
this.description = '';
|
||||
this.keywords = '';
|
||||
this.manager = '';
|
||||
this.modified = this.created;
|
||||
this.properties = {};
|
||||
this.calcProperties = {};
|
||||
this._worksheets = [];
|
||||
this.subject = '';
|
||||
this.title = '';
|
||||
this.views = [];
|
||||
this.media = [];
|
||||
this._definedNames = new DefinedNames();
|
||||
}
|
||||
|
||||
get xlsx() {
|
||||
if (!this._xlsx) this._xlsx = new XLSX(this);
|
||||
return this._xlsx;
|
||||
}
|
||||
|
||||
get csv() {
|
||||
if (!this._csv) this._csv = new CSV(this);
|
||||
return this._csv;
|
||||
}
|
||||
|
||||
get nextId() {
|
||||
// find the next unique spot to add worksheet
|
||||
for (let i = 1; i < this._worksheets.length; i++) {
|
||||
if (!this._worksheets[i]) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return this._worksheets.length || 1;
|
||||
}
|
||||
|
||||
addWorksheet(name, options) {
|
||||
const id = this.nextId;
|
||||
|
||||
// if options is a color, call it tabColor (and signal deprecated message)
|
||||
if (options) {
|
||||
if (typeof options === 'string') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.trace(
|
||||
'tabColor argument is now deprecated. Please use workbook.addWorksheet(name, {properties: { tabColor: { argb: "rbg value" } }'
|
||||
);
|
||||
options = {
|
||||
properties: {
|
||||
tabColor: {argb: options},
|
||||
},
|
||||
};
|
||||
} else if (options.argb || options.theme || options.indexed) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.trace(
|
||||
'tabColor argument is now deprecated. Please use workbook.addWorksheet(name, {properties: { tabColor: { ... } }'
|
||||
);
|
||||
options = {
|
||||
properties: {
|
||||
tabColor: options,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const lastOrderNo = this._worksheets.reduce((acc, ws) => ((ws && ws.orderNo) > acc ? ws.orderNo : acc), 0);
|
||||
const worksheetOptions = Object.assign({}, options, {
|
||||
id,
|
||||
name,
|
||||
orderNo: lastOrderNo + 1,
|
||||
workbook: this,
|
||||
});
|
||||
|
||||
const worksheet = new Worksheet(worksheetOptions);
|
||||
|
||||
this._worksheets[id] = worksheet;
|
||||
return worksheet;
|
||||
}
|
||||
|
||||
removeWorksheetEx(worksheet) {
|
||||
delete this._worksheets[worksheet.id];
|
||||
}
|
||||
|
||||
removeWorksheet(id) {
|
||||
const worksheet = this.getWorksheet(id);
|
||||
if (worksheet) {
|
||||
worksheet.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
getWorksheet(id) {
|
||||
if (id === undefined) {
|
||||
return this._worksheets.find(Boolean);
|
||||
}
|
||||
if (typeof id === 'number') {
|
||||
return this._worksheets[id];
|
||||
}
|
||||
if (typeof id === 'string') {
|
||||
return this._worksheets.find(worksheet => worksheet && worksheet.name === id);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
get worksheets() {
|
||||
// return a clone of _worksheets
|
||||
return this._worksheets
|
||||
.slice(1)
|
||||
.sort((a, b) => a.orderNo - b.orderNo)
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
eachSheet(iteratee) {
|
||||
this.worksheets.forEach(sheet => {
|
||||
iteratee(sheet, sheet.id);
|
||||
});
|
||||
}
|
||||
|
||||
get definedNames() {
|
||||
return this._definedNames;
|
||||
}
|
||||
|
||||
clearThemes() {
|
||||
// Note: themes are not an exposed feature, meddle at your peril!
|
||||
this._themes = undefined;
|
||||
}
|
||||
|
||||
addImage(image) {
|
||||
// TODO: validation?
|
||||
const id = this.media.length;
|
||||
this.media.push(Object.assign({}, image, {type: 'image'}));
|
||||
return id;
|
||||
}
|
||||
|
||||
getImage(id) {
|
||||
return this.media[id];
|
||||
}
|
||||
|
||||
get model() {
|
||||
return {
|
||||
creator: this.creator || 'Unknown',
|
||||
lastModifiedBy: this.lastModifiedBy || 'Unknown',
|
||||
lastPrinted: this.lastPrinted,
|
||||
created: this.created,
|
||||
modified: this.modified,
|
||||
properties: this.properties,
|
||||
worksheets: this.worksheets.map(worksheet => worksheet.model),
|
||||
sheets: this.worksheets.map(ws => ws.model).filter(Boolean),
|
||||
definedNames: this._definedNames.model,
|
||||
views: this.views,
|
||||
company: this.company,
|
||||
manager: this.manager,
|
||||
title: this.title,
|
||||
subject: this.subject,
|
||||
keywords: this.keywords,
|
||||
category: this.category,
|
||||
description: this.description,
|
||||
language: this.language,
|
||||
revision: this.revision,
|
||||
contentStatus: this.contentStatus,
|
||||
themes: this._themes,
|
||||
media: this.media,
|
||||
calcProperties: this.calcProperties,
|
||||
};
|
||||
}
|
||||
|
||||
set model(value) {
|
||||
this.creator = value.creator;
|
||||
this.lastModifiedBy = value.lastModifiedBy;
|
||||
this.lastPrinted = value.lastPrinted;
|
||||
this.created = value.created;
|
||||
this.modified = value.modified;
|
||||
this.company = value.company;
|
||||
this.manager = value.manager;
|
||||
this.title = value.title;
|
||||
this.subject = value.subject;
|
||||
this.keywords = value.keywords;
|
||||
this.category = value.category;
|
||||
this.description = value.description;
|
||||
this.language = value.language;
|
||||
this.revision = value.revision;
|
||||
this.contentStatus = value.contentStatus;
|
||||
|
||||
this.properties = value.properties;
|
||||
this.calcProperties = value.calcProperties;
|
||||
this._worksheets = [];
|
||||
value.worksheets.forEach(worksheetModel => {
|
||||
const {id, name, state} = worksheetModel;
|
||||
const orderNo = value.sheets && value.sheets.findIndex(ws => ws.id === id);
|
||||
const worksheet = (this._worksheets[id] = new Worksheet({
|
||||
id,
|
||||
name,
|
||||
orderNo,
|
||||
state,
|
||||
workbook: this,
|
||||
}));
|
||||
worksheet.model = worksheetModel;
|
||||
});
|
||||
|
||||
this._definedNames.model = value.definedNames;
|
||||
this.views = value.views;
|
||||
this._themes = value.themes;
|
||||
this.media = value.media || [];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Workbook;
|
||||
927
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/worksheet.js
generated
vendored
Normal file
927
doc/test-data/purchase_transaction/node_modules/exceljs/lib/doc/worksheet.js
generated
vendored
Normal file
@@ -0,0 +1,927 @@
|
||||
const _ = require('../utils/under-dash');
|
||||
|
||||
const colCache = require('../utils/col-cache');
|
||||
const Range = require('./range');
|
||||
const Row = require('./row');
|
||||
const Column = require('./column');
|
||||
const Enums = require('./enums');
|
||||
const Image = require('./image');
|
||||
const Table = require('./table');
|
||||
const DataValidations = require('./data-validations');
|
||||
const Encryptor = require('../utils/encryptor');
|
||||
const {copyStyle} = require('../utils/copy-style');
|
||||
|
||||
// Worksheet requirements
|
||||
// Operate as sheet inside workbook or standalone
|
||||
// Load and Save from file and stream
|
||||
// Access/Add/Delete individual cells
|
||||
// Manage column widths and row heights
|
||||
|
||||
class Worksheet {
|
||||
constructor(options) {
|
||||
options = options || {};
|
||||
this._workbook = options.workbook;
|
||||
|
||||
// in a workbook, each sheet will have a number
|
||||
this.id = options.id;
|
||||
this.orderNo = options.orderNo;
|
||||
|
||||
// and a name
|
||||
this.name = options.name;
|
||||
|
||||
// add a state
|
||||
this.state = options.state || 'visible';
|
||||
|
||||
// rows allows access organised by row. Sparse array of arrays indexed by row-1, col
|
||||
// Note: _rows is zero based. Must subtract 1 to go from cell.row to index
|
||||
this._rows = [];
|
||||
|
||||
// column definitions
|
||||
this._columns = null;
|
||||
|
||||
// column keys (addRow convenience): key ==> this._collumns index
|
||||
this._keys = {};
|
||||
|
||||
// keep record of all merges
|
||||
this._merges = {};
|
||||
|
||||
// record of all row and column pageBreaks
|
||||
this.rowBreaks = [];
|
||||
|
||||
// for tabColor, default row height, outline levels, etc
|
||||
this.properties = Object.assign(
|
||||
{},
|
||||
{
|
||||
defaultRowHeight: 15,
|
||||
dyDescent: 55,
|
||||
outlineLevelCol: 0,
|
||||
outlineLevelRow: 0,
|
||||
},
|
||||
options.properties
|
||||
);
|
||||
|
||||
// for all things printing
|
||||
this.pageSetup = Object.assign(
|
||||
{},
|
||||
{
|
||||
margins: {left: 0.7, right: 0.7, top: 0.75, bottom: 0.75, header: 0.3, footer: 0.3},
|
||||
orientation: 'portrait',
|
||||
horizontalDpi: 4294967295,
|
||||
verticalDpi: 4294967295,
|
||||
fitToPage: !!(
|
||||
options.pageSetup &&
|
||||
(options.pageSetup.fitToWidth || options.pageSetup.fitToHeight) &&
|
||||
!options.pageSetup.scale
|
||||
),
|
||||
pageOrder: 'downThenOver',
|
||||
blackAndWhite: false,
|
||||
draft: false,
|
||||
cellComments: 'None',
|
||||
errors: 'displayed',
|
||||
scale: 100,
|
||||
fitToWidth: 1,
|
||||
fitToHeight: 1,
|
||||
paperSize: undefined,
|
||||
showRowColHeaders: false,
|
||||
showGridLines: false,
|
||||
firstPageNumber: undefined,
|
||||
horizontalCentered: false,
|
||||
verticalCentered: false,
|
||||
rowBreaks: null,
|
||||
colBreaks: null,
|
||||
},
|
||||
options.pageSetup
|
||||
);
|
||||
|
||||
this.headerFooter = Object.assign(
|
||||
{},
|
||||
{
|
||||
differentFirst: false,
|
||||
differentOddEven: false,
|
||||
oddHeader: null,
|
||||
oddFooter: null,
|
||||
evenHeader: null,
|
||||
evenFooter: null,
|
||||
firstHeader: null,
|
||||
firstFooter: null,
|
||||
},
|
||||
options.headerFooter
|
||||
);
|
||||
|
||||
this.dataValidations = new DataValidations();
|
||||
|
||||
// for freezepanes, split, zoom, gridlines, etc
|
||||
this.views = options.views || [];
|
||||
|
||||
this.autoFilter = options.autoFilter || null;
|
||||
|
||||
// for images, etc
|
||||
this._media = [];
|
||||
|
||||
// worksheet protection
|
||||
this.sheetProtection = null;
|
||||
|
||||
// for tables
|
||||
this.tables = {};
|
||||
|
||||
this.conditionalFormattings = [];
|
||||
}
|
||||
|
||||
get name() {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
set name(name) {
|
||||
if (name === undefined) {
|
||||
name = `sheet${this.id}`;
|
||||
}
|
||||
|
||||
if (this._name === name) return;
|
||||
|
||||
if (typeof name !== 'string') {
|
||||
throw new Error('The name has to be a string.');
|
||||
}
|
||||
|
||||
if (name === '') {
|
||||
throw new Error('The name can\'t be empty.');
|
||||
}
|
||||
|
||||
if (name === 'History') {
|
||||
throw new Error('The name "History" is protected. Please use a different name.');
|
||||
}
|
||||
|
||||
// Illegal character in worksheet name: asterisk (*), question mark (?),
|
||||
// colon (:), forward slash (/ \), or bracket ([])
|
||||
if (/[*?:/\\[\]]/.test(name)) {
|
||||
throw new Error(`Worksheet name ${name} cannot include any of the following characters: * ? : \\ / [ ]`);
|
||||
}
|
||||
|
||||
if (/(^')|('$)/.test(name)) {
|
||||
throw new Error(`The first or last character of worksheet name cannot be a single quotation mark: ${name}`);
|
||||
}
|
||||
|
||||
if (name && name.length > 31) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(`Worksheet name ${name} exceeds 31 chars. This will be truncated`);
|
||||
name = name.substring(0, 31);
|
||||
}
|
||||
|
||||
if (this._workbook._worksheets.find(ws => ws && ws.name.toLowerCase() === name.toLowerCase())) {
|
||||
throw new Error(`Worksheet name already exists: ${name}`);
|
||||
}
|
||||
|
||||
this._name = name;
|
||||
}
|
||||
|
||||
get workbook() {
|
||||
return this._workbook;
|
||||
}
|
||||
|
||||
// when you're done with this worksheet, call this to remove from workbook
|
||||
destroy() {
|
||||
this._workbook.removeWorksheetEx(this);
|
||||
}
|
||||
|
||||
// Get the bounding range of the cells in this worksheet
|
||||
get dimensions() {
|
||||
const dimensions = new Range();
|
||||
this._rows.forEach(row => {
|
||||
if (row) {
|
||||
const rowDims = row.dimensions;
|
||||
if (rowDims) {
|
||||
dimensions.expand(row.number, rowDims.min, row.number, rowDims.max);
|
||||
}
|
||||
}
|
||||
});
|
||||
return dimensions;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Columns
|
||||
|
||||
// get the current columns array.
|
||||
get columns() {
|
||||
return this._columns;
|
||||
}
|
||||
|
||||
// set the columns from an array of column definitions.
|
||||
// Note: any headers defined will overwrite existing values.
|
||||
set columns(value) {
|
||||
// calculate max header row count
|
||||
this._headerRowCount = value.reduce((pv, cv) => {
|
||||
const headerCount = (cv.header && 1) || (cv.headers && cv.headers.length) || 0;
|
||||
return Math.max(pv, headerCount);
|
||||
}, 0);
|
||||
|
||||
// construct Column objects
|
||||
let count = 1;
|
||||
const columns = (this._columns = []);
|
||||
value.forEach(defn => {
|
||||
const column = new Column(this, count++, false);
|
||||
columns.push(column);
|
||||
column.defn = defn;
|
||||
});
|
||||
}
|
||||
|
||||
getColumnKey(key) {
|
||||
return this._keys[key];
|
||||
}
|
||||
|
||||
setColumnKey(key, value) {
|
||||
this._keys[key] = value;
|
||||
}
|
||||
|
||||
deleteColumnKey(key) {
|
||||
delete this._keys[key];
|
||||
}
|
||||
|
||||
eachColumnKey(f) {
|
||||
_.each(this._keys, f);
|
||||
}
|
||||
|
||||
// get a single column by col number. If it doesn't exist, create it and any gaps before it
|
||||
getColumn(c) {
|
||||
if (typeof c === 'string') {
|
||||
// if it matches a key'd column, return that
|
||||
const col = this._keys[c];
|
||||
if (col) return col;
|
||||
|
||||
// otherwise, assume letter
|
||||
c = colCache.l2n(c);
|
||||
}
|
||||
if (!this._columns) {
|
||||
this._columns = [];
|
||||
}
|
||||
if (c > this._columns.length) {
|
||||
let n = this._columns.length + 1;
|
||||
while (n <= c) {
|
||||
this._columns.push(new Column(this, n++));
|
||||
}
|
||||
}
|
||||
return this._columns[c - 1];
|
||||
}
|
||||
|
||||
spliceColumns(start, count, ...inserts) {
|
||||
const rows = this._rows;
|
||||
const nRows = rows.length;
|
||||
if (inserts.length > 0) {
|
||||
// must iterate over all rows whether they exist yet or not
|
||||
for (let i = 0; i < nRows; i++) {
|
||||
const rowArguments = [start, count];
|
||||
// eslint-disable-next-line no-loop-func
|
||||
inserts.forEach(insert => {
|
||||
rowArguments.push(insert[i] || null);
|
||||
});
|
||||
const row = this.getRow(i + 1);
|
||||
// eslint-disable-next-line prefer-spread
|
||||
row.splice.apply(row, rowArguments);
|
||||
}
|
||||
} else {
|
||||
// nothing to insert, so just splice all rows
|
||||
this._rows.forEach(r => {
|
||||
if (r) {
|
||||
r.splice(start, count);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// splice column definitions
|
||||
const nExpand = inserts.length - count;
|
||||
const nKeep = start + count;
|
||||
const nEnd = this._columns.length;
|
||||
if (nExpand < 0) {
|
||||
for (let i = start + inserts.length; i <= nEnd; i++) {
|
||||
this.getColumn(i).defn = this.getColumn(i - nExpand).defn;
|
||||
}
|
||||
} else if (nExpand > 0) {
|
||||
for (let i = nEnd; i >= nKeep; i--) {
|
||||
this.getColumn(i + nExpand).defn = this.getColumn(i).defn;
|
||||
}
|
||||
}
|
||||
for (let i = start; i < start + inserts.length; i++) {
|
||||
this.getColumn(i).defn = null;
|
||||
}
|
||||
|
||||
// account for defined names
|
||||
this.workbook.definedNames.spliceColumns(this.name, start, count, inserts.length);
|
||||
}
|
||||
|
||||
get lastColumn() {
|
||||
return this.getColumn(this.columnCount);
|
||||
}
|
||||
|
||||
get columnCount() {
|
||||
let maxCount = 0;
|
||||
this.eachRow(row => {
|
||||
maxCount = Math.max(maxCount, row.cellCount);
|
||||
});
|
||||
return maxCount;
|
||||
}
|
||||
|
||||
get actualColumnCount() {
|
||||
// performance nightmare - for each row, counts all the columns used
|
||||
const counts = [];
|
||||
let count = 0;
|
||||
this.eachRow(row => {
|
||||
row.eachCell(({col}) => {
|
||||
if (!counts[col]) {
|
||||
counts[col] = true;
|
||||
count++;
|
||||
}
|
||||
});
|
||||
});
|
||||
return count;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Rows
|
||||
|
||||
_commitRow() {
|
||||
// nop - allows streaming reader to fill a document
|
||||
}
|
||||
|
||||
get _lastRowNumber() {
|
||||
// need to cope with results of splice
|
||||
const rows = this._rows;
|
||||
let n = rows.length;
|
||||
while (n > 0 && rows[n - 1] === undefined) {
|
||||
n--;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
get _nextRow() {
|
||||
return this._lastRowNumber + 1;
|
||||
}
|
||||
|
||||
get lastRow() {
|
||||
if (this._rows.length) {
|
||||
return this._rows[this._rows.length - 1];
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// find a row (if exists) by row number
|
||||
findRow(r) {
|
||||
return this._rows[r - 1];
|
||||
}
|
||||
|
||||
// find multiple rows (if exists) by row number
|
||||
findRows(start, length) {
|
||||
return this._rows.slice(start - 1, start - 1 + length);
|
||||
}
|
||||
|
||||
get rowCount() {
|
||||
return this._lastRowNumber;
|
||||
}
|
||||
|
||||
get actualRowCount() {
|
||||
// counts actual rows that have actual data
|
||||
let count = 0;
|
||||
this.eachRow(() => {
|
||||
count++;
|
||||
});
|
||||
return count;
|
||||
}
|
||||
|
||||
// get a row by row number.
|
||||
getRow(r) {
|
||||
let row = this._rows[r - 1];
|
||||
if (!row) {
|
||||
row = this._rows[r - 1] = new Row(this, r);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
// get multiple rows by row number.
|
||||
getRows(start, length) {
|
||||
if (length < 1) return undefined;
|
||||
const rows = [];
|
||||
for (let i = start; i < start + length; i++) {
|
||||
rows.push(this.getRow(i));
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
addRow(value, style = 'n') {
|
||||
const rowNo = this._nextRow;
|
||||
const row = this.getRow(rowNo);
|
||||
row.values = value;
|
||||
this._setStyleOption(rowNo, style[0] === 'i' ? style : 'n');
|
||||
return row;
|
||||
}
|
||||
|
||||
addRows(value, style = 'n') {
|
||||
const rows = [];
|
||||
value.forEach(row => {
|
||||
rows.push(this.addRow(row, style));
|
||||
});
|
||||
return rows;
|
||||
}
|
||||
|
||||
insertRow(pos, value, style = 'n') {
|
||||
this.spliceRows(pos, 0, value);
|
||||
this._setStyleOption(pos, style);
|
||||
return this.getRow(pos);
|
||||
}
|
||||
|
||||
insertRows(pos, values, style = 'n') {
|
||||
this.spliceRows(pos, 0, ...values);
|
||||
if (style !== 'n') {
|
||||
// copy over the styles
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
if (style[0] === 'o' && this.findRow(values.length + pos + i) !== undefined) {
|
||||
this._copyStyle(values.length + pos + i, pos + i, style[1] === '+');
|
||||
} else if (style[0] === 'i' && this.findRow(pos - 1) !== undefined) {
|
||||
this._copyStyle(pos - 1, pos + i, style[1] === '+');
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.getRows(pos, values.length);
|
||||
}
|
||||
|
||||
// set row at position to same style as of either pervious row (option 'i') or next row (option 'o')
|
||||
_setStyleOption(pos, style = 'n') {
|
||||
if (style[0] === 'o' && this.findRow(pos + 1) !== undefined) {
|
||||
this._copyStyle(pos + 1, pos, style[1] === '+');
|
||||
} else if (style[0] === 'i' && this.findRow(pos - 1) !== undefined) {
|
||||
this._copyStyle(pos - 1, pos, style[1] === '+');
|
||||
}
|
||||
}
|
||||
|
||||
_copyStyle(src, dest, styleEmpty = false) {
|
||||
const rSrc = this.getRow(src);
|
||||
const rDst = this.getRow(dest);
|
||||
rDst.style = copyStyle(rSrc.style);
|
||||
// eslint-disable-next-line no-loop-func
|
||||
rSrc.eachCell({includeEmpty: styleEmpty}, (cell, colNumber) => {
|
||||
rDst.getCell(colNumber).style = copyStyle(cell.style);
|
||||
});
|
||||
rDst.height = rSrc.height;
|
||||
}
|
||||
|
||||
duplicateRow(rowNum, count, insert = false) {
|
||||
// create count duplicates of rowNum
|
||||
// either inserting new or overwriting existing rows
|
||||
|
||||
const rSrc = this._rows[rowNum - 1];
|
||||
const inserts = new Array(count).fill(rSrc.values);
|
||||
this.spliceRows(rowNum + 1, insert ? 0 : count, ...inserts);
|
||||
|
||||
// now copy styles...
|
||||
for (let i = 0; i < count; i++) {
|
||||
const rDst = this._rows[rowNum + i];
|
||||
rDst.style = rSrc.style;
|
||||
rDst.height = rSrc.height;
|
||||
// eslint-disable-next-line no-loop-func
|
||||
rSrc.eachCell({includeEmpty: true}, (cell, colNumber) => {
|
||||
rDst.getCell(colNumber).style = cell.style;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
spliceRows(start, count, ...inserts) {
|
||||
// same problem as row.splice, except worse.
|
||||
const nKeep = start + count;
|
||||
const nInserts = inserts.length;
|
||||
const nExpand = nInserts - count;
|
||||
const nEnd = this._rows.length;
|
||||
let i;
|
||||
let rSrc;
|
||||
if (nExpand < 0) {
|
||||
// remove rows
|
||||
if (start === nEnd) {
|
||||
this._rows[nEnd - 1] = undefined;
|
||||
}
|
||||
for (i = nKeep; i <= nEnd; i++) {
|
||||
rSrc = this._rows[i - 1];
|
||||
if (rSrc) {
|
||||
const rDst = this.getRow(i + nExpand);
|
||||
rDst.values = rSrc.values;
|
||||
rDst.style = rSrc.style;
|
||||
rDst.height = rSrc.height;
|
||||
// eslint-disable-next-line no-loop-func
|
||||
rSrc.eachCell({includeEmpty: true}, (cell, colNumber) => {
|
||||
rDst.getCell(colNumber).style = cell.style;
|
||||
});
|
||||
this._rows[i - 1] = undefined;
|
||||
} else {
|
||||
this._rows[i + nExpand - 1] = undefined;
|
||||
}
|
||||
}
|
||||
} else if (nExpand > 0) {
|
||||
// insert new cells
|
||||
for (i = nEnd; i >= nKeep; i--) {
|
||||
rSrc = this._rows[i - 1];
|
||||
if (rSrc) {
|
||||
const rDst = this.getRow(i + nExpand);
|
||||
rDst.values = rSrc.values;
|
||||
rDst.style = rSrc.style;
|
||||
rDst.height = rSrc.height;
|
||||
// eslint-disable-next-line no-loop-func
|
||||
rSrc.eachCell({includeEmpty: true}, (cell, colNumber) => {
|
||||
rDst.getCell(colNumber).style = cell.style;
|
||||
|
||||
// remerge cells accounting for insert offset
|
||||
if (cell._value.constructor.name === 'MergeValue') {
|
||||
const cellToBeMerged = this.getRow(cell._row._number + nInserts).getCell(colNumber);
|
||||
const prevMaster = cell._value._master;
|
||||
const newMaster = this.getRow(prevMaster._row._number + nInserts).getCell(prevMaster._column._number);
|
||||
cellToBeMerged.merge(newMaster);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this._rows[i + nExpand - 1] = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now copy over the new values
|
||||
for (i = 0; i < nInserts; i++) {
|
||||
const rDst = this.getRow(start + i);
|
||||
rDst.style = {};
|
||||
rDst.values = inserts[i];
|
||||
}
|
||||
|
||||
// account for defined names
|
||||
this.workbook.definedNames.spliceRows(this.name, start, count, nInserts);
|
||||
}
|
||||
|
||||
// iterate over every row in the worksheet, including maybe empty rows
|
||||
eachRow(options, iteratee) {
|
||||
if (!iteratee) {
|
||||
iteratee = options;
|
||||
options = undefined;
|
||||
}
|
||||
if (options && options.includeEmpty) {
|
||||
const n = this._rows.length;
|
||||
for (let i = 1; i <= n; i++) {
|
||||
iteratee(this.getRow(i), i);
|
||||
}
|
||||
} else {
|
||||
this._rows.forEach(row => {
|
||||
if (row && row.hasValues) {
|
||||
iteratee(row, row.number);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// return all rows as sparse array
|
||||
getSheetValues() {
|
||||
const rows = [];
|
||||
this._rows.forEach(row => {
|
||||
if (row) {
|
||||
rows[row.number] = row.values;
|
||||
}
|
||||
});
|
||||
return rows;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Cells
|
||||
|
||||
// returns the cell at [r,c] or address given by r. If not found, return undefined
|
||||
findCell(r, c) {
|
||||
const address = colCache.getAddress(r, c);
|
||||
const row = this._rows[address.row - 1];
|
||||
return row ? row.findCell(address.col) : undefined;
|
||||
}
|
||||
|
||||
// return the cell at [r,c] or address given by r. If not found, create a new one.
|
||||
getCell(r, c) {
|
||||
const address = colCache.getAddress(r, c);
|
||||
const row = this.getRow(address.row);
|
||||
return row.getCellEx(address);
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Merge
|
||||
|
||||
// convert the range defined by ['tl:br'], [tl,br] or [t,l,b,r] into a single 'merged' cell
|
||||
mergeCells(...cells) {
|
||||
const dimensions = new Range(cells);
|
||||
this._mergeCellsInternal(dimensions);
|
||||
}
|
||||
|
||||
mergeCellsWithoutStyle(...cells) {
|
||||
const dimensions = new Range(cells);
|
||||
this._mergeCellsInternal(dimensions, true);
|
||||
}
|
||||
|
||||
_mergeCellsInternal(dimensions, ignoreStyle) {
|
||||
// check cells aren't already merged
|
||||
_.each(this._merges, merge => {
|
||||
if (merge.intersects(dimensions)) {
|
||||
throw new Error('Cannot merge already merged cells');
|
||||
}
|
||||
});
|
||||
|
||||
// apply merge
|
||||
const master = this.getCell(dimensions.top, dimensions.left);
|
||||
for (let i = dimensions.top; i <= dimensions.bottom; i++) {
|
||||
for (let j = dimensions.left; j <= dimensions.right; j++) {
|
||||
// merge all but the master cell
|
||||
if (i > dimensions.top || j > dimensions.left) {
|
||||
this.getCell(i, j).merge(master, ignoreStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// index merge
|
||||
this._merges[master.address] = dimensions;
|
||||
}
|
||||
|
||||
_unMergeMaster(master) {
|
||||
// master is always top left of a rectangle
|
||||
const merge = this._merges[master.address];
|
||||
if (merge) {
|
||||
for (let i = merge.top; i <= merge.bottom; i++) {
|
||||
for (let j = merge.left; j <= merge.right; j++) {
|
||||
this.getCell(i, j).unmerge();
|
||||
}
|
||||
}
|
||||
delete this._merges[master.address];
|
||||
}
|
||||
}
|
||||
|
||||
get hasMerges() {
|
||||
// return true if this._merges has a merge object
|
||||
return _.some(this._merges, Boolean);
|
||||
}
|
||||
|
||||
// scan the range defined by ['tl:br'], [tl,br] or [t,l,b,r] and if any cell is part of a merge,
|
||||
// un-merge the group. Note this function can affect multiple merges and merge-blocks are
|
||||
// atomic - either they're all merged or all un-merged.
|
||||
unMergeCells(...cells) {
|
||||
const dimensions = new Range(cells);
|
||||
|
||||
// find any cells in that range and unmerge them
|
||||
for (let i = dimensions.top; i <= dimensions.bottom; i++) {
|
||||
for (let j = dimensions.left; j <= dimensions.right; j++) {
|
||||
const cell = this.findCell(i, j);
|
||||
if (cell) {
|
||||
if (cell.type === Enums.ValueType.Merge) {
|
||||
// this cell merges to another master
|
||||
this._unMergeMaster(cell.master);
|
||||
} else if (this._merges[cell.address]) {
|
||||
// this cell is a master
|
||||
this._unMergeMaster(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Shared/Array Formula
|
||||
fillFormula(range, formula, results, shareType = 'shared') {
|
||||
// Define formula for top-left cell and share to rest
|
||||
const decoded = colCache.decode(range);
|
||||
const {top, left, bottom, right} = decoded;
|
||||
const width = right - left + 1;
|
||||
const masterAddress = colCache.encodeAddress(top, left);
|
||||
const isShared = shareType === 'shared';
|
||||
|
||||
// work out result accessor
|
||||
let getResult;
|
||||
if (typeof results === 'function') {
|
||||
getResult = results;
|
||||
} else if (Array.isArray(results)) {
|
||||
if (Array.isArray(results[0])) {
|
||||
getResult = (row, col) => results[row - top][col - left];
|
||||
} else {
|
||||
// eslint-disable-next-line no-mixed-operators
|
||||
getResult = (row, col) => results[(row - top) * width + (col - left)];
|
||||
}
|
||||
} else {
|
||||
getResult = () => undefined;
|
||||
}
|
||||
let first = true;
|
||||
for (let r = top; r <= bottom; r++) {
|
||||
for (let c = left; c <= right; c++) {
|
||||
if (first) {
|
||||
this.getCell(r, c).value = {
|
||||
shareType,
|
||||
formula,
|
||||
ref: range,
|
||||
result: getResult(r, c),
|
||||
};
|
||||
first = false;
|
||||
} else {
|
||||
this.getCell(r, c).value = isShared
|
||||
? {
|
||||
sharedFormula: masterAddress,
|
||||
result: getResult(r, c),
|
||||
}
|
||||
: getResult(r, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Images
|
||||
addImage(imageId, range) {
|
||||
const model = {
|
||||
type: 'image',
|
||||
imageId,
|
||||
range,
|
||||
};
|
||||
this._media.push(new Image(this, model));
|
||||
}
|
||||
|
||||
getImages() {
|
||||
return this._media.filter(m => m.type === 'image');
|
||||
}
|
||||
|
||||
addBackgroundImage(imageId) {
|
||||
const model = {
|
||||
type: 'background',
|
||||
imageId,
|
||||
};
|
||||
this._media.push(new Image(this, model));
|
||||
}
|
||||
|
||||
getBackgroundImageId() {
|
||||
const image = this._media.find(m => m.type === 'background');
|
||||
return image && image.imageId;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Worksheet Protection
|
||||
protect(password, options) {
|
||||
// TODO: make this function truly async
|
||||
// perhaps marshal to worker thread or something
|
||||
return new Promise(resolve => {
|
||||
this.sheetProtection = {
|
||||
sheet: true,
|
||||
};
|
||||
if (options && 'spinCount' in options) {
|
||||
// force spinCount to be integer >= 0
|
||||
options.spinCount = Number.isFinite(options.spinCount) ? Math.round(Math.max(0, options.spinCount)) : 100000;
|
||||
}
|
||||
if (password) {
|
||||
this.sheetProtection.algorithmName = 'SHA-512';
|
||||
this.sheetProtection.saltValue = Encryptor.randomBytes(16).toString('base64');
|
||||
this.sheetProtection.spinCount = options && 'spinCount' in options ? options.spinCount : 100000; // allow user specified spinCount
|
||||
this.sheetProtection.hashValue = Encryptor.convertPasswordToHash(
|
||||
password,
|
||||
'SHA512',
|
||||
this.sheetProtection.saltValue,
|
||||
this.sheetProtection.spinCount
|
||||
);
|
||||
}
|
||||
if (options) {
|
||||
this.sheetProtection = Object.assign(this.sheetProtection, options);
|
||||
if (!password && 'spinCount' in options) {
|
||||
delete this.sheetProtection.spinCount;
|
||||
}
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
unprotect() {
|
||||
this.sheetProtection = null;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// Tables
|
||||
addTable(model) {
|
||||
const table = new Table(this, model);
|
||||
this.tables[model.name] = table;
|
||||
return table;
|
||||
}
|
||||
|
||||
getTable(name) {
|
||||
return this.tables[name];
|
||||
}
|
||||
|
||||
removeTable(name) {
|
||||
delete this.tables[name];
|
||||
}
|
||||
|
||||
getTables() {
|
||||
return Object.values(this.tables);
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Conditional Formatting
|
||||
addConditionalFormatting(cf) {
|
||||
this.conditionalFormattings.push(cf);
|
||||
}
|
||||
|
||||
removeConditionalFormatting(filter) {
|
||||
if (typeof filter === 'number') {
|
||||
this.conditionalFormattings.splice(filter, 1);
|
||||
} else if (filter instanceof Function) {
|
||||
this.conditionalFormattings = this.conditionalFormattings.filter(filter);
|
||||
} else {
|
||||
this.conditionalFormattings = [];
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Deprecated
|
||||
get tabColor() {
|
||||
// eslint-disable-next-line no-console
|
||||
console.trace('worksheet.tabColor property is now deprecated. Please use worksheet.properties.tabColor');
|
||||
return this.properties.tabColor;
|
||||
}
|
||||
|
||||
set tabColor(value) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.trace('worksheet.tabColor property is now deprecated. Please use worksheet.properties.tabColor');
|
||||
this.properties.tabColor = value;
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Model
|
||||
|
||||
get model() {
|
||||
const model = {
|
||||
id: this.id,
|
||||
name: this.name,
|
||||
dataValidations: this.dataValidations.model,
|
||||
properties: this.properties,
|
||||
state: this.state,
|
||||
pageSetup: this.pageSetup,
|
||||
headerFooter: this.headerFooter,
|
||||
rowBreaks: this.rowBreaks,
|
||||
views: this.views,
|
||||
autoFilter: this.autoFilter,
|
||||
media: this._media.map(medium => medium.model),
|
||||
sheetProtection: this.sheetProtection,
|
||||
tables: Object.values(this.tables).map(table => table.model),
|
||||
conditionalFormattings: this.conditionalFormattings,
|
||||
};
|
||||
|
||||
// =================================================
|
||||
// columns
|
||||
model.cols = Column.toModel(this.columns);
|
||||
|
||||
// ==========================================================
|
||||
// Rows
|
||||
const rows = (model.rows = []);
|
||||
const dimensions = (model.dimensions = new Range());
|
||||
this._rows.forEach(row => {
|
||||
const rowModel = row && row.model;
|
||||
if (rowModel) {
|
||||
dimensions.expand(rowModel.number, rowModel.min, rowModel.number, rowModel.max);
|
||||
rows.push(rowModel);
|
||||
}
|
||||
});
|
||||
|
||||
// ==========================================================
|
||||
// Merges
|
||||
model.merges = [];
|
||||
_.each(this._merges, merge => {
|
||||
model.merges.push(merge.range);
|
||||
});
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
_parseRows(model) {
|
||||
this._rows = [];
|
||||
model.rows.forEach(rowModel => {
|
||||
const row = new Row(this, rowModel.number);
|
||||
this._rows[row.number - 1] = row;
|
||||
row.model = rowModel;
|
||||
});
|
||||
}
|
||||
|
||||
_parseMergeCells(model) {
|
||||
_.each(model.mergeCells, merge => {
|
||||
// Do not merge styles when importing an Excel file
|
||||
// since each cell may have different styles intentionally.
|
||||
this.mergeCellsWithoutStyle(merge);
|
||||
});
|
||||
}
|
||||
|
||||
set model(value) {
|
||||
this.name = value.name;
|
||||
this._columns = Column.fromModel(this, value.cols);
|
||||
this._parseRows(value);
|
||||
|
||||
this._parseMergeCells(value);
|
||||
this.dataValidations = new DataValidations(value.dataValidations);
|
||||
this.properties = value.properties;
|
||||
this.pageSetup = value.pageSetup;
|
||||
this.headerFooter = value.headerFooter;
|
||||
this.views = value.views;
|
||||
this.autoFilter = value.autoFilter;
|
||||
this._media = value.media.map(medium => new Image(this, medium));
|
||||
this.sheetProtection = value.sheetProtection;
|
||||
this.tables = value.tables.reduce((tables, table) => {
|
||||
const t = new Table();
|
||||
t.model = table;
|
||||
tables[table.name] = t;
|
||||
return tables;
|
||||
}, {});
|
||||
this.conditionalFormattings = value.conditionalFormattings;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Worksheet;
|
||||
Reference in New Issue
Block a user