import { Application } from '@feathersjs/express'; import { ServiceMethods, Id } from '@feathersjs/feathers'; import ExcelJS from 'exceljs'; import _ from 'lodash'; import { WaybillSchema } from '../models/waybill/waybill.schema'; const duplicateRowWithMergedCells = (sheet: any, row: number, count: number) => { sheet.duplicateRow(row, count, true); const merges: string[] = sheet.model.merges; const rowMerges = merges.filter(range => range.match(`\\w+${row}:\\w+${row}`)); _.times(count, index => { const newRow = row + index + 1; // Unmerge everything in a newRow so we dont run into conflicts merges .filter(range => range.match(`\\w+${newRow}:\\w+${newRow}`)) .forEach(range => sheet.unMergeCells(range)); // Merge the same cells as in the initial row rowMerges .map(range => range.replace(new RegExp(`${row}`, 'g'), `${newRow}`)) .forEach(range => sheet.mergeCells(range)); }); }; class Spreadsheets implements Partial> { app!: Application; setup(app: Application) { this.app = app; } async get(id: Id) { const waybill: any = await this.app.service('waybills').get(id); const workbook = new ExcelJS.Workbook(); await workbook.xlsx.readFile('./documents/waybill-template.xltx'); const sheet = workbook.getWorksheet('Вертикальная'); if (waybill.operation === 'in') { sheet.getCell('Z5').value = waybill.contractor.vatId; } else { sheet.getCell('AS5').value = waybill.contractor.vatId; } duplicateRowWithMergedCells(sheet, 30, waybill.records.length - 1); waybill.records.forEach((record: any, index: number) => { const row = 30 + index; const getCol = (col: string) => sheet.getCell(`${col}${row}`); getCol('A').value = record.productId; getCol('W').value = 'шт'; getCol('AG').value = record.quantity; getCol('AP').value = record.price; }); await workbook.xlsx.writeFile('./documents/waybill.xlsx'); console.log('written!'); return 'written!'; } } export default (app: Application): void => { app.use('/spreadsheets', new Spreadsheets); };