diff --git a/docx/img/aguila_logo.png b/docx/img/aguila_logo.png new file mode 100644 index 0000000..b0a12d5 Binary files /dev/null and b/docx/img/aguila_logo.png differ diff --git a/docx/img/cee_logo.png b/docx/img/cee_logo.png new file mode 100644 index 0000000..e88de04 Binary files /dev/null and b/docx/img/cee_logo.png differ diff --git a/docx/img/ceem_logo.jpg b/docx/img/ceem_logo.jpg new file mode 100644 index 0000000..92bd7aa Binary files /dev/null and b/docx/img/ceem_logo.jpg differ diff --git a/docx/img/colegio_ingenieros_logo.png b/docx/img/colegio_ingenieros_logo.png new file mode 100644 index 0000000..8629f0f Binary files /dev/null and b/docx/img/colegio_ingenieros_logo.png differ diff --git a/docx/img/eate_logo.jpg b/docx/img/eate_logo.jpg new file mode 100644 index 0000000..6b4959b Binary files /dev/null and b/docx/img/eate_logo.jpg differ diff --git a/docx/img/eeg2_logo.png b/docx/img/eeg2_logo.png new file mode 100644 index 0000000..d359586 Binary files /dev/null and b/docx/img/eeg2_logo.png differ diff --git a/docx/img/eeg_f_logo.png b/docx/img/eeg_f_logo.png new file mode 100644 index 0000000..7daaf0d Binary files /dev/null and b/docx/img/eeg_f_logo.png differ diff --git a/docx/img/eeg_logo.png b/docx/img/eeg_logo.png new file mode 100644 index 0000000..2c15c59 Binary files /dev/null and b/docx/img/eeg_logo.png differ diff --git a/docx/img/fondo_certificado.png b/docx/img/fondo_certificado.png new file mode 100644 index 0000000..5a87f60 Binary files /dev/null and b/docx/img/fondo_certificado.png differ diff --git a/docx/img/matpel-logo.png b/docx/img/matpel-logo.png new file mode 100644 index 0000000..ee4dbce Binary files /dev/null and b/docx/img/matpel-logo.png differ diff --git a/docx/img/michigan_logo.png b/docx/img/michigan_logo.png new file mode 100644 index 0000000..80461f6 Binary files /dev/null and b/docx/img/michigan_logo.png differ diff --git a/docx/img/mtc_logo.png b/docx/img/mtc_logo.png new file mode 100644 index 0000000..245e139 Binary files /dev/null and b/docx/img/mtc_logo.png differ diff --git a/docx/img/osha_logo.png b/docx/img/osha_logo.png new file mode 100644 index 0000000..403c92a Binary files /dev/null and b/docx/img/osha_logo.png differ diff --git a/docx/main.ts b/docx/main.ts new file mode 100644 index 0000000..ef3e1a8 --- /dev/null +++ b/docx/main.ts @@ -0,0 +1,266 @@ +import * as fs from "fs"; +import { + Document, Packer, Paragraph, TextRun, PageOrientation, ImageRun, + HorizontalPositionRelativeFrom, VerticalPositionRelativeFrom, + convertMillimetersToTwip, + HorizontalPositionAlign, +} from "docx"; +import { join } from "path"; + + +function cm(centimeters: number) { + return convertMillimetersToTwip((100 * centimeters) / 150); +} + +function cmToEmu(cm: number) { + return Math.round(cm * 360000); +} + + +const imgFondoDoc = new ImageRun({ + data: fs.readFileSync(join(__dirname, "img", "fondo_certificado.png")), + transformation: { + height: cm(20.97), + width: cm(29.8), + }, + floating: { + zIndex: 0, + horizontalPosition: { + relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, + offset: 0, + }, + verticalPosition: { + relative: VerticalPositionRelativeFrom.TOP_MARGIN, + offset: 0, + }, + }, +}); + + +const imgMatpel = new ImageRun({ + data: fs.readFileSync(join(__dirname, "img", "matpel-logo.png")), + transformation: { + height: cm(2.81), + width: cm(2.81), + }, + floating: { + zIndex: 1, + horizontalPosition: { + relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, + offset: cmToEmu(0.7), + }, + verticalPosition: { + relative: VerticalPositionRelativeFrom.TOP_MARGIN, + offset: cmToEmu(0.7), + }, + }, +}); + +const imgCIP = new ImageRun({ + data: fs.readFileSync(join(__dirname, "img", "colegio_ingenieros_logo.png")), + transformation: { + height: cm(2.15), + width: cm(2.15), + }, + floating: { + zIndex: 1, + horizontalPosition: { + relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, + offset: cmToEmu(0.91), + }, + verticalPosition: { + relative: VerticalPositionRelativeFrom.TOP_MARGIN, + offset: cmToEmu(3.64), + }, + }, +}); + +const imgCEE = new ImageRun({ + data: fs.readFileSync(join(__dirname, "img", "cee_logo.png")), + transformation: { + height: cm(2.22), + width: cm(3.11), + }, + floating: { + zIndex: 1, + horizontalPosition: { + relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, + offset: cmToEmu(0.29), + }, + verticalPosition: { + relative: VerticalPositionRelativeFrom.TOP_MARGIN, + offset: cmToEmu(18), + }, + }, +}); + +const imgMTC = new ImageRun({ + data: fs.readFileSync(join(__dirname, "img", "mtc_logo.png")), + transformation: { + height: cm(1.3), + width: cm(4.08), + }, + floating: { + zIndex: 1, + horizontalPosition: { + relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, + offset: cmToEmu(5.13), + }, + verticalPosition: { + relative: VerticalPositionRelativeFrom.TOP_MARGIN, + offset: cmToEmu(19.33), + }, + }, +}); + +const imgEEG = new ImageRun({ + data: fs.readFileSync(join(__dirname, "img", "eeg_f_logo.png")), + transformation: { + height: cm(4.39), + width: cm(6.4), + }, + floating: { + zIndex: 1, + horizontalPosition: { + relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, + offset: cmToEmu(23.25), + }, + verticalPosition: { + relative: VerticalPositionRelativeFrom.TOP_MARGIN, + offset: cmToEmu(0), + }, + }, +}); + +const imgOSHA = new ImageRun({ + data: fs.readFileSync(join(__dirname, "img", "osha_logo.png")), + transformation: { + height: cm(1.55), + width: cm(4.46), + }, + floating: { + zIndex: 1, + horizontalPosition: { + relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, + offset: cmToEmu(24.34), + }, + verticalPosition: { + relative: VerticalPositionRelativeFrom.TOP_MARGIN, + offset: cmToEmu(4.95), + }, + }, +}); + +const imgAguila = new ImageRun({ + data: fs.readFileSync(join(__dirname, "img", "aguila_logo.png")), + transformation: { + height: cm(2.62), + width: cm(2.68), + }, + floating: { + zIndex: 1, + horizontalPosition: { + relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, + offset: cmToEmu(25.45), + }, + verticalPosition: { + relative: VerticalPositionRelativeFrom.TOP_MARGIN, + offset: cmToEmu(6.57), + }, + }, +}); + +const imgMichigan = new ImageRun({ + data: fs.readFileSync(join(__dirname, "img", "michigan_logo.png")), + transformation: { + height: cm(2.47), + width: cm(2.6), + }, + floating: { + zIndex: 1, + horizontalPosition: { + relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, + offset: cmToEmu(25.59), + }, + verticalPosition: { + relative: VerticalPositionRelativeFrom.TOP_MARGIN, + offset: cmToEmu(9.54), + }, + }, +}); + +const imgCEEM = new ImageRun({ + data: fs.readFileSync(join(__dirname, "img", "ceem_logo.jpg")), + transformation: { + height: cm(1), + width: cm(3.99), + }, + floating: { + zIndex: 1, + horizontalPosition: { + relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, + offset: cmToEmu(24.97), + }, + verticalPosition: { + relative: VerticalPositionRelativeFrom.TOP_MARGIN, + offset: cmToEmu(12.5), + }, + }, +}); + +const imgEATE = new ImageRun({ + data: fs.readFileSync(join(__dirname, "img", "eate_logo.jpg")), + transformation: { + height: cm(2.21), + width: cm(3.28), + }, + floating: { + zIndex: 1, + horizontalPosition: { + relative: HorizontalPositionRelativeFrom.LEFT_MARGIN, + offset: cmToEmu(25.54), + }, + verticalPosition: { + relative: VerticalPositionRelativeFrom.TOP_MARGIN, + offset: cmToEmu(14.09), + }, + }, +}); + + + +const doc = new Document({ + sections: [ + { + properties: { + page: { + size: { + orientation: PageOrientation.LANDSCAPE, + }, + }, + }, + children: [ + new Paragraph({ + children: [ + imgFondoDoc, + imgMatpel, + imgCIP, + imgCEE, + imgMTC, + imgEEG, + imgOSHA, + imgAguila, + imgMichigan, + imgCEEM, + imgEATE, + ], + }), + ], + }, + ], +}); + +// Used to export the file into a .docx file +Packer.toBuffer(doc).then((buffer) => { + fs.writeFileSync("My Document.docx", buffer); +}); diff --git a/package.json b/package.json index c77f1ed..48a42bd 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,8 @@ "ssr:watch": "node esbuild.js", "ssr:hydration": "node esbuild-client.js", "ssr": "concurrently \"node esbuild.js\" \"node esbuild-client.js\" \"tailwindcss -i static/tailwind.css -o ./static/styles.css --watch\"", - "tailwind": "tailwindcss -i static/tailwind.css -o ./static/styles.css --watch" + "tailwind": "tailwindcss -i static/tailwind.css -o ./static/styles.css --watch", + "docx": "tsc docx/main.ts && node docx/main.js" }, "dependencies": { "@nestjs/common": "^9.0.0", @@ -31,6 +32,7 @@ "axios": "^1.4.0", "class-transformer": "^0.5.1", "class-validator": "^0.14.0", + "docx": "^8.0.4", "dotenv": "^16.0.3", "mysql2": "^3.2.4", "reflect-metadata": "^0.1.13", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ed7fc83..c5161f6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -25,6 +25,9 @@ dependencies: class-validator: specifier: ^0.14.0 version: 0.14.0 + docx: + specifier: ^8.0.4 + version: 8.0.4 dotenv: specifier: ^16.0.3 version: 16.0.3 @@ -2884,6 +2887,17 @@ packages: esutils: 2.0.3 dev: true + /docx@8.0.4: + resolution: {integrity: sha512-bPS/UyWnflcr46JugKZVv8BBNIAVjvWbGOBvvWS21n14MQite78EO09GqNEpckG7kYsQqUzEPVsigErXKTrdFA==} + engines: {node: '>=10'} + dependencies: + '@types/node': 18.15.11 + jszip: 3.10.1 + nanoid: 3.3.6 + xml: 1.0.1 + xml-js: 1.6.11 + dev: false + /dotenv@16.0.3: resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} engines: {node: '>=12'} @@ -3752,6 +3766,10 @@ packages: engines: {node: '>= 4'} dev: true + /immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + dev: false + /import-fresh@3.3.0: resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} engines: {node: '>=6'} @@ -4470,6 +4488,15 @@ packages: graceful-fs: 4.2.11 dev: true + /jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + dev: false + /kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -4491,6 +4518,12 @@ packages: /libphonenumber-js@1.10.30: resolution: {integrity: sha512-PLGc+xfrQrkya/YK2/5X+bPpxRmyJBHM+xxz9krUdSgk4Vs2ZwxX5/Ow0lv3r9PDlDtNWb4u+it8MY5rZ0IyGw==} + /lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + dependencies: + immediate: 3.0.6 + dev: false + /light-my-request@5.9.1: resolution: {integrity: sha512-UT7pUk8jNCR1wR7w3iWfIjx32DiB2f3hFdQSOwy3/EPQ3n3VocyipUxcyRZR0ahoev+fky69uA+GejPa9KuHKg==} dependencies: @@ -4783,7 +4816,6 @@ packages: resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - dev: true /natural-compare-lite@1.4.0: resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} @@ -4958,6 +4990,10 @@ packages: engines: {node: '>=6'} dev: true + /pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + dev: false + /parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -5517,6 +5553,10 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + /sax@1.2.4: + resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + dev: false + /schema-utils@3.1.2: resolution: {integrity: sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==} engines: {node: '>= 10.13.0'} @@ -5592,6 +5632,10 @@ packages: resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} dev: true + /setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + dev: false + /setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} @@ -6455,6 +6499,17 @@ packages: signal-exit: 3.0.7 dev: true + /xml-js@1.6.11: + resolution: {integrity: sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==} + hasBin: true + dependencies: + sax: 1.2.4 + dev: false + + /xml@1.0.1: + resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==} + dev: false + /xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} diff --git a/tsconfig.json b/tsconfig.json index 5fe24bf..1874a7a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,6 +22,7 @@ }, "include": [ "src/**/*.ts", - "src/**/*.tsx" + "src/**/*.tsx", + "docx/**/*.ts", ] }