UNPKG

prg-class

Version:

Clases genéricas utilizadas por microservicios Programamos SPA.

528 lines (527 loc) 24.3 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ObjExcel = void 0; const fs = require("fs"); const Excel = require("exceljs"); const C = require("prg-constant"); const F = require("prg-function"); // import U = require('../params'); // Funciones especí­ficas de clases. // import UF = require('../../shared/mod-func'); class ObjExcel { constructor() { this.moLetterHead = { L1: 'Programamos SPA', L2: 'Desarrollo de Software', L3: 'https://www.programamos.cl', L4: 'La Capitanía 80, Oficina 101 Las Condes', L5: 'Fono 999082128' }; this.loL = []; // Arreglo con letras de columnas de Excel. Desde <A> hasta <AZ>. this.loA = ['', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q']; this.msColPri = 'FF1D7D4D'; this.msColSec = 'FF1D7D4D'; this.msColSec1 = 'FFCFE4DF'; this.msColWhi = 'FFFFFFFF'; this.msBorDel = 'thin'; this.msBorMed = 'medium'; this.msBorGru = 'thick'; this.msFont = 'Calibri'; this.mlMaxTabRegs = 15; this.mbRawData = false; this.moXls = { fileName: 'archivo.xlsx', stripRow: true, pattern: { even: { style: 'solid', color: { argb: this.msColSec1 } }, // eceeef odd: { style: 'solid', color: { argb: this.msColWhi } }, }, }; } fnExportDataset(aoParams) { return __awaiter(this, void 0, void 0, function* () { for (let k = 0; k < this.loA.length; k++) { // Ciclo para llenar arreglo de letras de columnas de Excel. for (let i = 0; i < 26; i++) { const lsL1 = this.loA[k]; const lsL2 = String.fromCharCode(i + 65); const lsLetra = lsL1 + lsL2; this.loL.push(lsLetra); } } return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { const P = aoParams; const lsTit = F.trim(P.wb.title); const lsTag = F.trim(P.wb.tag); const lsSbj = F.trim(P.wb.subject); const loWB = this.fnNewBook(lsTit, lsTag, lsSbj); // Crea libro. const loS1 = this.fnMakeDataDataset(P); this.exportDataset(loWB, 1, loS1, P.strip, P.wb, P.mc, P.cc, P.vw, P.fml, P.tag); if (!P.filename || F.trim(P.filename) === '') { // Retorna base 64... const buffer = yield loWB.xlsx.writeBuffer(); const string64 = buffer.toString('base64'); return resolve(F.fnReturn(null, string64, C.HttpCode.Ok.OK)); // Retorna datos. } else { // Escribe Excel en disco... return loWB.xlsx.writeFile(F.trim(P.filename)).then(() => { return resolve(F.fnReturn(null, true, C.HttpCode.Ok.OK)); // Retorna datos. }).catch((err) => { return resolve(F.fnReturn(null, false, C.HttpCode.Ok.OK)); // Retorna datos. }); } })); }); } exportDataset(aoWB, alSheetId, aoData, abStripRows, aoEnc = [], aoMC = [], aoCellColor = { colIni: 0, color: '', qty: 0, step: 0 }, aoVw = [], alFormula = 0, aoTag = null) { let lsAux = ''; // Variable auxiliar. const llFilTit = 7; // Cantidad de filas de encabezado de tí­tulo. const llHeaderRow = llFilTit + 1; // Fila donde se ubica encabezado de fila. const mlRowHeight = 23; // Alto de fila, por defecto. const liFacChar = 10; // Factor de conversión de ancho a caracteres. const ws = aoWB.addWorksheet(`Hoja${alSheetId}`, { properties: { defaultRowHeight: mlRowHeight } }); // Crea nombre de la hoja. const liCols = aoData.fields.length; // Determina cantidad de columnas. ws.properties.defaultRowHeight = mlRowHeight; ws.views = [{ activeCell: 'A1', showGridLines: false }]; // Define vista, por defecto de la hoja. if (aoVw && aoVw.length > 0) { ws.views = aoVw; } // *** Membrete *** ws.getCell('B2').value = this.moLetterHead.L1; ws.getCell('B3').value = this.moLetterHead.L2; ws.getCell('B4').value = this.moLetterHead.L3; ws.getCell('B4').font = { underline: true }; // Subraya membrete. for (let i = 7; i < (llFilTit); i++) { // Fillers ws.getCell(`B${i}`).value = ''; // Escribe fillers. } // *** TÍTULO *** const lsTit = aoEnc && aoEnc.title ? aoEnc.title : 'Informe'; this.fnAddText(ws, 'B7', lsTit, '', false, { name: this.msFont, size: 14, bold: true }); /* Escribe datos */ const loFld = ['', 'N°']; const loCols = [{ width: 5 }, { width: 5 }]; // Define las columnas. aoData.fields.forEach((loEL) => { loFld.push(loEL['c']); loCols.push({ width: loEL['w'] / liFacChar }); }); ws.columns = loCols; ws.addRows(['']); // Escribe separador de tí­tulo y encabezado de datos. ws.addRows([loFld]); // Escribe encabezado de datos. if (aoData && aoData.data && aoData.data.length > 0) { ws.addRows(aoData.data); // Escribe los datos. } const liRegs = aoData.data.length; // Cantidad de registros. const llEncFil = llFilTit + 1 + 1; // Determina fila de encabezado. for (let i = 0; i <= liRegs; i++) { // Ciclo para aplicar formato a datos (filas). for (let j = 0; j <= liCols; j++) { // Ciclo para aplicar formato a datos (columnas). lsAux = this.loL[j + 1] + (llHeaderRow + i + 1); // Determina letra de la columna. let lsAli = ''; if (j > 0) { const lsA = F.trim(aoData.fields[j - 1].a).toUpperCase(); lsAli = (lsA === undefined || lsA === '' || lsA === 'L') ? 'left' : aoData.fields[j - 1].a === 'C' ? 'center' : 'right'; const lsF = aoData.fields[j - 1].f; if (lsF !== '') { ws.getCell(lsAux).numFmt = lsF; // Si corresponde, asigna formato. } ws.getCell(lsAux).font = { size: 8 }; // Asigna tamaño de letra. } ws.getCell(lsAux).alignment = { wrapText: true, indent: 0, horizontal: lsAli, }; // Asigna celda que engorda, dependiendo del texto. if (abStripRows) { // Si se desea resaltar filas alternadas. const llI2 = i / 2; if (i > 0 && llI2 === parseInt(llI2.toString(), 10)) { // Resaltado de fila par. ws.getCell(lsAux).fill = { type: 'pattern', pattern: this.moXls.pattern.even.style, fgColor: this.moXls.pattern.even.color, }; } else { // Resaltado de fila impar. if (i > 0) { ws.getCell(lsAux).fill = { type: 'pattern', pattern: this.moXls.pattern.odd.style, fgColor: this.moXls.pattern.odd.color, }; } } } } } for (let i = 0; i <= liRegs; i++) { // Ciclo para aplicar altura de fila. ws.getRow(i + llFilTit + 2).height = mlRowHeight; } // *** Asigna Borde para lista de datos *** const llRowTabIni = llHeaderRow + 1; const llRowTabFin = llRowTabIni + liRegs; const lsBd = this.msBorDel; this.fnSetBox(ws, 'B', llRowTabIni + 1, 'B', llRowTabFin, lsBd, false, false, false, true); // Borde izquierda. // Borde derecha. this.fnSetBox(ws, this.loL[liCols + 1], llRowTabIni + 1, this.loL[liCols + 1], llRowTabFin, lsBd, false, true, false, false); this.fnSetBox(ws, 'B', llRowTabFin, this.loL[liCols + 1], llRowTabFin, lsBd, false, false, true, false); // Borde abajo. this.fnSetBox(ws, 'B', llRowTabFin, 'B', llRowTabFin, lsBd, false, false, true, true); // Borde esquina inferior izquierda. // Borde esquina derecha. this.fnSetBox(ws, this.loL[liCols + 1], llRowTabFin, this.loL[liCols + 1], llRowTabFin, lsBd, false, true, true, false); this.fnSetTableTitle(ws, 'B', llEncFil, this.loL[liCols + 1], llEncFil, this.msBorDel, false); // Aplica formato a encabezado. // *** Agrega columnas combinadas *** if (aoMC && aoMC.length > 0) { aoMC.forEach((mc) => { const lsCI = `${mc.il + mc.in}`; ws.mergeCells(`${lsCI}:${mc.fl}${mc.fn}`); ws.getCell(lsCI).value = mc.v; ws.getCell(lsCI).alignment = { horizontal: mc.a }; ws.getRow(mc.in).height = mlRowHeight; this.fnSetTableTitle(ws, mc.il, mc.in, mc.fl, mc.in + 1, this.msBorDel, true); }); } this.setCellColor(aoCellColor, ws, aoData.data.length); // Asigna colores personalizados. } cellValue(aoWs, asLetra, alFila, asMsg, alSz = 12, abBold = false) { if (F.trim(asMsg) !== '') { aoWs.getCell(`${asLetra}${alFila}`).value = asMsg; // Mensaje. } aoWs.getCell(`${asLetra}${alFila}`).font = { size: alSz, bold: abBold }; // Asigna tamaño de letra. } cellSumFormula(aoWs, asLetVal, alFilaVal, alSumaIni, alSumaFin, asFM, alSz = 12, abBold = false) { aoWs.getCell(`${asLetVal}${alFilaVal}`).value = { formula: `SUM(${asLetVal}${alSumaIni}:${asLetVal}${alSumaFin})`, // Fórmula. result: 0, // Valor por defecto. }; aoWs.getCell(`${asLetVal}${alFilaVal}`).numFmt = asFM; // Formato. aoWs.getCell(`${asLetVal}${alFilaVal}`).font = { size: alSz, bold: abBold }; // Asigna tamaño de letra. } setCellColor(aoCellColor, aoWS, alRowCount) { const CC = aoCellColor; if (!CC || CC.colIni <= 0 || F.trim(CC.color) === '' || CC.step <= 0 || CC.qty <= 0) { return; } let llCol = CC.colIni; const llIni = 9; for (let i = 0; i < CC.qty; i++) { const lsLet = this.loL[llCol]; const loCell = []; for (let j = llIni; j <= alRowCount + llIni; j++) { loCell.push(lsLet + F.trim(j)); } loCell.map((key) => { aoWS.getCell(key).fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: CC.color }, }; return; }); llCol += CC.step; } } fnMakeDataDataset(aoParams) { const loAux = []; if (aoParams && aoParams.d && aoParams.d.length > 0) { for (let i = 0; i < aoParams.d.length; i++) { const loRow = ['', i + 1]; for (let j = 0; j < aoParams.l.length; j++) { let lsName = F.trim(aoParams.l[j].n); const llType = F.intval(aoParams.l[j].t); if (llType === C.jDTT.xBool) { lsName += '1'; // En los campos boolean, se muestra la contraparte tipo texto: SI /NO. } let loVal = F.trim(aoParams.d[i][lsName]); if (llType === C.jDTT.xNumb) { loVal = F.intval(aoParams.d[i][lsName]); } if (llType === C.jDTT.xFloat) { loVal = F.floatval(aoParams.d[i][lsName]); } if (llType === C.jDTT.xDate) { // loVal = F.fnGetDateChile(aoParams.d[i][lsName]); loVal = F.fnGetDateStringChile(aoParams.d[i][lsName], false); } if (llType === C.jDTT.xDateTime) { loVal = F.fnGetDateStringChile(aoParams.d[i][lsName], true); } loRow.push(loVal); } loAux.push(loRow); } } const loRet = { data: !this.mbRawData ? loAux : aoParams.d, fields: aoParams.l }; return loRet; } fnSetTableTitle(aoWs, asColIni, alFilIni, asColFin = '', alFilFin = 0, asBorder = '', abBorderInterno = true) { // Bordes encabezado de tabla. const lsBd = asBorder !== '' ? asBorder : this.msBorMed; let loBx = { top: { style: lsBd, color: { argb: this.msColPri } }, left: { style: lsBd, color: { argb: this.msColPri } }, bottom: { style: lsBd, color: { argb: this.msColPri } }, right: { style: lsBd, color: { argb: this.msColPri } }, }; const loBL = { left: { style: lsBd, color: { argb: this.msColPri } }, top: { style: lsBd, color: { argb: this.msColPri } }, bottom: { style: lsBd, color: { argb: this.msColPri } }, }; const loBR = { right: { style: lsBd, color: { argb: this.msColPri } }, top: { style: lsBd, color: { argb: this.msColPri } }, bottom: { style: lsBd, color: { argb: this.msColPri } }, }; if (!abBorderInterno) { // No se requiere borde interno. loBx = { top: { style: lsBd, color: { argb: this.msColPri } }, bottom: { style: lsBd, color: { argb: this.msColPri } }, }; } const loGR1 = { type: 'pattern', pattern: 'solid', fgColor: { argb: this.msColSec }, // bgColor: { argb: this.msColSec }, }; // Configura filas. if (alFilFin < alFilIni) { alFilFin = alFilIni; asColFin = asColIni; } // Configura columnas. if (asColFin === '') { asColFin = asColIni; } const liColI = this.loL.indexOf(asColIni); // asColIni.charCodeAt(0); let liColF = this.loL.indexOf(asColFin); // asColFin.charCodeAt(0); if (liColF < liColI) { asColFin = asColIni; liColF = liColI; } if (!abBorderInterno) { // No tiene bordes internos, asigna borde izquierdo y derecho. // Ciclo para recorrer filas. for (let i = alFilIni; i <= alFilFin; i++) { const lsCelL = asColIni + i; // Determina celda izquierda. const lsCelR = asColFin + i; // Determina celda derecha. aoWs.getCell(lsCelL).border = loBL; aoWs.getCell(lsCelR).border = loBR; } } // Ciclo para recorrer filas / columnas. for (let i = alFilIni; i <= alFilFin; i++) { for (let j = liColI; j <= liColF; j++) { const loFont = { name: this.msFont, size: 9, bold: true, color: { argb: this.msColWhi } }; const lsCell = this.loL[j] + i; aoWs.getCell(lsCell).border = loBx; // aoWs.getCell(lsCell).font = { name: this.msFont, size: 9, bold: true, color: { argb: this.msColWhi } }; aoWs.getCell(lsCell).alignment = { horizontal: 'center' }; aoWs.getCell(lsCell).fill = loGR1; aoWs.getCell(lsCell).font = loFont; } } } fnBoxMedLins(aoWs, asColIni, alFilIni, asColFin = '', alFilFin = 0, asBorder = this.msBorGru) { // Configura filas. if (alFilFin < alFilIni) { alFilFin = alFilIni; asColFin = asColIni; } // Configura columnas. if (asColFin === '') { asColFin = asColIni; } const liColI = asColIni.charCodeAt(0); let liColF = asColFin.charCodeAt(0); if (liColF < liColI) { asColFin = asColIni; liColF = liColI; } const loBTL = { top: { style: asBorder, color: { argb: this.msColPri } }, left: { style: asBorder, color: { argb: this.msColPri } }, }; const loBTR = { top: { style: asBorder, color: { argb: this.msColPri } }, right: { style: asBorder, color: { argb: this.msColPri } }, }; const loBBL = { bottom: { style: asBorder, color: { argb: this.msColPri } }, left: { style: asBorder, color: { argb: this.msColPri } }, }; const loBBR = { bottom: { style: asBorder, color: { argb: this.msColPri } }, right: { style: asBorder, color: { argb: this.msColPri } }, }; const loBT = { top: { style: asBorder, color: { argb: this.msColPri } } }; const loBB = { bottom: { style: asBorder, color: { argb: this.msColPri } } }; const loBL = { left: { style: asBorder, color: { argb: this.msColPri } } }; const loBR = { right: { style: asBorder, color: { argb: this.msColPri } } }; const loBF1 = { bottom: { style: this.msBorDel, color: { argb: this.msColPri } }, top: { style: this.msBorDel, color: { argb: this.msColPri } }, }; const loBRF = { right: { style: asBorder, color: { argb: this.msColPri } }, bottom: { style: this.msBorDel, color: { argb: this.msColPri } }, top: { style: this.msBorDel, color: { argb: this.msColPri } }, }; // Raya superior e inferior. for (let j = liColI; j <= liColF; j++) { const lsCelI = this.loL[j] + alFilIni; const lsCelF = this.loL[j] + alFilFin; aoWs.getCell(lsCelI).border = loBT; aoWs.getCell(lsCelF).border = loBB; } // Borde izquierdo y derecho. for (let j = alFilIni + 1; j < alFilFin; j++) { const lsCelL = asColIni + j; // Determina celda izquierda. const lsCelR = asColFin + j; // Determina celda izquierda. aoWs.getCell(lsCelL).border = loBL; aoWs.getCell(lsCelR).border = loBRF; } // Esquinas. aoWs.getCell(asColIni + alFilIni).border = loBTL; aoWs.getCell(asColIni + alFilFin).border = loBBL; aoWs.getCell(asColFin + alFilIni).border = loBTR; aoWs.getCell(asColFin + alFilFin).border = loBBR; // Líneas delgadas interiores. for (let i = alFilIni + 1; i < alFilFin; i++) { for (let j = liColI + 1; j < liColF; j++) { const lsCell = this.loL[j] + i; // Determina celda para aplicar línea fina. aoWs.getCell(lsCell).border = loBF1; } } } fnLinVert(aoWs, asColIni, alFilIni, asColFin = '', alFilFin = 0) { // Configura filas. if (alFilFin < alFilIni) { alFilFin = alFilIni; asColFin = asColIni; } // Configura columnas. if (asColFin === '') { asColFin = asColIni; } const liColI = asColIni.charCodeAt(0); let liColF = asColFin.charCodeAt(0); if (liColF < liColI) { asColFin = asColIni; liColF = liColI; } const loBy = { left: { style: this.msBorMed, color: { argb: this.msColPri } }, right: { style: this.msBorMed, color: { argb: this.msColPri } }, }; // Crea bordes. for (let i = alFilIni; i <= alFilFin; i++) { for (let j = liColI; j <= liColF; j++) { const lsCell = this.loL[j] + i; // Determina celda para aplicar línea fina. aoWs.getCell(lsCell).border = loBy; } } } fnSetBox(aoWs, asColIni, alFilIni, asColFin = '', alFilFin = 0, asBorderStyle = this.msBorDel, abTop = false, abRight = false, abBottom = false, abLeft = false) { // Configura filas. if (alFilFin < alFilIni) { alFilFin = alFilIni; asColFin = asColIni; } // Configura columnas. if (asColFin === '') { asColFin = asColIni; } const liColI = this.loL.indexOf(asColIni); let liColF = this.loL.indexOf(asColFin); if (liColF < liColI) { asColFin = asColIni; liColF = liColI; } if (asBorderStyle === '') { asBorderStyle = this.msBorMed; } const loSty = { style: asBorderStyle, color: { argb: this.msColPri } }; let loB = { top: loSty, left: loSty, bottom: loSty, right: loSty }; if (!abTop && !abRight && !abBottom && !abLeft) { // Aplica todos los bordes. } else { // Aplica bordes específicos. const loAux = {}; if (abTop) { loAux.top = loSty; } if (abRight) { loAux.right = loSty; } if (abBottom) { loAux.bottom = loSty; } if (abLeft) { loAux.left = loSty; } loB = loAux; } // Crea bordes. for (let i = alFilIni; i <= alFilFin; i++) { for (let j = liColI; j <= liColF; j++) { const lsCell = this.loL[j] + i; // Determina celda para aplicar línea fina. aoWs.getCell(lsCell).border = loB; } } } fnAddText(aoWs, asCell, asText, asAliHor = 'left', abWrap = false, aoFont = null) { aoWs.getCell(asCell).value = asText; aoWs.getCell(asCell).alignment = { wrapText: abWrap, horizontal: asAliHor, }; if (aoFont !== null) { aoWs.getCell(asCell).font = aoFont; } } fnAddNumber(aoWs, asCell, adNumber, asFormat = '', aoFont = null) { aoWs.getCell(asCell).value = adNumber; aoWs.getCell(asCell).alignment = { horizontal: 'right' }; if (aoFont !== null) { aoWs.getCell(asCell).font = aoFont; } if (asFormat !== '') { aoWs.getCell(asCell).numFmt = asFormat; } } fnNewBook(asTitle = '', asTag = '', asSubject = '') { const loWB = new Excel.Workbook(); loWB.creator = 'HOSCAR'; loWB.lastModifiedBy = 'HOSCAR'; loWB['title'] = asTitle; loWB['keywords'] = asTag; loWB['subject'] = asSubject; loWB.created = new Date(); loWB.modified = new Date(); loWB.lastPrinted = new Date(); return loWB; } fnWriteFile(aoWB, asUserId, asFile) { return new Promise((resolve, reject) => { let lsDir = this.fnTempFolder(); // Carpeta Base. lsDir = `${lsDir}userdata`; if (!fs.existsSync(lsDir)) { fs.mkdirSync(lsDir); } lsDir = `${lsDir}/${asUserId}`; if (!fs.existsSync(lsDir)) { fs.mkdirSync(lsDir); } const lsFileName = `${lsDir}/${asFile}`; aoWB.xlsx.writeFile(lsFileName).then(() => { const lsRet = F.fnStrReplace('/', '|', lsFileName); return resolve(F.fnReturn('', lsRet, C.HttpCode.Ok.OK)); // Retorna datos. }); }); } fnTempFolder() { return F.getPathTemp(); } } exports.ObjExcel = ObjExcel;