diff --git a/package-lock.json b/package-lock.json
index 9940a9f..42380ca 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,18 +18,22 @@
"@fortawesome/fontawesome-free": "^6.7.2",
"@primeng/themes": "^19.1.0",
"animate.css": "^4.1.1",
+ "file-saver": "^2.0.5",
"primeflex": "^4.0.0",
"primeicons": "^7.0.0",
"primeng": "^19.1.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
+ "xlsx": "^0.18.5",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^19.2.9",
"@angular/cli": "^19.2.9",
"@angular/compiler-cli": "^19.2.0",
+ "@types/file-saver": "^2.0.7",
"@types/jasmine": "~5.1.0",
+ "@types/xlsx": "^0.0.35",
"jasmine-core": "~5.6.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
@@ -5160,6 +5164,13 @@
"@types/send": "*"
}
},
+ "node_modules/@types/file-saver": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz",
+ "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/http-errors": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz",
@@ -5292,6 +5303,13 @@
"@types/node": "*"
}
},
+ "node_modules/@types/xlsx": {
+ "version": "0.0.35",
+ "resolved": "https://registry.npmjs.org/@types/xlsx/-/xlsx-0.0.35.tgz",
+ "integrity": "sha512-s0x3DYHZzOkxtjqOk/Nv1ezGzpbN7I8WX+lzlV/nFfTDOv7x4d8ZwGHcnaiB8UCx89omPsftQhS5II3jeWePxQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@vitejs/plugin-basic-ssl": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.2.0.tgz",
@@ -5563,6 +5581,15 @@
"node": ">=8.9.0"
}
},
+ "node_modules/adler-32": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.3.1.tgz",
+ "integrity": "sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/agent-base": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
@@ -6313,6 +6340,19 @@
],
"license": "CC-BY-4.0"
},
+ "node_modules/cfb": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cfb/-/cfb-1.2.2.tgz",
+ "integrity": "sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "adler-32": "~1.3.0",
+ "crc-32": "~1.2.0"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -6555,6 +6595,15 @@
"node": ">=0.10.0"
}
},
+ "node_modules/codepage": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.15.0.tgz",
+ "integrity": "sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -6852,6 +6901,18 @@
}
}
},
+ "node_modules/crc-32": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz",
+ "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==",
+ "license": "Apache-2.0",
+ "bin": {
+ "crc32": "bin/crc32.njs"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -7847,6 +7908,12 @@
}
}
},
+ "node_modules/file-saver": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz",
+ "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==",
+ "license": "MIT"
+ },
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
@@ -8008,6 +8075,15 @@
"node": ">= 0.6"
}
},
+ "node_modules/frac": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/frac/-/frac-1.1.2.tgz",
+ "integrity": "sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/fraction.js": {
"version": "4.3.7",
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
@@ -13030,6 +13106,18 @@
"dev": true,
"license": "BSD-3-Clause"
},
+ "node_modules/ssf": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.11.2.tgz",
+ "integrity": "sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "frac": "~1.1.2"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/ssri": {
"version": "12.0.0",
"resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz",
@@ -14624,6 +14712,24 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/wmf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wmf/-/wmf-1.0.2.tgz",
+ "integrity": "sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/word": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/word/-/word-0.3.0.tgz",
+ "integrity": "sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==",
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/wrap-ansi": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
@@ -14797,6 +14903,27 @@
}
}
},
+ "node_modules/xlsx": {
+ "version": "0.18.5",
+ "resolved": "https://registry.npmjs.org/xlsx/-/xlsx-0.18.5.tgz",
+ "integrity": "sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "adler-32": "~1.3.0",
+ "cfb": "~1.2.1",
+ "codepage": "~1.15.0",
+ "crc-32": "~1.2.1",
+ "ssf": "~0.11.2",
+ "wmf": "~1.0.1",
+ "word": "~0.3.0"
+ },
+ "bin": {
+ "xlsx": "bin/xlsx.njs"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
diff --git a/package.json b/package.json
index d5778c5..8c63519 100644
--- a/package.json
+++ b/package.json
@@ -20,18 +20,22 @@
"@fortawesome/fontawesome-free": "^6.7.2",
"@primeng/themes": "^19.1.0",
"animate.css": "^4.1.1",
+ "file-saver": "^2.0.5",
"primeflex": "^4.0.0",
"primeicons": "^7.0.0",
"primeng": "^19.1.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
+ "xlsx": "^0.18.5",
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^19.2.9",
"@angular/cli": "^19.2.9",
"@angular/compiler-cli": "^19.2.0",
+ "@types/file-saver": "^2.0.7",
"@types/jasmine": "~5.1.0",
+ "@types/xlsx": "^0.0.35",
"jasmine-core": "~5.6.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
diff --git a/src/app/pages/actualizacion-pd/actualizacion-pd.component.html b/src/app/pages/actualizacion-pd/actualizacion-pd.component.html
index 2d53ead..37ba6b5 100644
--- a/src/app/pages/actualizacion-pd/actualizacion-pd.component.html
+++ b/src/app/pages/actualizacion-pd/actualizacion-pd.component.html
@@ -1,84 +1,144 @@
-
-
-
+
+
-
-
Filtro Código Cronograma
-
-
+
+
Filtro Código Cronograma
+
+
-
-
Título de la tabla:
-
+
+
Título de la tabla:
+
+
+
+
-
-
- | Empresa |
- Código de cronograma |
- Etapa del Servicio |
- Nombre sistema |
- Tipo de inversión |
- Código de glosa PD |
- Descripción glosa |
- Monto Inversión Total (UF) |
- Año de Inicio |
- Año de Término |
- Mes de Término |
- Nota |
- Estado aprobación |
- Observación |
-
-
-
-
- | {{ product.empresa }} |
- {{ product.codigoCronograma }} |
- {{ product.codigoCronogramaAjuste }} |
- {{ product.tipoCarga }} |
- {{ product.estadoRevision }} |
- {{ product.estadoRevision }} |
- {{ product.fechaIngreso }} |
-
-
- |
- {{ product.dato9 }} |
- {{ product.dato10 }} |
- {{ product.dato11 }} |
- {{ product.dato12 }} |
-
-
- |
-
- |
-
-
-
-
-
-
+ [rowsPerPageOptions]="[5, 10, 20]"
+ styleClass="p-datatable-sm"
+ >
+
+
+ | Empresa |
+ Código de cronograma |
+ Etapa del Servicio |
+ Nombre sistema |
+ Tipo de inversión |
+ Código de glosa PD |
+ Descripción glosa |
+ Monto Inversión Total (UF) |
+ Año de Inicio |
+ Año de Término |
+ Mes de Término |
+ Nota |
+ Estado aprobación |
+ Observación |
+
+
+
+
+ | {{ product.empresa }} |
+ {{ product.codigoCronograma }} |
+ {{ product.codigoCronogramaAjuste }} |
+ {{ product.tipoCarga }} |
+ {{ product.estadoRevision }} |
+ {{ product.estadoRevision }} |
+ {{ product.fechaIngreso }} |
+
+
+ |
+ {{ product.dato9 }} |
+ {{ product.dato10 }} |
+ {{ product.dato11 }} |
+ {{ product.dato12 }} |
+
+
+ |
+
+
+ |
+
+
+
+
+
+
+
diff --git a/src/app/pages/actualizacion-pd/actualizacion-pd.component.ts b/src/app/pages/actualizacion-pd/actualizacion-pd.component.ts
index bd93f78..3a024b9 100644
--- a/src/app/pages/actualizacion-pd/actualizacion-pd.component.ts
+++ b/src/app/pages/actualizacion-pd/actualizacion-pd.component.ts
@@ -1,14 +1,27 @@
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
-import { TableModule } from 'primeng/table';
+import { Table, TableModule } from 'primeng/table';
import { InputTextModule } from 'primeng/inputtext';
import { SelectModule } from 'primeng/select';
+import { ButtonModule } from 'primeng/button';
+import { TooltipModule } from 'primeng/tooltip';
+import * as FileSaver from 'file-saver';
+import * as XLSX from 'xlsx';
@Component({
selector: 'app-actualizacion-pd',
- imports: [FormsModule, TableModule, InputTextModule, SelectModule],
+ imports: [
+ FormsModule,
+ TableModule,
+ InputTextModule,
+ SelectModule,
+ ButtonModule,
+ TooltipModule
+
+ ],
templateUrl: './actualizacion-pd.component.html',
- styleUrl: './actualizacion-pd.component.scss'
+ styleUrl: './actualizacion-pd.component.scss',
+ standalone: true
})
export class ActualizacionPdComponent {
pageTitle: string = 'Cronogramas cargados:';
@@ -19,7 +32,6 @@ export class ActualizacionPdComponent {
{ name: 'Aprobado', value: 'Aprobado' },
{ name: 'Rechazado', value: 'Rechazado' },
];
-
products: any[] = [
{
empresa: 'Empresa A',
@@ -81,4 +93,83 @@ export class ActualizacionPdComponent {
},
];
-}
+ /**
+ * Exporta la tabla a Excel
+ * @param table Referencia a la tabla PrimeNG
+ */
+ exportExcel(table: Table) {
+ // Preparamos los datos para exportar
+ const exportData = this.prepareDataForExport(table);
+
+ // Creamos el libro de Excel
+ const worksheet = XLSX.utils.json_to_sheet(exportData);
+ const workbook = { Sheets: { 'data': worksheet }, SheetNames: ['data'] };
+
+ // Aplicamos estilos a las celdas (encabezados en negrita con fondo azul)
+ this.applyStyles(worksheet);
+
+ // Opciones de exportación
+ const excelBuffer: any = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
+
+ // Guardamos el archivo
+ this.saveAsExcelFile(excelBuffer, 'cronogramas_exportados');
+ }
+
+ /**
+ * Prepara los datos para la exportación, filtrando según sea necesario
+ */
+ prepareDataForExport(table: Table): any[] {
+ // Si hay filtros aplicados, usamos los datos filtrados
+ const data = table.filteredValue || table.value;
+
+ // Mapeamos los datos para tener solo las propiedades que queremos exportar
+ return data.map(item => {
+ return {
+ 'Empresa': item.empresa,
+ 'Código de cronograma': item.codigoCronograma,
+ 'Etapa del Servicio': item.codigoCronogramaAjuste,
+ 'Nombre sistema': item.tipoCarga,
+ 'Tipo de inversión': item.estadoRevision,
+ 'Código de glosa PD': item.analista,
+ 'Descripción glosa': item.fechaIngreso,
+ 'Monto Inversión Total (UF)': '',
+ 'Año de Inicio': item.dato9,
+ 'Año de Término': item.dato10,
+ 'Mes de Término': item.dato11 || '',
+ 'Nota': item.dato12 || '',
+ 'Estado aprobación': item.dato13,
+ 'Observación': ''
+ };
+ });
+ }
+
+ /**
+ * Aplica estilos al worksheet de Excel
+ */
+ applyStyles(worksheet: XLSX.WorkSheet) {
+ // Establecemos el estilo para los encabezados
+ const headerStyle = {
+ font: { bold: true, color: { rgb: 'FFFFFF' } },
+ fill: { fgColor: { rgb: '0070C0' } },
+ alignment: { horizontal: 'center' }
+ };
+
+ // Aplicar estilos a los encabezados (primera fila)
+ const range = XLSX.utils.decode_range(worksheet['!ref'] || 'A1');
+ for (let col = range.s.c; col <= range.e.c; col++) {
+ const cellRef = XLSX.utils.encode_cell({ r: 0, c: col });
+ if (!worksheet[cellRef]) worksheet[cellRef] = { t: 's', v: '' };
+ worksheet[cellRef].s = headerStyle;
+ }
+ }
+
+ /**
+ * Guarda el buffer como un archivo Excel
+ */
+ saveAsExcelFile(buffer: any, fileName: string): void {
+ const EXCEL_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8';
+ const EXCEL_EXTENSION = '.xlsx';
+ const data: Blob = new Blob([buffer], { type: EXCEL_TYPE });
+ FileSaver.saveAs(data, fileName + '_' + new Date().getTime() + EXCEL_EXTENSION);
+ }
+}
\ No newline at end of file
diff --git a/src/app/pages/ajuste-pd/ajuste-pd.component.html b/src/app/pages/ajuste-pd/ajuste-pd.component.html
index 6ac2ee6..5b30fc6 100644
--- a/src/app/pages/ajuste-pd/ajuste-pd.component.html
+++ b/src/app/pages/ajuste-pd/ajuste-pd.component.html
@@ -1,98 +1,135 @@
-
-
-
+
+
-
-
Filtro Código Cronograma
-
-
+
+
Filtro Código Cronograma
+
+
-
-
-
+
+
-
-
- |
- Cronograma base vigente |
- Cronograma base ajustado |
-
-
- | Empresa |
- Código de cronograma |
- Etapa del Servicio |
- Nombre sistema |
- Nombre sistema |
- Nombre localidad |
- Tipo de inversión |
- Código de glosa PD |
- Descripción glosa |
- Monto Inversión Total (UF) |
- Año de Inicio |
- Año de Término |
- Mes de Término |
- Tipo de ajuste |
- Año de Inicio |
- Año de Término |
- Mes de Término |
- Nota |
- Estado aprobación |
- Observación |
-
-
-
-
- | {{ product.empresa }} |
- {{ product.codigoCronograma }} |
- {{ product.codigoCronogramaAjuste }} |
- {{ product.tipoCarga }} |
- {{ product.estadoRevision }} |
- {{ product.estadoRevision }} |
- {{ product.fechaIngreso }} |
- {{ product.estadoRevision }} |
- {{ product.dato9 }} |
- {{ product.dato10 }} |
- {{ product.dato13 }} |
- {{ product.dato14 }} |
- {{ product.dato15 }} |
- {{ product.dato16 }} |
- {{ product.dato17 }} |
- {{ product.dato18 }} |
- {{ product.dato11 }} |
- {{ product.dato12 }} |
-
-
- |
-
- |
-
-
-
-
-
-
-
-
+ [rowsPerPageOptions]="[5, 10, 20]"
+ >
+
+
+ |
+ Cronograma base vigente |
+ Cronograma base ajustado |
+
+
+ | Empresa |
+ Código de cronograma |
+ Etapa del Servicio |
+ Nombre sistema |
+ Nombre sistema |
+ Nombre localidad |
+ Tipo de inversión |
+ Código de glosa PD |
+ Descripción glosa |
+ Monto Inversión Total (UF) |
+ Año de Inicio |
+ Año de Término |
+ Mes de Término |
+ Tipo de ajuste |
+ Año de Inicio |
+ Año de Término |
+ Mes de Término |
+ Nota |
+ Estado aprobación |
+ Observación |
+
+
+
+
+ | {{ product.empresa }} |
+ {{ product.codigoCronograma }} |
+ {{ product.codigoCronogramaAjuste }} |
+ {{ product.tipoCarga }} |
+ {{ product.estadoRevision }} |
+ {{ product.estadoRevision }} |
+ {{ product.fechaIngreso }} |
+ {{ product.estadoRevision }} |
+ {{ product.dato9 }} |
+ {{ product.dato10 }} |
+ {{ product.dato13 }} |
+ {{ product.dato14 }} |
+ {{ product.dato15 }} |
+ {{ product.dato16 }} |
+ {{ product.dato17 }} |
+ {{ product.dato18 }} |
+ {{ product.dato11 }} |
+ {{ product.dato12 }} |
+
+
+ |
+
+
+ |
+
+
+
+
+
+
diff --git a/src/app/pages/ajuste-pd/ajuste-pd.component.ts b/src/app/pages/ajuste-pd/ajuste-pd.component.ts
index 5bc6924..33454ac 100644
--- a/src/app/pages/ajuste-pd/ajuste-pd.component.ts
+++ b/src/app/pages/ajuste-pd/ajuste-pd.component.ts
@@ -1,22 +1,31 @@
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
-import { TableModule } from 'primeng/table';
+import { TableModule ,Table} from 'primeng/table';
import { InputTextModule } from 'primeng/inputtext';
import { SelectModule } from 'primeng/select';
+import { TooltipModule } from 'primeng/tooltip';
+import { ButtonModule } from 'primeng/button';
+import * as FileSaver from 'file-saver';
+import * as XLSX from 'xlsx';
@Component({
selector: 'app-ajuste-pd',
- imports: [FormsModule, TableModule, InputTextModule, SelectModule],
+ imports: [
+ FormsModule,
+ TableModule,
+ InputTextModule,
+ SelectModule,
+ TooltipModule,
+ ButtonModule
+ ],
templateUrl: './ajuste-pd.component.html',
styleUrl: './ajuste-pd.component.scss'
})
export class AjustePdComponent {
selectedCity: any = '';
empresas: any[] = [{name: 'Empresa A'}, {name: 'Empresa B'}, {name: 'Empresa C'}];
-
select1: any = '';
estadoAprobacion: any[] = [{name:'Rechazado'}, {name:'Aprobado'}];
-
products: any[] = [
{
empresa: 'Empresa A',
@@ -92,4 +101,114 @@ export class AjustePdComponent {
},
];
-}
+ /**
+ * Exporta los datos de la tabla a un archivo Excel
+ * @param table Referencia a la tabla PrimeNG
+ */
+ exportExcel(table: Table) {
+ try {
+ // Obtenemos los datos a exportar (usamos los datos filtrados si existen)
+ const dataToExport = this.prepareDataForExport(table);
+
+ // Creamos el libro de Excel
+ const worksheet = XLSX.utils.json_to_sheet(dataToExport);
+ const workbook = { Sheets: { 'data': worksheet }, SheetNames: ['data'] };
+
+ // Aplicamos estilos a las celdas
+ this.applyExcelStyles(worksheet);
+
+ // Opciones de exportación
+ const excelBuffer: any = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
+
+ // Guardamos el archivo
+ this.saveAsExcelFile(excelBuffer, 'ajuste_pd');
+
+ console.log('Exportación a Excel completada con éxito');
+ } catch (error) {
+ console.error('Error al exportar a Excel:', error);
+ }
+ }
+
+ /**
+ * Prepara los datos para la exportación, traduciendo los nombres de columnas
+ * @param table Referencia a la tabla PrimeNG
+ * @returns Array de objetos con los datos formateados para exportar
+ */
+ private prepareDataForExport(table: Table): any[] {
+ // Si hay filtros aplicados, usamos los datos filtrados, de lo contrario todos los datos
+ const data = table.filteredValue || table.value;
+
+ // Mapeamos los datos para tener nombres de columnas en español y legibles
+ return data.map(item => {
+ return {
+ 'Empresa': item.empresa,
+ 'Código de cronograma': item.codigoCronograma,
+ 'Etapa del Servicio': item.codigoCronogramaAjuste,
+ 'Nombre sistema': item.tipoCarga,
+ 'Tipo de inversión': item.estadoRevision,
+ 'Código de glosa PD': item.analista,
+ 'Descripción glosa': item.fechaIngreso,
+ 'Año de Inicio': item.dato9,
+ 'Año de Término': item.dato10,
+ 'Estado aprobación': item.dato13
+ };
+ });
+ }
+
+ /**
+ * Aplica estilos al worksheet de Excel para mejorar la presentación
+ * @param worksheet Hoja de Excel a la que aplicar estilos
+ */
+ private applyExcelStyles(worksheet: XLSX.WorkSheet) {
+ // Definimos estilos para los encabezados
+ const headerStyle = {
+ font: { bold: true, color: { rgb: 'FFFFFF' } },
+ fill: { fgColor: { rgb: '007ACC' } }, // Color azul para los encabezados
+ alignment: { horizontal: 'center', vertical: 'center' }
+ };
+
+ // Aplicamos estilos a los encabezados (primera fila)
+ const range = XLSX.utils.decode_range(worksheet['!ref'] || 'A1');
+ for (let col = range.s.c; col <= range.e.c; col++) {
+ const cellRef = XLSX.utils.encode_cell({ r: 0, c: col });
+ if (!worksheet[cellRef]) worksheet[cellRef] = { t: 's', v: '' };
+
+ // Asignamos el estilo al encabezado
+ worksheet[cellRef].s = headerStyle;
+ }
+
+ // Ajustamos el ancho de las columnas automáticamente
+ const colWidths = [];
+ for (let col = range.s.c; col <= range.e.c; col++) {
+ colWidths.push({ wch: 15 }); // Ancho predeterminado
+ }
+ worksheet['!cols'] = colWidths;
+ }
+
+ /**
+ * Guarda el buffer como un archivo Excel
+ * @param buffer Datos del archivo Excel
+ * @param fileName Nombre base del archivo
+ */
+ private saveAsExcelFile(buffer: any, fileName: string): void {
+ // Definimos el tipo MIME para archivos Excel
+ const EXCEL_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8';
+ const EXCEL_EXTENSION = '.xlsx';
+
+ // Creamos un Blob con los datos
+ const data: Blob = new Blob([buffer], { type: EXCEL_TYPE });
+
+ // Generamos un nombre de archivo con timestamp para evitar duplicados
+ const today = new Date();
+ const formattedDate =
+ today.getFullYear().toString() +
+ (today.getMonth() + 1).toString().padStart(2, '0') +
+ today.getDate().toString().padStart(2, '0') +
+ '_' +
+ today.getHours().toString().padStart(2, '0') +
+ today.getMinutes().toString().padStart(2, '0');
+
+ // Guardamos el archivo
+ FileSaver.saveAs(data, `${fileName}_${formattedDate}${EXCEL_EXTENSION}`);
+ }
+}
\ No newline at end of file