You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
314 lines
6.8 KiB
314 lines
6.8 KiB
'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;
|
|
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;
|