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.
		
		
		
		
		
			
		
			
				
					166 lines
				
				3.9 KiB
			
		
		
			
		
	
	
					166 lines
				
				3.9 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								const _ = require('./under-dash');
							 | 
						||
| 
								 | 
							
								const colCache = require('./col-cache');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class CellMatrix {
							 | 
						||
| 
								 | 
							
								  constructor(template) {
							 | 
						||
| 
								 | 
							
								    this.template = template;
							 | 
						||
| 
								 | 
							
								    this.sheets = {};
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  addCell(addressStr) {
							 | 
						||
| 
								 | 
							
								    this.addCellEx(colCache.decodeEx(addressStr));
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  getCell(addressStr) {
							 | 
						||
| 
								 | 
							
								    return this.findCellEx(colCache.decodeEx(addressStr), true);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  findCell(addressStr) {
							 | 
						||
| 
								 | 
							
								    return this.findCellEx(colCache.decodeEx(addressStr), false);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  findCellAt(sheetName, rowNumber, colNumber) {
							 | 
						||
| 
								 | 
							
								    const sheet = this.sheets[sheetName];
							 | 
						||
| 
								 | 
							
								    const row = sheet && sheet[rowNumber];
							 | 
						||
| 
								 | 
							
								    return row && row[colNumber];
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  addCellEx(address) {
							 | 
						||
| 
								 | 
							
								    if (address.top) {
							 | 
						||
| 
								 | 
							
								      for (let row = address.top; row <= address.bottom; row++) {
							 | 
						||
| 
								 | 
							
								        for (let col = address.left; col <= address.right; col++) {
							 | 
						||
| 
								 | 
							
								          this.getCellAt(address.sheetName, row, col);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								    } else {
							 | 
						||
| 
								 | 
							
								      this.findCellEx(address, true);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  getCellEx(address) {
							 | 
						||
| 
								 | 
							
								    return this.findCellEx(address, true);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  findCellEx(address, create) {
							 | 
						||
| 
								 | 
							
								    const sheet = this.findSheet(address, create);
							 | 
						||
| 
								 | 
							
								    const row = this.findSheetRow(sheet, address, create);
							 | 
						||
| 
								 | 
							
								    return this.findRowCell(row, address, create);
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  getCellAt(sheetName, rowNumber, colNumber) {
							 | 
						||
| 
								 | 
							
								    const sheet = this.sheets[sheetName] || (this.sheets[sheetName] = []);
							 | 
						||
| 
								 | 
							
								    const row = sheet[rowNumber] || (sheet[rowNumber] = []);
							 | 
						||
| 
								 | 
							
								    const cell =
							 | 
						||
| 
								 | 
							
								      row[colNumber] ||
							 | 
						||
| 
								 | 
							
								      (row[colNumber] = {
							 | 
						||
| 
								 | 
							
								        sheetName,
							 | 
						||
| 
								 | 
							
								        address: colCache.n2l(colNumber) + rowNumber,
							 | 
						||
| 
								 | 
							
								        row: rowNumber,
							 | 
						||
| 
								 | 
							
								        col: colNumber,
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    return cell;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  removeCellEx(address) {
							 | 
						||
| 
								 | 
							
								    const sheet = this.findSheet(address);
							 | 
						||
| 
								 | 
							
								    if (!sheet) {
							 | 
						||
| 
								 | 
							
								      return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    const row = this.findSheetRow(sheet, address);
							 | 
						||
| 
								 | 
							
								    if (!row) {
							 | 
						||
| 
								 | 
							
								      return;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    delete row[address.col];
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  forEachInSheet(sheetName, callback) {
							 | 
						||
| 
								 | 
							
								    const sheet = this.sheets[sheetName];
							 | 
						||
| 
								 | 
							
								    if (sheet) {
							 | 
						||
| 
								 | 
							
								      sheet.forEach((row, rowNumber) => {
							 | 
						||
| 
								 | 
							
								        if (row) {
							 | 
						||
| 
								 | 
							
								          row.forEach((cell, colNumber) => {
							 | 
						||
| 
								 | 
							
								            if (cell) {
							 | 
						||
| 
								 | 
							
								              callback(cell, rowNumber, colNumber);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  forEach(callback) {
							 | 
						||
| 
								 | 
							
								    _.each(this.sheets, (sheet, sheetName) => {
							 | 
						||
| 
								 | 
							
								      this.forEachInSheet(sheetName, callback);
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  map(callback) {
							 | 
						||
| 
								 | 
							
								    const results = [];
							 | 
						||
| 
								 | 
							
								    this.forEach(cell => {
							 | 
						||
| 
								 | 
							
								      results.push(callback(cell));
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								    return results;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  findSheet(address, create) {
							 | 
						||
| 
								 | 
							
								    const name = address.sheetName;
							 | 
						||
| 
								 | 
							
								    if (this.sheets[name]) {
							 | 
						||
| 
								 | 
							
								      return this.sheets[name];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (create) {
							 | 
						||
| 
								 | 
							
								      return (this.sheets[name] = []);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return undefined;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  findSheetRow(sheet, address, create) {
							 | 
						||
| 
								 | 
							
								    const {row} = address;
							 | 
						||
| 
								 | 
							
								    if (sheet && sheet[row]) {
							 | 
						||
| 
								 | 
							
								      return sheet[row];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (create) {
							 | 
						||
| 
								 | 
							
								      return (sheet[row] = []);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return undefined;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  findRowCell(row, address, create) {
							 | 
						||
| 
								 | 
							
								    const {col} = address;
							 | 
						||
| 
								 | 
							
								    if (row && row[col]) {
							 | 
						||
| 
								 | 
							
								      return row[col];
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (create) {
							 | 
						||
| 
								 | 
							
								      return (row[col] = this.template
							 | 
						||
| 
								 | 
							
								        ? Object.assign(address, JSON.parse(JSON.stringify(this.template)))
							 | 
						||
| 
								 | 
							
								        : address);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return undefined;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  spliceRows(sheetName, start, numDelete, numInsert) {
							 | 
						||
| 
								 | 
							
								    const sheet = this.sheets[sheetName];
							 | 
						||
| 
								 | 
							
								    if (sheet) {
							 | 
						||
| 
								 | 
							
								      const inserts = [];
							 | 
						||
| 
								 | 
							
								      for (let i = 0; i < numInsert; i++) {
							 | 
						||
| 
								 | 
							
								        inserts.push([]);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      sheet.splice(start, numDelete, ...inserts);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  spliceColumns(sheetName, start, numDelete, numInsert) {
							 | 
						||
| 
								 | 
							
								    const sheet = this.sheets[sheetName];
							 | 
						||
| 
								 | 
							
								    if (sheet) {
							 | 
						||
| 
								 | 
							
								      const inserts = [];
							 | 
						||
| 
								 | 
							
								      for (let i = 0; i < numInsert; i++) {
							 | 
						||
| 
								 | 
							
								        inserts.push(null);
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      _.each(sheet, row => {
							 | 
						||
| 
								 | 
							
								        row.splice(start, numDelete, ...inserts);
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = CellMatrix;
							 |