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
						
					
					
				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;
 |